Mini-Notation Basics
Mini-notation is a compact syntax for describing musical patterns, inspired by TidalCycles and Strudel.
Typed prefixes
Mini-notation strings carry a parse-mode prefix that disambiguates atom semantics:
| Prefix | Atom semantics | Example |
|---|---|---|
v"…" | Numeric only (raw scalars, no mtof) | v"<0 0.5 -0.5>" |
n"…" | Note names + bare MIDI ints (both → Hz) | n"c4 e4 g4" |
s"…" | Sample names | s"bd ~ bd ~" |
c"…" | Chord symbols | c"Am C G" |
n"…" | Auto-detect (legacy, still works) | n"c4 bd Am" |
See Pattern Literals for full coverage of typed prefixes and the scalar() cast.
Pitch tokens
Specify notes with letter name and octave:
// Single notes
n"c4" // Middle C
n"f#3" // F sharp, octave 3
n"Bb5" // B flat, octave 5 Sequences (top-level alternation)
Top-level spaces play one element per cycle. One cycle equals one beat by default, so "c4 e4 g4 c5" plays four notes across four cycles — one per beat.
// One note per cycle (= one note per beat)
n"c4 e4 g4 c5"
|> ((f) -> sine(f) * ar(trigger(1)))
|> out(@) This is a deliberate divergence from Strudel/Tidal, which treats top-level as subdivision. We chose per-cycle alternation so long melodies stay readable as "c d e f g a b c5" without anyone having to count elements to predict the playback speed.
<a b c d> is documented as a synonym of the top-level form — same per-cycle alternation.
Rests
Use ~ or _ for silence:
// Rest on cycle 3
n"c4 e4 ~ g4" Chords
For chord symbols (Am7, Cmaj7), inline chord brackets ([c4 e4 g4]), and voice-leading transforms (anchor, mode, voicing, addVoicings), see Chords.
// Inline chord, three notes at once
n"[c4 e4 g4]"
// Chord-symbol progression — one chord per cycle
chord("Am C G F") Grouping ([…]) — pack into one cycle
Use square brackets to pack multiple elements into a single cycle:
// Four notes packed into one cycle (= four sixteenths per beat at default)
n"[c4 e4 g4 c5]"
// Mix: c4 cycle, then [e4 f4] subdivided into one cycle, then g4 cycle, then c5
n"c4 [e4 f4] g4 c5" Polyrhythms
Comma separates parallel patterns:
// 3 against 4
n"c4 e4 g4, c3 g3 c3 g3" Modifiers
Modifiers change how pattern elements are played. Important: Modifiers must be inside the pattern string.
Speed (*n)
Repeat an element n times in its time slot:
// Repeat c4 four times (fits 4 notes in 1 slot)
n"c4*4 e4"
// Speed up a group
n"[c4 e4]*2 g4" // [c4 e4 c4 e4] in first half Slow (/n)
Stretch an element to span n times its normal duration:
// Stretch pattern to 2 cycles
n"[c4 e4 g4 b4]/2" // Events at beats 0, 2, 4, 6
// Slow down individual note
n"c4/2 e4 g4" Repeat (!n)
Replicate an element n times (extends the sequence):
// a!2 b = a a b (3 elements, each takes 1/3 of time)
n"c4!2 e4" // c4 appears twice, then e4
// Compare with speed (*n) which compresses:
// a*2 b = [a a] b (2 elements, first has 2 notes in half the time)
n"c4*2 e4" // c4 plays twice quickly, then e4 Chance (?n)
Set probability (0-1) of the element playing:
// 50% chance each note plays
n"c4?0.5 e4?0.5 g4?0.5" Weight/Elongation (@n)
Adjust temporal weight (how much time an element takes relative to siblings):
// First note takes twice as much time
n"c4@2 e4 g4" // c4: 50%, e4: 25%, g4: 25%
// Create uneven rhythms
s"bd@3 sn" // bd: 75%, sn: 25% Alternation
Use angle brackets for elements that alternate each cycle:
// Plays c4 on cycle 1, e4 on cycle 2, g4 on cycle 3, then repeats
n"<c4 e4 g4>"
// Alternate between groups
n"<[c4 e4] [g4 b4]>" Modifier placement
Critical: Pattern modifiers must be inside the pattern string:
// CORRECT: modifier inside string
s"[bd sn]/2" // Pattern plays over 2 cycles
// WRONG: modifier outside string
s"bd sn"/2 // This divides the SIGNAL by 2, not the pattern! Pattern functions
Typed pattern literals
Basic pattern playback:
n"c4 e4 g4" |> ((f) -> sine(f)) |> out(@) Practical examples
// Simple melody
n"c4 e4 g4 e4" |> ((f) ->
saw(f) |> lp(@, 1500) * ar(trigger(4))
) |> out(@) // Chord progression
chord("C Em Am G") |> ((f) ->
saw(f) |> lp(@, 800) * ar(trigger(1), 0.1, 0.5)
) |> out(@) // Rhythmic pattern with rests
n"c4 ~ e4 ~ g4 ~ e4 ~" |> ((f) ->
tri(f) * ar(trigger(8), 0.01, 0.1)
) |> out(@) Related: Sequencing, Closures