Skip to content

Euclidean Rhythms

Euclidean rhythms are generated by distributing a number of hits as evenly as possible across a number of steps. This algorithm produces many traditional rhythms from around the world.

Given n hits and k steps, the Euclidean algorithm spaces the hits as evenly as possible. For example, 3 hits over 8 steps produces: x . . x . . x .

This is the Cuban tresillo rhythm, found in many styles of music.

Use parentheses after a note to apply Euclidean rhythm:

// note(hits, steps)
[C4(3,8)] // C4 with 3 hits over 8 steps
[bd(3,8)] // Kick drum with tresillo rhythm

The note plays on the generated hit positions and rests on the others.

Add a third parameter to rotate the pattern:

// note(hits, steps, rotation)
[C4(3,8,2)] // Same pattern rotated by 2 steps
[bd(3,8,1)] // Tresillo starting on second hit

Rotation is a left shift of the hit pattern. All hit/rest positions maintain their relative spacing, but the whole pattern shifts leftward by rotation steps — positions that shift off the left wrap to the right.

Here is (3,8) at different rotations:

RotationPatternOnset positions
0x . . x . . x .0, 3, 6
1. . x . . x . x2, 5, 7
2. x . . x . x .1, 4, 6
3x . . x . x . .0, 3, 5

Layering rotations of the same pattern creates interlocking rhythms:

use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
// Three tresillo rotations interlocking
drums << [bd(3,8,0), sd(3,8,2), hh(3,8,5)];
PLAY;

There are three equivalent ways to write Euclidean patterns.

Use parentheses directly after a note or sample inside []:

[C4(3,8)] // 3 hits, 8 steps
[bd(5,8,2)] // 5 hits, 8 steps, rotation 2

Create Euclidean patterns with the standalone function:

euclid(3, 8, [C4]) // 3 hits, 8 steps, source pattern
euclid(3, 8, [C4], 2) // With rotation

Or use it as a method on any pattern:

[C4].euclid(3, 8) // 3 hits, 8 steps
[C4].euclid(3, 8, 2) // With rotation
Inline C4(3,8)Function euclid(3, 8, [C4])Method [C4].euclid(3, 8)
SourceSingle elementAny patternAny pattern
Inside []YesNoNo
Multi-note sourceNoYesYes
ChainingWith modifiersStandaloneWith methods

These are equivalent:

[C4(3,8)]
euclid(3, 8, [C4])
[C4].euclid(3, 8)

Many traditional rhythms are Euclidean:

PatternHit patternNameOrigin/Style
(2,3)x x .Various
(3,4)x x x .CumbiaColombian
(2,5)x . x . .Khafif-e-ramalPersian
(3,7)x . x . x . .AksakTurkish
(3,8)x . . x . . x .TresilloCuban, many styles
(5,8)x . x x . x x .CinquilloCuban, Brazilian
(4,12)x . . x . . x . . x . .Various
(7,12)x . x x . x . x x . x .West African bellTraditional African
(5,16)x . . x . . x . . x . . x . . .Bossa novaBrazilian
(7,16)x . . x . x . x . . x . x . x .SambaBrazilian
x . . x . . x .

Onsets at positions 0, 3, 6 — grouping as 3+3+2 eighth notes (long-long-short). This asymmetric grouping is the rhythmic backbone of Cuban son, Afro-Cuban jazz, pop, EDM, and reggaeton. The tresillo is one of the most widely used rhythmic cells in music.

let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
drums << [bd(3,8)]; // Tresillo kick
PLAY;
x . x x . x x .

Onsets at positions 0, 2, 3, 5, 6. The cinquillo is a denser complement of the tresillo — it fills in two of the tresillo’s gaps while keeping the same 8-step frame. Found in Cuban contradanza and Brazilian samba patterns.

let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
drums << [rs(5,8)]; // Cinquillo on rim shot
PLAY;
x . . x . x . x . . x . x . x .

Seven hits across 16 sixteenth notes — a driving, intricate pattern with onsets at positions 0, 3, 5, 7, 10, 12, 14.

let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
// Samba feel
drums << [bd(7,16), hh*16];
PLAY;

Combine different Euclidean rhythms for polyrhythmic textures:

// Different euclidean per voice
[C4(3,8) D4(5,8)] // Two notes with different rhythms
// Mix euclidean and plain notes
[C4(3,8) E4 G4] // C4 has euclidean, E4/G4 are plain

The source pattern is queried each cycle and its notes are distributed across the Euclidean hit positions. If there are more hits than notes, the notes wrap around:

euclid(3, 8, [C4 E4 G4]) // 1:1 mapping — each note gets one hit
euclid(5, 8, [C4 E4]) // Wraps: C4 E4 C4 E4 C4
// Alternating source changes per cycle
[<C4 E4 G4>].euclid(3, 8)

Euclidean rhythms create interesting drum patterns:

let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
// Classic polyrhythm
drums << [bd(3,8) sd(2,8) hh(5,8)];
// 3 against 4 against 5
drums << [bd(3,16), sd(4,16), hh(5,16)];
// Afrobeat-style
drums << [bd(3,8), sd(2,8), hh(7,8)];

Combine Euclidean patterns with other modifiers:

[bd(3,8)*2] // Euclidean pattern sped up 2x
[C4(5,8) D4@2] // Euclidean C4, weighted D4

The order matters — modifiers applied before or after Euclidean give different results:

[C4(3,8)*2] // Euclid then fast: 3 hits played twice as fast
euclid(3, 8, [C4 E4].fast(2)) // Fast before euclid: source doubled, then 3 hits picked
let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
// Cascara pattern approximation
drums << [rs(5,8), bd(3,8), hh*8];
PLAY;
let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("cr78")));
// Sparse, hypnotic
drums << [bd(3,16), hh(7,16), sd(2,16,4)];
PLAY;
let melody = MidiTrack(1);
// Euclidean arpeggio
melody << [C4(3,8) E4(5,8) G4(7,8)];
PLAY;