Z zvuk
FX

Compressor

Dynamic range compression as a bus FX insert. Wraps DynamicsCompressorNode + makeup gain. Bypass is a graph swap — no parameter latency.

TL;DR

Compresses the dynamic range of whatever you route through it. Use it on a voice bus to even out dialogue, on a music bus for glue, or on the master as a limiter (with ratio: 20 and a fast attack).

API surface

Compressor + CompressorConfig ts
class Compressor implements FxInsert {
  readonly input: GainNode;
  readonly output: GainNode;

  bypassed: boolean;                  // graph-swap, not a parameter

  applyConfig(c: CompressorConfig): void;
  get reduction(): number;            // live gain reduction (negative dB)
  dispose(): void;
}

interface CompressorConfig {
  threshold?: number;                 // dB, default -24
  knee?:      number;                 // dB,   default 30
  ratio?:     number;                 // n:1,  default 12
  attack?:    number;                 // s,    default 0.003
  release?:   number;                 // s,    default 0.25
  makeupGain?: number;                // dB,   default 0
}

Live demo

Five knobs and a live reduction meter. Toggle bypass to A/B against the dry signal — the meter goes to zero when bypassed.

Recipes

Voice bus glue

ts ts
import { Compressor } from 'zvuk';

const comp = new Compressor(engine.context, {
  threshold: -18,
  ratio: 4,
  attack: 0.005,
  release: 0.18,
  makeupGain: 6,
});

engine.bus('voice').addFx(comp);

// Live tweaks:
comp.applyConfig({ threshold: -22, ratio: 6 });
comp.bypassed = true;                 // a/b test

Read live gain reduction

ts ts
setInterval(() => {
  console.log('reduction:', comp.reduction.toFixed(2), 'dB');
}, 33);

Pitfalls

Don't compress music to mush.
Ratios above 8:1 on music sound pumpy. Reserve heavy ratios for voice or SFX glue; for music sit at 2:1–4:1 with a soft knee.
Don't dial makeupGain to compensate fully.
Match the bypassed level by ear, not by math. The compressor is doing work; trust the meter, not the knob.
Don't put a Compressor on every bus.
Each bus's compressor is independent. Stacking them makes your mix breathe in unpredictable ways. Pick the bus where the dynamics actually matter.

Related