How does a chromagram decide which frequencies count as a C, a C#, or an A?
This heatmap shows the answer: twelve rows of frequency filters, one per
pitch class, with Gaussian bumps that repeat every octave and an
octave-dominance envelope fading the extremes. Technically:
filters.chroma({sr:22050, n_fft:2048}) is rendered as a
12 × 1025 heatmap (each row is a pitch class, C at the bottom, base_c grid;
x-axis is FFT bin frequency 0 → 11025 Hz). Proofs: the pitch class with the
most weight at the FFT bin nearest 440 Hz must be 9 (A), and every column's
L2 norm must be ≤ 1 + 1e-6 (per-bin norm=2 column normalization, then
dominance weighting only ever shrinks it).