Composables & protocol
The data pipelines are also available standalone, if you want to drive your own rendering
or combine them with mode="external".
useLocalAudio(options?)
Captures mic or display audio and runs the WASM FFT.
const {
fftData, // Ref<Uint8Array> — magnitudes 0–255
isActive, sourceType, devices, activeDeviceId,
getDevices, // () => Promise<AudioDevice[]>
start, // (deviceId?) => Promise<void> — microphone
startDisplay, // () => Promise<void> — tab/system audio
stop
} = useLocalAudio({ fftSize: 2048, bins: 80, startFreq: 100, endFreq: 18000 })
useWebSocketFft(options?)
Connects to a WebSocket that streams raw PCM and computes the FFT in-browser via WASM
(distinct from the component's websocket mode, which expects pre-computed FFT). Feed
its fftData into the component with mode="external".
const {
fftData, fftDataLeft, fftDataRight, isConnected,
connect, // (url) => void
disconnect,
processSamples // (Float32Array) => void — feed PCM manually
} = useWebSocketFft({ fftSize: 2048, bins: 80, overlap: 0.5, autoReconnect: true })
The raw WASM FFT processor is also exported from vue-fft-visualizer/wasm for direct use.
WebSocket protocol
mode="websocket" expects a server that sends pre-computed FFT frames.
1. Config message (JSON), once on connect:
{ "type": "config", "mode": "fft", "bins": 80, "fps": 120 }
2. Binary FFT frames, continuously:
- One
uint8(0–255) per frequency bin —binsbytes per frame - 0 = silence, 255 = maximum amplitude
- Typically 100 Hz – 18 kHz, exponentially spaced
For best results the server should capture at 48 kHz+, apply a Hann/Hamming window, compute a 1024–2048-point FFT, map to exponentially-spaced bands, apply A-weighting, convert to dB, normalize to 0–255, and stream at 60–120 fps.
Reference servers
The repository's backend-examples/ has servers that capture system audio, compute FFT, and
stream it: Python (pyalsaaudio + numpy, incl. a Raspberry Pi variant), Node.js
(node-audiorecorder + fft.js), and Rust (cpal + rustfft).