Skip to main content

Master Limiter

Added in 5.8.0

When several sounds play at the same time their waveforms add up. Five samples at full volume sum to roughly five times full scale, and the Web Audio destination hard-clips everything above that ceiling. You hear it as crackle or distortion, most noticeably on sounds with a sharp attack such as piano notes, drum hits or gunfire.

The master limiter holds those peaks back instead of letting them clip. It sits last in the master chain, after volume and panning, so it catches everything on the way out:

sound → gain → pan → master gain → master pan → [limiter] → output

It is off by default, so upgrading to 5.8.0 never changes how an existing project sounds. Turn it on when you mix several sounds at once.

Try it

Play a stack of identical notes with the limiter off and then on. Identical samples add up coherently, so this reaches the clipping ceiling quickly.

Master limiter: off
Overlapping sounds will clip against the output ceiling.
Gain reduction: 0.0 dB
Try this: set the slider to 8 or more and press play with the limiter off. Turn the limiter on and play again. The overall level stays similar, but the harsh edge on the attack disappears because the peaks are no longer being clipped off.

Enabling it

Set it once when you create the manager:

const soundHub = new SoundHub({
createNewInstance: true,
masterLimiter: true, // prevents clipping when sounds overlap
});

Or toggle it at runtime. This only rewires the output chain, so playback is not interrupted:

soundHub.setMasterLimiter(true);
soundHub.isMasterLimiterEnabled(); // true

Tuning it

The defaults are tuned as a brick-wall limiter rather than a compressor:

ParameterValueWhy
threshold-3 dBFSLeaves a little headroom below the ceiling
knee0Hard knee, so it limits rather than compresses
ratio20Effectively a brick wall
attack0.003 sFast enough to catch note transients
release0.25 sRecovers without pumping

Anything below the threshold passes through untouched, so quiet material is unaffected.

If you need different behaviour, the underlying DynamicsCompressorNode is exposed:

const limiter = soundHub.getMasterLimiterNode();

if (limiter) {
limiter.threshold.value = -6; // start limiting earlier
limiter.release.value = 0.4; // let it recover more slowly

console.log(limiter.reduction); // current gain reduction in dB
}

Reading reduction is the easiest way to check whether the limiter is actually doing anything: it stays at 0 while you are under the threshold and goes negative as peaks are held back.

Audio you generate yourself

The limiter only sees what passes through the master chain. Sound you create with an oscillator, a MediaElementSource or an AudioWorklet and connect straight to context.destination bypasses it completely, along with master volume, mute and panning.

Connect it to getMasterInput() instead:

const context = soundHub.getContext();

const osc = context.createOscillator();
const gain = context.createGain();

osc.connect(gain);
gain.connect(soundHub.getMasterInput()); // not context.destination

osc.start();

This matters more than it sounds. Synthesized sources are usually much hotter than recorded samples: a sawtooth at full amplitude peaks at 0 dBFS while a typical sample peaks around -20 dBFS, so an untamed oscillator can be ten times louder than everything else and clip on its own.

When to use it

SituationRecommendation
A single background trackNot needed
Playing a sound the user triggers repeatedlyWorth enabling
A playable instrument, several notes at onceEnable
A game scene with many overlapping effectsEnable
You already mix at low per-sound volumesOptional, it will rarely engage

A limiter is a safety net, not a substitute for a sensible mix. If you know you will play ten sounds at once, lowering the individual volumes still gives you the cleanest result; the limiter is there to catch what you did not plan for.