Audio lab: hear the DSP

A real-time audio playground running in your browser via WebAssembly, compiled from the audio-dsp Rust crate β€” a hand-rolled FFT, a seven-type biquad filter bank, and YIN pitch detection. The browser only does I/O (mic, file decoding, playback); every sample of math runs in Rust, and the same crate compiles to native targets unchanged.

Input:
440 Hz
0.80

Press an input button to start (browser needs a gesture for audio).

Waveform β€” scrolling; gray = raw in, teal = filtered out

Spectrum β€” dB per frequency, log axis

Filter

0.7 0 dB

Gain only applies to peaking and shelf filters. Try: low-pass at 200 Hz on the tone, then sweep the frequency up and watch the spectrum's right side come alive.

Tuner β€” YIN pitch detection on the raw input

–

What's going on

Two views of one signal

The waveform is amplitude over time β€” the raw input in gray, the filtered output in teal, drawn on top. Bypass the filter and they sit exactly on top of each other; engage a low-pass and you watch the teal trace go smooth while the gray keeps buzzing. The spectrum is the filtered signal through a Fourier transform: energy per frequency, via a hand-rolled radix-2 FFT with a Hann window (which tames spectral leakage at the cost of slightly fattening each peak). Two domains, one cause.

Filters

Each filter is a biquad β€” a second-order IIR section with five coefficients computed from the RBJ Audio EQ Cookbook. Seven types cover every distinct thing a filter can do to a spectrum: remove above (low-pass), remove below (high-pass), keep a slice (band-pass), kill a slice (notch), boost/cut a slice (peaking), tilt the bass (low-shelf) or treble (high-shelf). Q controls how narrow the slice is.

Pitch, not peaks

The tuner doesn't pick the tallest FFT bin β€” on a guitar string that's usually a harmonic, and you'd be told you're an octave sharp. Instead it uses the YIN algorithm, which measures periodicity in the time domain: the lag at which the signal best predicts itself. Frequency then maps to the nearest note in 12-tone equal temperament (A4 = 440 Hz), with cents telling you which way to turn the peg.

The Rust core

fft.rs, filter.rs, pitch.rs, note.rs β€” no dependencies, sample rate always a parameter, unit-tested sample by sample. The page is a thin shell; the crate builds for native targets unchanged.

Further reading

← back to demos