Audio UI
Lets a bass be heard on small speakers. A phone or a laptop cannot play the lowest notes, but the ear hears a note from its harmonics alone. The device takes the lows under a frequency, shapes them into their harmonics, which those speakers can play, and adds them to the sound. It is a device: a state, a panel, an engine and tools, each its own file.
Installation
pnpm dlx shadcn@latest add @audio-ui/bass-enhancer
It installs the device's state, its engine and its panel to components/audio-ui/devices/bass-enhancer/. The demo above, which wires them to a loop, is @audio-ui/block-bass-enhancer.
Controls
Controls · 5
Panel
The panel draws the sub it takes, dashed, and the band its harmonics go to, two and a half times higher. bassEnhancerBands(state) is what it draws.
import { BassEnhancerPanel } from "@/components/audio-ui/devices/bass-enhancer/panel";
import { bassEnhancerDevice } from "@/components/audio-ui/devices/bass-enhancer/device";
const [state, setState] = useState(() => bassEnhancerDevice.defaults());
<BassEnhancerPanel onValueChange={setState} value={state} />;Engine
Create it, connect it and update it as for any device: see The engine.
The bass enhancer runs on the audio thread: the bass enhancer of @audio/effect-subbass in an AudioWorklet loaded from a blob (BASS_ENHANCER_WORKLET is its source), 128 frames at a time: a low-pass takes the sub, a waveshaper makes its even and odd harmonics, and a band-pass keeps them between two and five times the frequency, where small speakers play. A worklet cannot import, so the device carries the kernel as published (BASS_ENHANCER_KERNELS, in its kernels.ts). Until it is ready, and in a context with no worklets, the sound passes clean: ready resolves once it is in the graph.