Pattern Methods
Pattern methods transform or inspect a pattern value and chain freely: [C4 D4 E4].fast(2).transpose(5).reverse().
| Method | Returns | Meaning |
|---|---|---|
fast(factor) | Pattern | Speed up by factor |
slow(factor) | Pattern | Slow down by factor |
transpose(semitones) | Pattern | Shift pitches in semitones |
reverse() | Pattern | Mirror events within each cycle |
rotate(steps) | Pattern | Rotate events by steps, wrapping |
stack(other) | Pattern | Layer two patterns simultaneously |
cat(other) / concat(other) | Pattern | Alternate patterns cycle by cycle |
euclid(hits, steps [, rotation]) | Pattern | Euclidean rhythm |
degrade(probability) | Pattern | Randomly drop events |
nudge(offsets) | Pattern | Per-step timing offsets |
swing(amount) | Pattern | Shift odd-indexed events forward |
humanize(amount) | Pattern | Pseudo-random timing variation |
in_key(key) | Pattern | Resolve scale degrees against a key |
quantize(key) | Pattern | Snap pitches to the nearest scale tone |
map(fn) | Pattern | Transform each note through a function |
map_with_timing(fn) | Pattern | Transform with position and duration |
iter() | Iterator | Infinite iterator over events |
at(index) | Pattern | Element at index (same as p[index]) |
length() | Number | Event count in cycle 0 |
describe() | String | Human-readable structure description |
kind() | String | Concrete pattern kind |
elements() | Array | Child sub-patterns |
Time & Pitch Transforms
Section titled “Time & Pitch Transforms”fast(factor)
Section titled “fast(factor)”Speed up the pattern — fast(2) fits two cycles into one.
let doubled = [C4 D4 E4 F4].fast(2);let varied = [C4 D4].fast(<1 2 4>); // patterned factor, changes per cycleslow(factor)
Section titled “slow(factor)”Slow down the pattern — slow(2) stretches one cycle over two.
let halftime = [C4 D4 E4 F4].slow(2);transpose(semitones)
Section titled “transpose(semitones)”Shift all pitches by semitones (negative shifts down). On sample patterns this applies a pitch-shift instead.
let octave_up = [C4 D4 E4].transpose(12);let down_fifth = [C4 D4 E4].transpose(-7);let moving = [C4 E4 G4].transpose([0 7 12]); // per-cycle shiftreverse()
Section titled “reverse()”Mirror events within each cycle.
let back = [C4 D4 E4 F4].reverse(); // F4 E4 D4 C4rotate(steps)
Section titled “rotate(steps)”Rotate events within each cycle, wrapping around. Positive rotates right ([C4 D4 E4].rotate(1) → [E4 C4 D4]), negative rotates left.
let right = [C4 D4 E4].rotate(1);let left = [C4 D4 E4].rotate(-1); // [D4 E4 C4]Combining
Section titled “Combining”stack(other)
Section titled “stack(other)”Layer two patterns so they play simultaneously.
let layered = [C4 E4 G4].stack([C3 G3]);cat(other) / concat(other)
Section titled “cat(other) / concat(other)”Alternate two patterns cycle by cycle: the receiver plays on even cycles, the argument on odd cycles. concat is an alias for cat.
let ab = [C4 D4 E4].cat([F4 G4]);Rhythm & Chance
Section titled “Rhythm & Chance”euclid(hits, steps [, rotation])
Section titled “euclid(hits, steps [, rotation])”Distribute hits onsets as evenly as possible over steps slots (Bjorklund algorithm). The optional third argument rotates the result by that many steps.
let tresillo = [C4].euclid(3, 8);let rotated = [C4].euclid(3, 8, 2);degrade(probability)
Section titled “degrade(probability)”Randomly drop events with the given probability (0–1). Deterministic per event time, so a pattern degrades the same way on every run.
let sparse = [C4 D4 E4 F4].degrade(0.3); // each event has a 30% chance to droplet rising = [C4 D4].degrade([0.0 0.5 0.9]); // per-cycle probabilityMicrotiming
Section titled “Microtiming”All microtiming amounts are step-relative fractions: 0.25 means a quarter of the event’s own step size. Durations are preserved.
nudge(offsets)
Section titled “nudge(offsets)”Shift events by per-step offsets. Accepts a single number (applied to every event), an array #[...] of offsets cycled through per event, or a pattern (queried per cycle).
let pushed = [C4 D4 E4 F4].nudge(0.1);let groove = [C4 D4 E4 F4].nudge(#[0, 0.25, 0, -0.1]);let drift = [C4 D4].nudge(<0.0 0.1>);swing(amount)
Section titled “swing(amount)”Shift odd-indexed events forward by amount; even-indexed events stay on the grid.
let swung = [C4 D4 E4 F4].swing(0.25);humanize(amount)
Section titled “humanize(amount)”Add a pseudo-random offset in [-amount, +amount] to each event. Offsets are derived by hashing the event time, so results are deterministic and reproducible.
let loose = [C4 D4 E4 F4].humanize(0.05);Keys & Tonality
Section titled “Keys & Tonality”in_key(key)
Section titled “in_key(key)”Resolve scale-degree elements (^1, ^5:maj7, …) to concrete pitches using a key. MIDI notes and samples pass through unchanged.
let k = Key(C4, "major");let melody = [^1 ^3 ^5 ^-2].in_key(k);let diatonic = [^1: ^4: ^5:].in_key(Key(A3, "minor"));quantize(key)
Section titled “quantize(key)”Snap MIDI pitches to the nearest scale tone of the key. Degrees and samples are left unchanged.
let snapped = [C4 C#4 D4 D#4].quantize(Key(C4, "major"));Mapping & Iteration
Section titled “Mapping & Iteration”map(fn)
Section titled “map(fn)”Transform each event through a function. The function receives the MIDI pitch as a number and returns the replacement — a note, number, array, pattern, or rest.
let up = [C4 D4 E4].map(fn(note) { return note + 12; });let split = [C4 G4].map(fn(note) { if note > 64 { return note + 12; } return note;});map_with_timing(fn)
Section titled “map_with_timing(fn)”Like map, but the function also receives start (cycle position, 0–1) and dur (event duration in cycles).
let accented = [C4 D4 E4 F4].map_with_timing(fn(note, start, dur) { if start == 0.0 { return note + 12; } // lift the downbeat return note;});iter()
Section titled “iter()”Create an infinite iterator over the pattern’s events. Each item is an event value carrying note, start, and duration. Always bound it with .take(n).
let events = [C4 D4 E4].iter().take(6).collect();for event in [C4 E4 G4].iter().take(3) { PRINT event.note();}Indexing & Introspection
Section titled “Indexing & Introspection”at(index)
Section titled “at(index)”Element at a zero-based index, returned as a pattern. p[index] is equivalent. Works on indexable patterns (sequences, stacks, alternations); out-of-range indices are an error.
let seq = [C4 D4 E4 F4];let first = seq.at(0);let third = seq[2];length()
Section titled “length()”Number of events in cycle 0.
let n = [C4 D4 E4].length(); // 3describe()
Section titled “describe()”Human-readable description of the pattern’s structure — useful for debugging chained transforms.
let what = [C4 D4].fast(2).reverse().describe();PRINT what;kind()
Section titled “kind()”The concrete pattern kind as a string ("Sequence", "Stack", "Fast", …).
let k = [C4 D4].fast(2).kind(); // "Fast"elements()
Section titled “elements()”Child sub-patterns as an array — the layers of a stack, the parts of a concatenation, and so on.
let layers = [C4 D4].stack([E4 F4]).elements();PRINT layers.length(); // 2See Also
Section titled “See Also”- Transforming Patterns — narrative guide with musical recipes
- Microtiming — groove, swing, and humanization in depth
- Mini-Notation Grammar — the syntax inside pattern brackets