Skip to content

Write Polymetric and Euclidean Rhythms

The syntax is in Mini-Notation Grammar; how the onsets are placed is in Polymeter & Euclidean Rhythm.

Put the loops in curly braces, separated by commas. Every loop plays on the grid of the first one, and a shorter loop drifts against it:

use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");
drums.set_instrument(Sampler(Kit("TR-808")));
drums << {bd sd bd sd, ch ch oh}; // 4-step grid; the 3-hat loop drifts
PLAY;

Set the grid yourself with %n — n steps per cycle for every loop:

drums << {bd sd bd sd, ch ch oh}%8;

A polymetric group can be one element of a sequence:

drums << [{bd sd bd}%4 cp]; // the group fills the first half

Add (hits, steps) to an element:

use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");
drums.set_instrument(Sampler(Kit("TR-808")));
drums << [bd(3,8), ch(7,16), sd(2,16,4)];
PLAY;

The element plays on the hits and rests on the other steps, inside its own slot. bd(3,8) is the tresillo; the explanation lists more rhythms that two numbers spell.

A third number rotates the rhythm by that many steps. Rotations of one rhythm on different sounds interlock:

use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");
drums.set_instrument(Sampler(Kit("CR-78")));
drums << [bd(3,8,0), rs(3,8,2), hh(3,8,5)];
PLAY;

euclid() takes a whole pattern as the source, and deals its notes onto the hits in order:

let dealt = euclid(3, 8, [C4 E4 G4]); // one note per hit
let wrapped = euclid(5, 8, [C4 E4]); // C4 E4 C4 E4 C4
let melody = MidiTrack("melody");
melody >> MidiOutput("synth");
melody << dealt;
PLAY;

The order of the operations matters. [C4(3,8)*2] makes the rhythm first and then plays it twice as fast; euclid(3, 8, [C4 E4].fast(2)) doubles the source first and then picks the hits from it.