Compressor
Dynamic range compression as a bus FX insert. Wraps DynamicsCompressorNode and makeup gain. Bypass is a graph swap, so it has no parameter latency.
One line of dialogue is a whisper and the next is a shout, and the player is on a phone at a bus stop. Compression is how you make both audible without making either wrong.
A Compressor narrows the
dynamic range of whatever passes through it. Use it on a voice bus to even
out dialogue, on a music bus for glue, or on the master as a soft limiter
at ratio: 20 with a fast attack.
It is limiter-like and not a brick wall. With a finite attack and no lookahead, transients still get through, so it is not a guarantee against clipping.
API surface
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 drops to zero when bypassed.
Recipes
Voice bus glue
import { Compressor } from '@schmooky/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
setInterval(() => {
console.log('reduction:', comp.reduction.toFixed(2), 'dB');
}, 33); Pitfalls
Related
- FX index
- Sidechain ducking covers Ducker, a compressor keyed from another bus.
- Bus is where FX inserts live.