Arrangement
Transport and mixer
EQ and filters
Modulation
Utility
Instruments
Audio UI
Brings loud parts down. Above the threshold, the level rises by one decibel for every ratio decibels in. With the sidechain on, it follows the level of another signal, so a kick can duck a pad. It is a device: a state, a panel, an engine and tools, each its own file.
Installation
pnpm dlx shadcn@latest add @audio-ui/compressor
It installs the device's state, its engine and its panel to components/audio-ui/devices/compressor/. The demo above, which wires them to a loop, is @audio-ui/block-compressor.
Controls
Controls · 10
engine.sidechain. See Sidechain.Panel
The panel draws the transfer curve the state plays: the threshold, the dashed unity line, and a dot that rides the curve at the level going in. Pass level, a live source in dB, to show the dot. Below the threshold the curve sits above unity by the make-up gain.
import { CompressorPanel } from "@/components/audio-ui/devices/compressor/panel";
import { compressorDevice } from "@/components/audio-ui/devices/compressor/device";
const [state, setState] = useState(() => compressorDevice.defaults());
<CompressorPanel onValueChange={setState} value={state} />;Engine
Create it, connect it and update it as for any device: see The engine.
engine.reduction; // dB being taken off, read per frameWhat goes on each node comes from compressorSettings(state). Two things the browser's compressor node does that the engine accounts for:
- It adds a make-up gain of its own that cannot be turned off. It grows with the threshold and the ratio (+10.8 dB at -24 dB and 4:1). With Auto make-up off, the engine takes it back out and applies Make-up. With it on, the node's is kept.
- It looks ahead by 6 ms. The dry path waits as long, so a parallel mix does not comb. This is the latency of the device.
With the sidechain on, the browser's node has no input for it, so the signal goes through a gain that a worklet drives. The worklet follows the peak of the sidechain, instant up and 10 ms down, and applies the same curve as the node, with a soft knee, a slope of 1/ratio over the threshold, and the attack and release on the reduction. The make-up of the node is added by hand. Measured in Chrome with a sine at -6 dB over a threshold of -18 dB at 4:1, it takes off 8.9 dB at 1 kHz and 8.5 dB at 60 Hz, where the curve says 9. With the sidechain on, engine.reduction reads the detector.
How close the curve is
The curve is the static curve of the node: the level once the gain has settled. A real detector follows a signal with an attack and a release, so what you hear sits a little above it. Measured in Chrome with a 440 Hz sine, it is about 0.5 dB at the defaults and up to 1.3 dB with a slow attack and a short release. Below the threshold it is exact.