This is a real Web Audio synthesizer, not a canned sample. An OscillatorNode generates the chosen waveform at the note frequency, feeding a BiquadFilterNode lowpass with a true cutoff/resonance response:
H(f) governed by f_c (cutoff) and Q (resonance) — a real 2-pole biquad
y[n] = x[n] + feedback·y[n−D] (feedback delay line, D = delayTime·sampleRate)
IR[i] = noise(i)·(1 − i/N)^decay (synthetic decaying-noise impulse response, convolved for reverb)
The filtered signal splits three ways: dry, through a DelayNode with a feedback GainNode looped back into it (a real feedback delay line — the classic echo equation above), and through a ConvolverNode loaded with an algorithmically generated impulse response (exponentially decaying white noise — a Schroeder-style synthetic reverb, not a sample). All three sum into the master gain, then into an AnalyserNode that drives everything you see.
The 3D scene reads the analyser's real frequency-domain and time-domain data every frame — nothing here is pre-baked animation:
- Radial spectrum ring — 64 bars arranged in a circle, each bar's height set directly from
getByteFrequencyData() for that frequency bin.
- Echo-depth waveform — the live time-domain waveform (
getByteTimeDomainData()) is drawn as a ring at the front, then repeated as fainter, shrinking rings receding into the +Z depth axis — one ring per audible echo tap. Their spacing along Z is set by the real delay time slider, and how many rings are visible (and how quickly they fade) is set by the real feedback amount, exactly mirroring what you'd hear.
- Reverb mix tints the scene's ambient haze and softens the ring edges — more mix, more diffusion, matching how the convolved signal blurs the dry attack.
Drag to orbit the camera, scroll to zoom.