Spectrum Module — Real-Time Frequency Analyser

A shared visualisation module that renders a live frequency spectrum using getFloatFrequencyData. Used by all synths with live audio (Neuro, Juno, BIA) and available as an inactive canvas placeholder on offline-only synths (kick, snare, hi-hat).

Exports

Export Signature Purpose
createSpectrumAnalyser (ac) → AnalyserNode Creates a standardised AnalyserNode (FFT 2048, smoothing 0.5, –100 to –20 dB)
readThemeColor (varName) → {r,g,b} Reads a CSS custom property and parses it as an RGB object
startSpectrum (analyser, canvas) → stop() Starts a RAF loop drawing spectrum bars. Returns a stop function

Drawing

The startSpectrum function renders frequency-domain data as 1 px bars with 1 px gaps, mapped logarithmically from 20 Hz to sr/2:

bars:   1 px wide, 1 px gap
colors: green (–bs-success) → amber (–bs-warning) → red (–bs-danger)
peak hold: dots that decay at 0.02/frame
auto-scale: normalises to the current peak across all bars

Theme Support

Colours read CSS custom properties (--bs-success, --bs-warning, --bs-danger) so they adapt to dark/light theme automatically.

Integration

Each live-audio init file imports and wires the spectrum:

import { createSpectrumAnalyser, startSpectrum } from './modules/spectrum.js';
var analyser = createSpectrumAnalyser(ac);
var stop = startSpectrum(analyser, document.getElementById('spectrum'));

The analyser is inserted into the master output chain (masterGain → analyser → destination or a stereo-sum tap). The #spectrum canvas is positioned absolutely at the bottom of .synth-main with pointer-events: none.

Files

File Purpose
modules/spectrum.js Module definition (~116 lines)
synth_neuro.html Has #spectrum canvas, position: relative containers
synth_juno.html Same layout
synth_bia_clone.html Same layout (replaced former VU meter)
synth_kick.html, synth_snare.html, synth_hihat.html Canvas present but inactive (offline-only)