@maruaudio/dsp/voices/round-robin picks which alternate take of a sample group plays next, deterministically, so every execution lane draws the same sequence. Three modes: cycle (cursor modulo the take count), random (one Numerical Recipes LCG step, high 16 bits, modulo the count) and random-cycle (an LCG-chosen take among those not yet visited, so every take plays once before the mask resets, and the first draw of a new cycle avoids the previous take when at least two are available). The cursor, visited mask and previous take are kept per group and per key, so a group spanning the keyboard rotates each key on its own; the LCG stays per group. The source header says the arithmetic was extracted unchanged from @maru/voices-sampler-zone.
Parameters
| Input | Coded range and meaning |
|---|---|
state.count[group] | Eligible takes for this draw, written by the caller; 0 or 1 always selects take 0 |
group | 0 to 127 (ROUND_ROBIN_MAX_GROUPS 128); group 0 is by convention not round-robined |
key | 0 to 127 (ROUND_ROBIN_MAX_KEYS) for nextRoundRobinKeyTake |
mode | ROUND_ROBIN_OFF 0 (layered, not drawn), CYCLE 1, RANDOM 2, RANDOM_CYCLE 3; any other value draws as random-cycle |
Each group's seed is group × 2654435761 mod 2^32 (roundRobinSeed), Knuth's multiplicative hash. roundRobinBit(n) is 2^n by repeated doubling.
Lifecycle
createRoundRobinState() allocates six typed arrays once: count, random and selected per group, cursor, visited and previous per (group, key) → resetRoundRobin reseeds every group and clears every rotation → per note, write count, then nextRoundRobinKeyTake(state, group, key, mode) (or nextRoundRobinTake, the same draw at key 0) returns the take.
When to use it
Alternate takes of the same hit or note, so repeated strikes of one key do not repeat one recording: cycle for a fixed order, random or random-cycle for a varied one that is the same on every run.
Limits
- Integer arithmetic only, through
%,Math.floorand repeated doubling, so the closure lowers to every target. - Random-cycle addresses at most 32 takes (
ROUND_ROBIN_MAX_TAKES, the mask width); the cycle cursor is stored in aUint8Array. - The draw functions do not write
state.selected; read the return value. - No audio output.