Audio UI
Draws its own transfer curve. Four points set the level out at -90, -60, -20 and 0 dB in, and the curve runs between them in straight lines. A point under the straight line of a clean sound turns the sound down at that level, one over it turns it up: one curve brings the loud parts down, lifts the quiet ones or closes on the noise. It plays the compander 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/compander
It installs the device's state, its engine and its panel to components/audio-ui/devices/compander/. The demo above, which wires them to a loop, is @audio-ui/block-compander.
Controls
Controls · 7
Panel
The panel draws the transfer curve against the straight line of a clean sound, with a handle on each point that moves up and down. The curve is measured from the package's own stream, run on a steady level until it settles.
import { CompanderPanel } from "@/components/audio-ui/devices/compander/panel";
import { companderDevice } from "@/components/audio-ui/devices/compander/device";
const [state, setState] = useState(() => companderDevice.defaults());
<CompanderPanel 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 compander node. The engine plays the processor of @audio/dynamics-compand's manifest as published, in an AudioWorklet fed only while it plays: off, or until the worklet is ready, the sound goes round it. Every one of its values 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.
Measured on a steady tone from -70 to -3 dB, the output sits within 0.2 dB of the curve.