Audio UI
Widens the dynamics. Downward, it turns down what falls under the threshold, softer than a gate: the room between the words, the bleed between the hits. Upward, it lifts what rises over it, giving back the peaks a limiter flattened. It plays the expander of audio.js. It is a device: a state, a panel, an engine and tools, each its own file.
Installation
pnpm dlx shadcn@latest add @audio-ui/expander
It installs the device's state, its engine and its panel to components/audio-ui/devices/expander/. The demo above, which wires them to a loop, is @audio-ui/block-expander.
Controls
Controls · 8
Panel
The panel draws the transfer curve against the straight line of a clean sound, with a handle on the threshold, through the package's own gain curves.
import { ExpanderPanel } from "@/components/audio-ui/devices/expander/panel";
import { expanderDevice } from "@/components/audio-ui/devices/expander/device";
const [state, setState] = useState(() => expanderDevice.defaults());
<ExpanderPanel 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 frameThe browser has no expander node. The engine plays the processor of @audio/dynamics-expander's manifest as published, in an AudioWorklet fed only while it plays: off, or until the worklet is ready, the sound goes round it. The mode, the threshold, the ratio, the knee and the range change as it plays. A new attack or release builds it again: at most every 50 ms, the new one first playing the last 100 ms of sound, then taking over in a 30 ms fade. engine.reduction reads what it takes off, so it reads 0 upward.
How close the curve is
The curve is the static curve, the level once it has settled. Measured on a steady tone at 100 Hz and at 1 kHz, the output's peaks sit up to 1.2 dB under it near and past the threshold, and on it elsewhere.
Upward has no ceiling but the range: at the defaults, a tone at -6 dB comes out at +17 dB. Follow it with a limiter, or keep the range low.