Audio UI
Makes the whole sound brighter or darker with one knob. It tilts the tone around a pivot: turned up, the highs rise and the lows fall by as much, turned down the other way round. It is a device: a state, a panel, an engine and tools, each its own file.
Installation
pnpm dlx shadcn@latest add @audio-ui/tilt-eq
It installs the device's state, its engine and its panel to components/audio-ui/devices/tilt-eq/. The demo above, which wires them to a loop, is @audio-ui/block-tilt-eq.
Controls
Controls · 4
Panel
The panel draws the curve the tilt plays, with a line at the pivot. tiltEqCurve(state) is the curve it draws, from the shelves of @audio/biquad as the kernel makes them.
import { TiltEqPanel } from "@/components/audio-ui/devices/tilt-eq/panel";
import { tiltEqDevice } from "@/components/audio-ui/devices/tilt-eq/device";
const [state, setState] = useState(() => tiltEqDevice.defaults());
<TiltEqPanel onValueChange={setState} value={state} />;Engine
Create it, connect it and update it as for any device: see The engine.
The tilt is the kernel of @audio/eq-tilt in an AudioWorklet loaded from a blob (TILT_EQ_WORKLET is its source), 128 frames at a time: a low shelf and a high shelf of @audio/biquad at the pivot, with opposite gains and a Q of 0.5, gentler than the fixed slope of a BiquadFilterNode shelf, which is why it runs in a worklet. A worklet cannot import, so the device carries both modules as published (TILT_EQ_KERNELS, in its kernels.ts). A turn of a knob makes new coefficients and keeps the filters' state, so it does not click. Until the worklet is ready the sound passes clean, and engine.ready resolves to false in a context that cannot run worklets. tiltEqSettings(state) is what goes on it: the kernel's own gain raises the lows, so it takes the tilt the other way round.