Each voice is rendered ONCE per setting into an AudioBuffer and played back with a BufferSource, rather than being built as a node graph per hit. Every drum here is a one-shot, struck, decaying, unchangeable afterwards, so there is nothing a live graph could do that a buffer cannot, and the difference at sixteen hits a second is one node per strike instead of six. It is the arrangement the pluck module uses for the same reason, and it has a second payoff: the recipes become a pure function of (voice, params, sample rate), so the kick's sweep and the tone control's flat centre are asserted in Node rather than described.
The kick integrates its phase sample by sample as the frequency falls, rather than evaluating sin(2·pi·f(t)·t). The second form is the classic sweep bug: as f falls, the phase argument can run backwards, and the sweep arrives with a discontinuity in it. Everything with a pitch envelope here, the kick, both toms, is written the first way.
Every noise source is drawn from the SDK's seeded xorshift32, forked by the voice's own id. Math.random() is forbidden in DSP in this repo, and rendering to a buffer makes the rule easy to keep rather than merely stated: the same snare produces the same samples on every machine and in every run, and forking per voice rather than sharing one stream means adding a voice later cannot shift the noise in the ones beside it.
The choke group is two rules kept separate. RETRIGGER: a voice struck again cuts its own previous ring, which every voice does because one drum cannot be hit twice at once. CHOKE: a voice struck cuts every other member of its group, which only the hats have. Both cut with a 4 ms fade rather than a hard stop, because a buffer stopped mid-cycle is a click and a click on every closed hat would be the loudest thing in the mix.
The step player lives inside the voice pool, not in the React layer. A setTimeout in a component fires whenever the main thread gets round to it, so a pattern driven from React drifts audibly under any load; instead a timer wakes every 25 ms, asks a pure function which hits fall in the next 120 ms, and commits each one with an absolute audio-clock time. The pure half, which hits, at what times, with which accent velocities, is a function of an origin and a window, so it is tested from a mocked clock with no audio in the loop at all.
Accent is a velocity, not a second sound: 118 against 86 on the unaccented steps, which through the velocity-squared law comes out about 5 dB louder. A linear velocity map would put those two 3 dB apart and make the accent switch look broken, which is the whole reason the law is squared here as it is everywhere else in this repo.
The pad grid and the step lane are ui-kit registry items rather than parts of this page. Their layout, hit testing, velocity law, drag-paint rule and playhead maths sit in pure cores beside them with their own tests, per the surface catalog's rule that gesture maths lands in the kit first, which is also what lets the pads' choke badge and the engine's choke cut be the same function.