Euclidean rhythms

Euclidean rhythms distribute n pulses as evenly as possible across k steps. Many traditional rhythms (clave, tresillo, bossa nova) are Euclidean patterns. Pass an array #(pulses steps) and send euclidean.

#( pulses steps ) euclidean to: #instrumentName.
ArgumentTypeDescription
pulsesIntegerNumber of triggers to distribute
stepsIntegerTotal number of steps in the pattern
"Classic tresillo — 3 pulses in 8 steps"
#(3 8) euclidean to: #conga.

"Cinquillo — 5 pulses in 16 steps (a Cuban staple)"
#(5 16) euclidean to: #bongo.

"With a custom sample index on each trigger"
#(5 16) euclidean index: ' 1 3 5 2'; to: #bongo.

Offset

Rotate the Euclidean pattern forward (positive) or backward to shift the phase of the rhythm. Cascade offset: before to:.

#( pulses steps ) euclidean offset: N; to: #instrumentName.
"Offset by 1 step forward — useful to stagger layered Euclidean patterns"
#(5 16) euclidean offset: 1; to: #cowbell.

"Same rhythm, different phase"
#(5 16) euclidean offset: 3; to: #bongo.
💡 Layer two Euclidean patterns on the same instrument with different offsets for polyrhythmic textures without any external tools.

Dirt notes — asDirtNotes

Route a melodic pattern to a SuperDirt instrument using a compact string notation. Each token is a MIDI note number; - is a rest; /N sets duration in beats; *N repeats the previous note N times.

'pattern-string' asDirtNotes to: #instrumentName.
'-/8 , 38 , 56*2 , -/4 , 41 , 66' asDirtNotes to: #acid; envMod: '0.8 0.2 0.3'.

"Tokens: rest(8 beats) → note 38 → note 56 twice → rest(4 beats) → 41 → 66"
TokenMeaning
38MIDI note 38 (one step)
-Rest (one step)
-/8Rest lasting 8 steps
56*2Note 56 repeated 2 times
,Separator between tokens

Dirt index — asDirtIndex

Like asDirtNotes but selects sample indices within a SuperDirt folder rather than MIDI note pitches. Combine with notes: to add a pitch layer.

'index-string' asDirtIndex notes: 'note-string' to: #instrumentName.
'1 , -/16 . 7 , -/9 , 12 , -/12, 18' asDirtIndex
    notes: '38 45 78 62 81'
    to: #speakspell.

Adding notes — notes:

Any Sequencer can have MIDI note values assigned to its triggers. By default all steps play note 60 (C3). Pass a space-separated string to notes: — values cycle across triggers.

sequencer notes: 'n1 n2 n3 ...' to: #instrumentName.
16 quavers notes: '60 64 67 72' to: #piano.
"Plays a C major arpeggio across 16 steps"

#plena asRhythm notes: '36 48 60' to: #bass.

Arpeggiation — arpeggiate:

Walk through a chord voicing across the triggers of a sequencer. Pass chord names as a space-separated string; Coypu resolves them to MIDI note sets.

sequencer arpeggiate: 'chord1 chord2 ...'; to: #instrumentName.
#cumbiaClave asRhythm arpeggiate: '12-sus4 0-min'; to: #psg; level: '0.4'.
"Alternates between a sus4 arpeggio and a minor arpeggio"
â„šī¸ Chord names follow the pattern root-quality, e.g. 0-maj, 7-min, 12-sus4, 4-dim. The root is a semitone offset from the base note.

Random melodic walk — randomWalksOn:octaves:root:

Generate a list of MIDI notes by randomly walking up and down a scale over a specified octave range from a root note. This produces organic, scale-coherent melodies that evolve differently on each evaluation.

N randomWalksOn: Scale <scale> octaves: octaves root: rootMidi.
ArgumentTypeDescription
NIntegerNumber of steps to generate
scaleScale constante.g. Scale pentatonicMajor, Scale sakura
octavesIntegerOctave range to walk within
rootMidiIntegerRoot note as MIDI number (e.g. 48 = C3)
"64-step random walk on Sakura scale, 2 octaves from C3"
64 randomTrigs
    notes: (32 randomWalksOn: Scale sakura octaves: 2 root: 48)
    to: #psg.

"Minor pentatonic walk, 3 octaves"
16 quavers
    notes: (16 randomWalksOn: Scale minorPentatonic octaves: 3 root: 36)
    to: #piano.
💡 Re-evaluate this line during a performance to generate a fresh melodic variation on the fly — no two evaluations produce the same walk.

Dynamics — level:

Set per-trigger amplitude values by cascading level: on any sequencer. Values are floats (0.0 – 1.0) and cycle across triggers.

sequencer to: #instrumentName; level: 'v1 v2 v3 ...'.
16 randomTrigs to: #ch; level: '0.8 0.4 0.3'.

#(1 0 1 0) asSeq to: #snare; level: '1.0 0.5'.
"Alternates full and half velocity"

"Set level directly on a named instrument after routing"
#clap level: '0.3 0.1 0.4'.

Envelope modulation — envMod:

Available for SuperDirt instruments. Controls envelope modulation depth per step. Cascades in the same way as level:.

'-/8 , 38 , 56*2 , -/4 , 41 , 66'
    asDirtNotes
    to: #acid;
    envMod: '0.8 0.2 0.3'.

Chaining all together

Here is a complete performance sketch combining multiple advanced pattern techniques:

ep := EcoPhausto new.
ep playFor: 128 bars.

"Kick: Euclidean 3-in-8"
#(3 8) euclidean to: #kick.

"Snare: hex pattern"
'020F' hexBeat to: #snare.

"Hi-hat: random triggers with swing dynamics"
16 randomTrigs to: #ch; level: '0.9 0.4 0.7 0.3'.

"Bass: notes on a named rhythm"
#cumbiaClave asRhythm notes: '36 36 43 36' to: #bass.

"Lead: random walk on pentatonic over 2 octaves"
16 randomTrigs
    notes: (16 randomWalksOn: Scale pentatonicMajor octaves: 2 root: 60)
    to: #psg; level: '0.6'.