A sound FX could not control dynamics. A Compressor squeezes the
loudness together, and a Limiter keeps every peak below a line. Both
work on a voice and on a bus, where they tame everything at once.
- Compressor: DynamicsCompressorNode with Threshold, Ratio, Knee,
Attack and Release, then Makeup and Auto-gain from 0 to 1. After the
node the sound gets (1 - w) * makeup + w * A dB. A is what the curve
takes off at 0 dBFS.
- The node adds 0.6 of A by itself, as the spec says. That gain is
taken back out, so 0 really means no makeup.
- The knee shape is left to the browser by the spec. dynamics.ts ports
Chromium's curve. It gives the gain Chrome was measured to add at
four settings to three places.
- Limiter: a class on the FX worklet with Threshold, Ceiling, Release
and Auto-gain. It looks 5 ms ahead: the smallest gain of the window
ahead, averaged over the window, then a release. No sample passes the
lower of threshold and ceiling. Auto-gain raises it toward the
ceiling.
- Deviation from the plan in the issue: the Limiter has a Threshold as
well. Without it Auto-gain has nothing to measure against.
- Latency is made up on voices now too. A voice starts as much earlier
as its stages are late (Compressor 6 ms, Limiter 5 ms). The other
way of a Mix and the other layers of a note are held back to the
latest, and a bus counts it into its latency.
- A voice with a Limiter counts as ringing, so the worklet is stopped
only after what it still holds is out.
Tests:
- Unit dynamics (new) 8, soundfx 49 (3 new), sound-library 100 (4 new),
green.
- Counter-checks, each turns tests red: no look-ahead in the Limiter
(3), no taking back of the node's gain (1), a voice not started
earlier (1), no stage latency on a bus (1), no hold-back in a Mix (1).
- e2e 34 (melektaus-atx): ALL PASSED, 78 checks (1 new). Chrome
offline: Compressor 288 samples late, Limiter 240. Full scale through
-12 dB 4:1 hard knee: +0.19 dB with full auto-gain, -8.81 dB without.
A sine at 2 through the Limiter at -6 dB peaks at -6.00 dB, with
auto-gain 1 at -1.00 dB.
- The gate runs once on the last commit of this series.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>