Concurrency
Voice limits with a steal strategy. Keeps polyphony bounded, and decides which voice dies when the limit is hit.
Hold a button that fires a 50 ms click every frame. Thirty seconds later you have eighteen hundred live voices, a stalled audio thread, and a fan at full tilt. Nothing in the Web Audio API stops you.
Concurrency is a per-bus cap on how many voices may sound at once,
together with a rule for what happens when a new voice arrives at a full
bus. That rule is the steal strategy. It picks an existing voice
to end so the new one can play, and it runs synchronously, before
play() returns.
How many voices can play at once?
As many as you allow. The cap is declared per bus, so a UI bus can hold
four while an SFX bus holds thirty-two. A bus with no
concurrency block is unbounded, which is the right default
for music and the wrong one for anything a player can spam.
Strategies
- oldest kills the voice that started first. This is the default, and the right call for SFX rain.
- lowest-priority kills the voice with the smallest
priority. Use it when you have a hierarchy: a hero attack outranks a footstep, which outranks an ambience tick. - quietest kills the least audible voice. It ranks candidates by an existing meter tap where one exists and by the voice's own gain otherwise, so it costs nothing per candidate.
- none rejects the new voice. The returned
Voiceis already ended.
API
createEngine({
buses: {
sfx: { concurrency: { max: 32, steal: 'oldest' } },
voice: { concurrency: { max: 1, steal: 'lowest-priority' } },
},
}); engine.bus('sfx').setConcurrency({ max: 8, steal: 'lowest-priority' }); Live demo
Change max and steal, then mash "Fire voice".
Slots fill, and once you pass the cap you can watch which voice the
strategy picks.
Recipes
Protect important voices
// Hero hit — protected from stealing.
engine.sound('player-hit').play({ priority: 10 });
// Footstep — cheap, expendable.
engine.sound('footstep').play({ priority: 0 });
With steal: 'lowest-priority', the player-hit voice survives
until it ends naturally or another priority-10 voice arrives.
Pitfalls
steal: 'none' for SFX.'none' for a voice or alarm bus, where you
want the announcement that is already playing to finish.
max: 4 that sounds chopped. Profile real gameplay before
clamping.