Transform a Pattern
Each recipe starts from a pattern you already have and returns a new one. The original is never changed, so you can derive as many variations from one motif as you need. Every method is listed in the pattern methods reference.
Play a phrase faster or slower
Section titled “Play a phrase faster or slower”.fast(n) plays the pattern n times per cycle; .slow(n) stretches it across n cycles.
use "std/instruments" { SamplerMelodic, Kit };
let lead = AudioTrack("lead");lead.set_instrument(SamplerMelodic(Kit("keys")));
lead << [C4 E4 G4 C5].reverse().fast(2); // descending, twice per cycle
PLAY;[C4 D4 E4].fast(2) and the mini-notation [[C4 D4 E4]*2] give the same result.
Harmonize a melody
Section titled “Harmonize a melody”Stack the melody against a transposed copy of itself. Four semitones up is a major third:
let melody = [C4 D4 E4 F4];print(melody.stack(melody.transpose(4)).describe());.transpose() leaves rests untouched, so a melody with gaps harmonizes cleanly.
Turn a phrase into a palindrome
Section titled “Turn a phrase into a palindrome”Append a reversed copy:
let base = [C4 D4 E4 G4];print(base.concat(base.reverse()).describe());.rotate(n) is the other reordering: it shifts the notes right by n (negative shifts left) and
wraps around the ends.
Thin out a busy part
Section titled “Thin out a busy part”.degrade(p) drops each note with probability p. On a stream of hi-hats it adds occasional gaps:
use "std/instruments" { Sampler, Kit };
let hats = AudioTrack("hats");hats.set_instrument(Sampler(Kit("TR-808")));
hats << [ch*8].degrade(0.15); // straight 8ths, about 15% of hits dropped
PLAY;The same hits drop on every playback. To change which hits drop, change the pattern.
Rewrite every note
Section titled “Rewrite every note”.map(fn) calls your function with each note’s MIDI number and plays what it returns: a number
replaces the note, an array turns it into a chord, and a pattern substitutes a sub-sequence. Fold
a melody into one octave:
let melody = [C4 D4 E4 F4 G4];
let folded = melody.map(fn(note) { return 60 + (note % 12);});print(folded.describe());Change notes by where they fall in the cycle
Section titled “Change notes by where they fall in the cycle”.map_with_timing(fn) also passes each note’s start (0.0 to 1.0 in the cycle) and its
duration. Lift the second half of the cycle up an octave:
let pat = [C4 D4 E4 F4];
let lifted = pat.map_with_timing(fn(note, start, dur) { if start >= 0.5 { return note + 12; } return note;});print(lifted.describe());Find out what a chain does
Section titled “Find out what a chain does”When a chain doesn’t sound the way you expect, print .describe() and read it inside-out.
.length() counts the events in one cycle:
print([C4 D4 E4].reverse().transpose(7).describe());// => Transpose(7, Reverse(Sequence[3]))
print([C4 D4 E4 F4].length());// => 4Transpose(7, Reverse(Sequence[3])) is a three-note sequence, reversed, then transposed. If the
order is not what you meant, reorder the chain. How Patterns Work
explains why the order matters.