Core

Audio engines

Standalone FFT pipelines — local capture, client-side FFT of a PCM stream, PCM decoding, and the raw WASM processor.

The core ships the audio→FFT pipelines as standalone factories, so you can produce FFT magnitudes without the renderer — drive your own visuals, or feed the result into FFTVisualizer with mode: 'external'. These are exactly what the Vue composables wrap.

All engines emit Uint8Array magnitudes (0–255 per bin) and share four options: fftSize (default 2048), bins (default 80), startFreq (default 100 Hz), and endFreq (default 18000 Hz).

createLocalAudio(options?)

Captures mic or system/tab audio and computes the FFT in-browser via the Rust WASM processor.

import { createLocalAudio } from 'fft-visualizer-core'

const audio = createLocalAudio({
  bins: 80,
  onData: (data) => {
    // data: Uint8Array — fresh magnitudes each animation frame
  },
  onStateChange: () => {
    // isActive / devices / activeDeviceId / sourceType changed
  }
})

await audio.getDevices()   // enumerate inputs (prompts for mic permission)
await audio.start()        // microphone (optional deviceId argument)
await audio.startDisplay() // tab/system audio via screen sharing
audio.stop()

The returned LocalAudioEngine exposes read-only fftData, isActive, sourceType, devices, and activeDeviceId, plus the getDevices / start / startDisplay / stop methods above.

createWebSocketFft(options?)

Connects to a WebSocket that streams raw PCM and computes the FFT client-side via WASM — distinct from FFTVisualizer's websocket mode, which expects pre-computed FFT (see WebSocket protocol). It produces mono, left, and right spectra.

import { createWebSocketFft } from 'fft-visualizer-core'

const engine = createWebSocketFft({
  bins: 80,
  overlap: 0.5,        // 0–0.75; more overlap = lower latency, ~2× FFT compute
  autoReconnect: true,
  onData: (mono, left, right) => { /* Uint8Array each */ }
})

engine.connect('wss://your-server/pcm')
engine.processSamples(float32Pcm) // or feed PCM manually
engine.disconnect()
engine.free() // tear down and free WASM processors

Read-only getters: fftData, fftDataLeft, fftDataRight, isConnected.

pcmToChannels(buffer, bitDepth, channels)

Decodes an interleaved integer-PCM ArrayBuffer (16/24/32-bit) into normalized Float32 channels — { mono, left, right }, each in [-1, 1). Mono input is duplicated to both channels; only the first two channels of multichannel input are used. This is the decoder createWebSocketFft uses internally.

Raw WASM processor

For full control, the Rust FftProcessor is exported from a dedicated subpath. It's kept out of the main entry so importing the visualizer never eagerly loads ~289 kB of WASM.

import { FftProcessor } from 'fft-visualizer-core/wasm'

const processor = new FftProcessor(fftSize, bins, startFreq, endFreq, sampleRate)
const magnitudes = processor.process(float32TimeDomainSamples) // Uint8Array
processor.free()
Copyright © 2026