Add Swing and Human Feel
Swing is measured on a grid you name; nudge and humanize are measured on each event’s own step. Notes keep their length when they move. How Patterns Work explains the model.
Swing a pattern
Section titled “Swing a pattern”.swing(amount, grid) cuts the cycle into grid slots and delays every second one, like the
swing on a drum machine. 16 swings 16ths, 8 swings 8ths. Whatever plays on the beat stays, so a
whole kit swings as one groove:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.set_instrument(Sampler(Kit("CR-78")));
drums << [bd*4, _ cp _ cp, hh*16].swing(0.1, 16);
PLAY;The kicks and claps sit on the grid’s even slots and don’t move; the hats on the odd 16ths play late.
The amount is a fraction of one slot and runs from 0 to 0.5. Start low and raise it by ear;
0.33 puts the delayed slots on the triplet —
How Patterns Work explains why.
The grid is an even number of slots per cycle, from 2 to 1024.
Place a groove by hand
Section titled “Place a groove by hand”.nudge(offsets) moves each event by its own amount: 0.0 is on the grid, positive is later,
negative is earlier. The offsets are used in order and wrap when there are more events than
offsets:
[bd sd bd sd].nudge([0.0, 0.25, 0.0, -0.1]); // snare 1 late, snare 2 early[bd sd bd sd].nudge([0.0, 0.1]); // [0, 0.1, 0, 0.1]Offsets: 0.0 +0.25 0.0 -0.1
Original: | bd | sd | bd | sd | 0 0.25 0.5 0.75 1.0
Nudged: | bd | sd | bd | sd | 0 0.3125 0.5 0.725 1.0Add human timing
Section titled “Add human timing”.humanize(amount) moves each event by an offset within ±amount of its step. The offsets differ
from event to event but are the same on every playback:
[bd sd bd sd].humanize(0.1); // ±10% of a stepStart around 0.05 and raise it until the part loosens without sounding sloppy.
Change the groove from cycle to cycle
Section titled “Change the groove from cycle to cycle”Each method accepts a pattern where it takes an amount, so the groove can alternate:
[hh*8].swing(<0.25 0.33>, 8); // moderate, then triplet[bd sd bd sd].humanize(<0.05 0.2>); // tight, then loose[bd sd bd sd].nudge(<[0 0.25 0 -0.1] [0 0 0 0]>); // nudged, then straightCombine swing and humanize
Section titled “Combine swing and humanize”Set the groove first, then add the jitter:
[hh*8].swing(0.25, 8).humanize(0.05);[bd sd bd sd].nudge([0.0, 0.15, 0.0, -0.08]).humanize(0.05);If you humanize first, the swing is measured from positions that have already moved, and the groove blurs.
Give each layer its own feel
Section titled “Give each layer its own feel”Put the layers on separate tracks and time each one on its own — here straight kicks, swung and humanized hats, and a late snare:
use "std/instruments" { Sampler, Kit };
let kit = Sampler(Kit("CR-78"));
let kicks = AudioTrack("kicks");kicks.set_instrument(kit);kicks << [bd*4].humanize(0.05);
let hats = AudioTrack("hats");hats.set_instrument(kit);hats << [hh*8].swing(0.2, 8).humanize(0.05);
let snares = AudioTrack("snares");snares.set_instrument(kit);snares << [_ sd _ sd].nudge([0.0, 0.1]);
PLAY;