2. Rhythm Section
Nimbus has dedicated drum machines for kick, snare, and hi-hat. They use drum-mode seq strings (x = hit, . = rest) instead of scale degrees.
The three drum machines
function* song(ctx) { const kk = kick() const sn = snare() const hh = hat()
yield cast(kk, 'drums', seq(4, 'x.x.x.x.'), ctx) yield cast(sn, 'drums', seq(4, '..x...x.'), ctx) yield cast(hh, 'drums', seq(4, 'x.x.x.x.'), ctx)}Pass 'drums' as the second argument to cast whenever you use a drum machine — pitch is ignored.
kick — bass drum
kick() is a synthesized bass drum based on a pitch-swept sine wave. Key parameters:
| Parameter | Default | Effect |
|---|---|---|
pitch | 60 Hz | Starting frequency — higher = tighter, lower = boomy |
decay | 0.3 s | Length of the tail |
punch | 0.8 | Transient click — higher = harder attack |
gain | 0.8 | Output level |
// Standard kickkick()
// Tight and punchy (techno/house)kick({ pitch: 80, decay: 0.15, punch: 1.0 })
// Deep and slow (hip-hop / trap)kick({ pitch: 40, decay: 0.8, punch: 0.5 })
// High and clicky (dry click track)kick({ pitch: 120, decay: 0.05, punch: 1.0, gain: 0.6 })snare — snare drum
snare() combines a tonal body with a noise burst. Key parameters:
| Parameter | Default | Effect |
|---|---|---|
tone | 180 Hz | Body frequency — higher = brighter crack |
snap | 0.9 | Noise punch amount |
decay | 0.15 s | Length of the tail |
gain | 0.7 | Output level |
// Standard snaresnare()
// Tight crack (reggae / pop)snare({ tone: 220, snap: 1.0, decay: 0.08 })
// Deep rimshotsnare({ tone: 140, snap: 0.5, decay: 0.25 })
// Snappy clap-like hitsnare({ tone: 300, snap: 1.0, decay: 0.04, gain: 0.8 })hat — hi-hat
hat() is a metallic noise oscillator. Key parameters:
| Parameter | Default | Effect |
|---|---|---|
decay | 0.05 s | Length — short = closed, long = open |
tone | 8000 Hz | Filter frequency — higher = brighter |
gain | 0.5 | Output level |
// Closed hi-hat (default — very short)hat()
// Open hi-hathat({ decay: 0.35 })
// Ride cymbal feelhat({ decay: 0.6, tone: 6000, gain: 0.4 })
// Shaker / ghost hathat({ decay: 0.02, tone: 10000, gain: 0.25 })Drum patterns
Classic patterns
// 4/4 rock beatyield cast(kk, 'drums', seq(4, 'x.x.x.x.'), ctx) // kick on 1, 2.5, 3, 4yield cast(sn, 'drums', seq(4, '..x...x.'), ctx) // snare on 2 and 4yield cast(hh, 'drums', seq(4, 'x.x.x.x.'), ctx) // 8th-note hat
// Straight four-on-the-floor (house/techno)yield cast(kk, 'drums', seq(4, 'x...x...x...x...'), ctx) // 16th grid
// Trap hi-hat: dense 16th notes with gapsyield cast(hh, 'drums', seq(4, 'x.xx.x.xx.xx.x..'), ctx)Syncopation
Offset the kick or snare from the beat for groove:
// Syncopated kick (pushes beat 3)yield cast(kk, 'drums', seq(4, 'x...x.x.....x...'), ctx)
// Reggaeton / dembow (kick on 1 and "and-3")yield cast(kk, 'drums', seq(4, 'x.....x.x.......'), ctx)yield cast(sn, 'drums', seq(4, '....x.......x...'), ctx)Ghost notes with velocity
Add a (v:low) suffix to make a hit quieter (velocity 0–1):
// Snare with ghost notes — lowercase = implied low velocity in text, use w: for weightedyield cast(sn, 'drums', seq(4, '..x...x.'), ctx) // main hitsPolymeter — different loop lengths
When a drum sequence has a different beats value from the other patterns, it loops at its own rate. This creates evolving, interlocking rhythms automatically.
function* song(ctx) { const kk = kick() const sn = snare() const hh = hat()
yield cast(kk, 'drums', seq(4, 'x...x...x...x...'), ctx) // 4 beats yield cast(sn, 'drums', seq(3, '..x.x.'), ctx) // 3 beats — loops every 12 beats yield cast(hh, 'drums', seq(2, 'x.x.x.x.'), ctx) // 2 beats}The kick, snare, and hat are now in 4:3:2 ratio — they realign every 12 beats.
Full rhythm section example
A complete beat with melodic bass:
function* song(ctx) { const kk = kick({ decay: 0.25 }) const sn = snare({ snap: 0.8 }) const hh = hat({ decay: 0.04 }) const ohh = hat({ decay: 0.3, gain: 0.3 }) const bass = vasynth({ wave: 'sine', cutoff: 600, attack: 0.01, release: 0.15, gain: 0.7 }) const bKey = scales(4, 'C2:minor')
yield cast(kk, 'drums', seq(4, 'x...x.x.....x...'), ctx) yield cast(sn, 'drums', seq(4, '....x.......x...'), ctx) yield cast(hh, 'drums', seq(4, 'x.x.x.x.x.x.x.x.'), ctx) yield cast(ohh, 'drums', seq(4, '......x.......x.'), ctx) yield cast(bass, bKey, seq(4, '0,_,_,4,_,2,_,_'), ctx)}Next
3. Melody & Harmony → — add chord progressions and multi-voice melody.