Z zvuk
Guide

Building your mix

The shape of a five-bus production mix. Pick the buses, declare them at construction, route everything through them.

Pick your buses up front

Most game-style apps land on the same five-or-six buses. Don't over-think this on day one — you can always rename later.

  • music — looped background tracks; one voice at a time, occasionally crossfaded.
  • sfx — gameplay one-shots, dense, polyphonic.
  • voice — VO, dialogue, alerts; usually exclusive (one at a time).
  • ambience — looped environmental textures.
  • ui — clicks, hovers, modal opens.

Bare-bones declaration

ts ts
createEngine({
  buses: {
    music:    { level: 0.7 },
    sfx:      { level: 1.0, concurrency: { max: 32 } },
    voice:    { level: 1.0, concurrency: { max: 1, steal: 'none' } },
    ambience: { level: 0.4 },
    ui:       { level: 0.6 },
  },
  master: { headroom: -3 },
});

What it looks like

bus graph
SOURCES music.mp3 crowd.webm coin.webm click.webm voice.m4a BUSES music level 0.8 · concurrency 4 fx: reverb sfx level 1.0 · concurrency 32 steal: oldest voice level 1.0 · ducks music fx: ducker(from: voice) MASTER Master headroom -3 dB 🔊 dest sidechain (voice → music)

Add FX inserts

ts ts
import { Compressor, Reverb } from 'zvuk';

engine.bus('music').addFx(new Reverb(engine.context, { wet: 0.2 }));
engine.bus('voice').addFx(new Compressor(engine.context, {
  threshold: -18, ratio: 4, attack: 0.005, release: 0.15,
}));

Reverb on music is for atmosphere. Compressor on voice levels out dialogue without losing presence. Don't put reverb on SFX — individual hits sound smeared.

Master headroom

ts ts
// Master gets -3 dB of headroom. Lifts the ceiling for transient SFX
// without clipping. If you hear pumping or clicks, drop to -6.
createEngine({ master: { headroom: -3 } });

Live mixer

engine.state = cold
0 voices

What about ducking?

Sidechain a target bus from a source bus — when the source is loud, the target dips. See the ducking guide.

Pitfalls

Don't declare buses you don't use.
Each bus is two GainNodes. Negligible cost individually, but ten unused buses is a yard sale.
Don't expose the master gain to UI.
Master is for mix headroom and mute (e.g. tab visibility). User volume belongs on a bus or a parameter — most users want a music slider, not a global knob.