The AnalyserNode runs a Short-Time Fourier Transform: it chops the signal into overlapping windows and takes an FFT of each. One FFT gives you the energy at every frequency bin at one instant. Stack those spectra left-to-right in time and you get a spectrogram. Each vertical strip you see is one FFT frame turned into color.
bin spacing: delta_f = fs / N (fs = sample rate, N = FFT size)With N = 4096 at 48 kHz, delta_f ~= 11.7 Hz. That is the same
absolute spacing everywhere -- great up high, but crude down low where whole semitones
are only a few Hz apart.
Pitch is logarithmic. Going up one octave always multiplies frequency by 2 (A2=110, A3=220, A4=440). So equal musical intervals must map to equal vertical distance only if the axis is logarithmic. This explorer maps screen height by:
freq(y) = f_min * (f_max / f_min) ^ y (y in 0..1, bottom..top)That is why C1, C2, C3 ... are drawn evenly spaced. A linear-Hz spectrogram crams all the music into the top and wastes the bottom.
A true Constant-Q Transform picks a bank of filters whose quality factor is constant across the whole range:
Q = f / delta_f = f_k / (f_(k+1) - f_k) = 1 / (2^(1/b) - 1)where b is the number of bins per octave. Constant Q means the window
length scales with frequency -- long windows (fine resolution) for low notes, short
windows for high notes:
Honest disclosure of what THIS tool does: it takes one fixed-size FFT and
resamples it onto a log axis (the fragment shader reads the linear FFT texture at
log-spaced positions). That gives the correct musical layout and the harmonic combs
line up perfectly, but the underlying time/frequency resolution is still the FFT's
constant delta_f, not a true CQT's constant Q. So low notes look
slightly smeared and highs slightly over-sharp compared with a real CQT. The "bins/octave"
readout reports the effective log-axis density, not a genuine filterbank.
A vibrating string or reed produces a fundamental f plus overtones at
2f, 3f, 4f, ... -- exact integer multiples. That is why the sawtooth shows a
full evenly-stacked comb (on this log axis the partials get closer together going up,
because 2f/f is an octave but 3f/2f is only a fifth), while the pure sine shows a single
line. The overlay draws those integer multiples so you can watch them land on the bright
bands.
Play 220 Hz and 330 Hz together (ratio 3:2). Their harmonic combs share partials: the 3rd harmonic of the low note (660) equals the 2nd of the high note (660); 1320 is shared too. Shared partials = consonance. When the ratio is slightly off, those shared partials sit a few Hz apart and their sum rises and falls at the difference frequency -- that slow throb is beating, and it is how the interval is tuned by ear.