Mini-notation rhythm construction
Learning objectives
- learner can build rhythms with subdivision, multiplication, rest, replicate and elongate operators
- learner can express polyrhythm and polymetre with bracket syntax
- learner can generate Euclidean rhythms from (k,n) notation
Capstone — one whole task that evidences the objectives
From a blank Tidal/Strudel buffer, construct a polymetric drum pattern that combines nested subdivisions, replication, an elongated accent, and a Euclidean (k,n) hi-hat, then explain how cycle-orientation makes the cross-rhythm emerge.
Prerequisite modules
This module builds the core motor skill of algorave drum programming: typing a full, groove-worthy drum pattern into a blank Tidal or Strudel buffer using mini-notation alone. On stage, the mini-notation string is your drum machine — there is no piano roll to fall back on, so tresillo hats, uneven accents, and drifting polymetres all have to flow from a handful of operators you can type without thinking, mid-set, while the previous pattern is still playing.
The arc starts supported: with a working groove from the prerequisite modules on screen, the learner edits single steps — subdividing one slot with square brackets (“square brackets subdivide one step into a nested sub-sequence”), adding a roll with the asterisk multiplier, punching a hole with the tilde rest. Next come the two operators beginners conflate with those: replicate (”! replicates a step n times at equal duration”) and elongate (”@ elongates a step proportionally”), drilled until the *, !, @ distinction is automatic. The learner then layers with commas, contrasts square-bracket polyrhythm against curly-bracket polymetre, and drops in a Euclidean hi-hat via the (k,n) parenthesis notation. The capstone strips the scaffolding away: a blank buffer, one polymetric pattern combining all of it, plus a spoken explanation of why the cross-rhythm emerges — which is gated by the cycle-as-time-unit and cycle-not-beat atoms, since the explanation only works if you understand that everything is rescaled into one shared cycle.
Supporting atoms enrich rather than gate: the / stretch operator, angle-bracket alternation, the euclid function form, Strudel’s polymeter variants, and the Bol Processor lineage that explains where this notation’s cyclic worldview comes from.
Walkthrough
Mini-notation is your drum machine on stage — no piano roll, just operators you type without thinking. At strudel.cc (Ctrl-Enter play, Ctrl-. stop) we drill each operator, then combine them. Everything sits in one cycle: more tokens = faster, not longer ([[tidal-cycle-as-time-unit]]). Each step is a complete, playable program.
1 — subdivide with [ ]. A bracket group packs several hits into one step’s time. Here beat 2 holds two snares and beat 4 holds three — the grid bends without changing the bar ([[mini-notation-sub-sequence]]).
sound("bd [sd sd] bd [sd sd sd]").bank("RolandTR909")
2 — multiply * and rest ~. *n repeats a step n times in its own slot (a roll); ~ is silence. hh*4 is a sixteenth-note roll on beat-4’s slot, ~ punches a hole ([[mini-notation-multiply]], [[mini-notation-rest]]).
sound("bd ~ sd hh*4").bank("RolandTR909")
3 — replicate ! vs elongate @ (the operators beginners conflate). !n makes n separate steps (each a full slot); @n holds one step across n slots. So bd!3 is three even kicks, sd@3 is one snare stretched over three — versus * which crams repeats into a single slot. Hear the difference ([[mini-notation-replicate]], [[mini-notation-elongate]]).
sound("bd!3 sd@3 hh").bank("RolandTR909")
4 — layer in parallel with , (polyrhythm). A comma inside one string stacks voices that share the cycle — three different subdivisions at once, a cross-rhythm from one line ([[tidal-polyrhythm-comma-syntax]]).
sound("bd*4, ~ sd ~ sd, hh*8").bank("RolandTR909")
5 — polymetre with { }%n. Curly braces align by step, not by cycle: {cp cp cp}%8 lays 3 claps onto an 8-step grid, so the phrase drifts against the 4/4 and slowly rotates — cheap evolution from one token group ([[tidal-polyrhythm-polymetre]]).
sound("bd*4, {cp cp cp}%8").bank("RolandTR909")
6 — a Euclidean hat and the whole polymetric groove (the capstone). Add (k,n) — k hits spread evenly over n steps — and combine every operator: replicated/subdivided kick, an elongated snare accent, a Euclidean hat, and a polymetric clap. It’s dense on the page but each voice is one idiom, and the cross-rhythm emerges because all of them are rescaled into the same cycle ([[tidal-euclidean-notation]], [[tidal-cycle-not-beat-orientation]]):
$: sound("bd!2 ~ [bd bd] ~").bank("RolandTR909")
$: sound("~ sd@2 ~").bank("RolandTR909")
$: sound("hh(5,8)").bank("RolandTR909").gain(0.5)
$: sound("{cp cp cp}%8").bank("RolandTR909").gain(0.4)
What good sounds like. A groove that drifts but stays legible — the kick-and-snare backbone holds while the Euclidean hats and polymetric clap rotate against it, so it sounds like it’s evolving without you editing. If it turns to mush, the polymetre or Euclid layer is too loud (drop its .gain) or too busy; the ear needs the plain backbone to hear the cross-rhythm against. The skill is typing these operators mid-set without looking. (Skill map: live-coder Domain B1 / A2 — mini-notation fluency.)
Now make it yours. Change the Euclid to hh(7,16) for busier hats. Push the clap polymetre to %6 and feel the drift speed up. Swap ! for * on the kick and hear replication become a roll. Add a fifth voice: sound("~ oh") for an offbeat open hat.
Runnable examples
Generated from the context/ instrument corpus by concept (redistributable idioms only). Do not edit — regenerate with gen-module-examples.mjs.
euclidean-rhythm
s("bd(3,8)")
strudel-0004 · CC0
d1 $ sound "bd(3,8)"
tidal-0004 · CC0
polymeter
s("{bd sd, hh hh hh}%4")
strudel-0007 · CC0
d1 $ sound "{bd sn, hh hh hh}%4"
tidal-0007 · CC0
polyrhythm
s("bd*3, hh*4")
strudel-0006 · CC0
d1 $ sound "bd*3, hh*4"
tidal-0006 · CC0
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating
Part of curricula
- Live Coder — zero to performing live-coded music — Patterns, Grooves & Voices required
Unlocks — modules that require this one