DSL Overview
The song generator
Every Nimbus program is a JavaScript generator function:
function* song(ctx) { // ...}function* makes song a generator. The engine calls it once per cycle and
collects everything you yield. ctx is the cycle context object.
ctx.cycle is the current cycle number, starting at 0.
Yield patterns
yield cast(...) sends one pattern to the engine for the current cycle.
You can yield multiple times to play multiple parts simultaneously:
function* song(ctx) { const key = scales(4, 'C4:major') const synth = vasynth({ wave: 'sawtooth', gain: 0.5 }) const kk = kick({ freq: 58, gain: 0.7 })
yield cast(synth, key, seq(4, '0,2,4,~'), ctx) yield cast(kk, 'drums', seq(4, 'x.x.'), ctx)}Branch with ctx.cycle
Use ctx.cycle to change phrases over time:
if (ctx.cycle % 4 === 0) { yield cast(bells, key, seq(4, '(every4:0)'), ctx)}Cycle length
The beatsPerCycle control in the header sets how many beats each cycle
contains. Options: 4 / 8 / 16. The engine uses this value for all timing
calculations. ctx.beatsPerCycle exposes the current setting inside the
generator.
Structuring longer pieces
Use arrange() instead of manual ctx.cycle branching to
describe multi-section compositions:
yield* arrange(ctx, [ { name: 'intro', cycles: 8, patterns: [cast(bass, key, bassSeq, ctx)] }, { name: 'verse', cycles: 16, patterns: [cast(bass, key, bassSeq, ctx), cast(lead, key, leadSeq, ctx)] }, { name: 'chorus', cycles: 8, patterns: [cast(bass, key, chorusSeq, ctx), cast(lead, key, leadSeq, ctx)], crossfade: 4 },])For self-evolving patterns, see Generative — markov() & lsys().