AI-generated Computed, not drawn Audio half deferred

This explorer was generated by Claude (Anthropic) for the DSP 101 course materials. Every pixel column of every spectrogram on this page is a real transform of real samples. The page contains an iterative radix‑2 FFT with an explicit bit‑reversal permutation; the short‑time Fourier transform frames the signal at the hop you choose, multiplies each frame by the window you choose, and transforms it. A spectrogram that was painted to look plausible instead of computed would be a defect, not a simplification, so nothing here is painted.

Computed live (kind a) — nearly everything: Δt, Δf and their product from N and fs; the frame count, hop, bin count and FFT count of the work actually done; each window's measured half‑power main‑lobe width and measured peak side‑lobe level, obtained by transforming the window itself zero‑padded to 8192 points; the two‑tone resolvability verdict, which is found by looking for two separated local maxima with a real dip between them in this page's own computed spectrum rather than by comparing the spacing to a formula; the click's measured smear in frames and in milliseconds; and the chirp's measured peak bin per frame.

Published figures (kind b) — exactly one column of one table. The textbook peak side‑lobe levels sit beside the measured ones in the window table so you can compare them; they are labelled “published” there. Note the repository's own lessons disagree with each other about Blackman by 1 dB, so the measured number is the one this page treats as primary. Illustrative (kind c): the default signal parameters, the default sample rate and the noise level. Nothing illustrative is plotted as data.

Window definitions and the published side‑lobe figures: F. J. Harris, “On the use of windows for harmonic analysis with the discrete Fourier transform,” Proc. IEEE, vol. 66, no. 1, pp. 51–83, Jan. 1978. STFT and time‑frequency resolution: A. V. Oppenheim and R. W. Schafer, Discrete-Time Signal Processing, 3rd ed., ch. 10. Colour map: viridis (S. van der Walt and N. Smith, matplotlib, 2015), interpolated here in linear‑light sRGB.

The audio half of the syllabus lab is deferred, not dropped. courses/dsp101/SYLLABUS.md asks the lab to “record or load audio” and to show “speech and music spectrograms”. This page has no microphone capture and no playback: audio work is parked repository‑wide (TODO.md §9), so the signals here are synthesised test cases chosen because each one wants a different window. You are looking at the STFT half of the lab.

Spectrogram / STFT explorer — the time–frequency trade-off

Course demo — linked from the lesson deck in both languages; the page itself is English‑only for now. Built for DSP-101 Module 9 (SYLLABUS.md:377, “Lab: Generate Spectrograms”). One idea, two knobs: a window of N samples gives you Δt = N/fs of time resolution and Δf ≈ fs/N of frequency resolution, and their product is fixed. Spend N on one and you have spent it. The three spectrograms side by side are the whole argument; the rest of the page exists so you can read them. Seeded, so the same settings always draw the same picture.

One column of the spectrogram, step by step

Each thumbnail is live and shows the frame under the cursor, at the current settings. A spectrogram is a stack of DFTs, not a magic image — this row is the proof, and panel D below is the last thumbnail at full size.

1 · slice
Take N samples

Frame m starts at sample 0. Its length is the window length N.

2 · window
Multiply by w[n]

Tapering the ends is what stops the frame's hard edges being read as signal.

3 · pad + FFT
Transform NFFT points

Zero-padding to NFFT adds bins between the ones you had. It does not add resolution.

4 · dB
20·log10|Xm[k]|

Magnitude in dB, referenced to the loudest bin in the whole spectrogram, then clipped at the floor you set.

5 · colour
One column of pixels

dB → viridis, low at the bottom. Stack one of these per frame and you have the spectrogram.

Knobs

Signal

Different signals want different windows. That is the point of having five of them: there is no window length that is right for all of these, and one of them is deliberately impossible.

Seeded Gaussian noise — illustrative default. “New noise” redraws it from the next seed; the same seed always gives the same noise.

Record

The sample rate sets the top of the frequency axis (fs/2, the Nyquist frequency) and it scales Δt and Δf together. Both defaults are illustrative.

Total samples L, and therefore how many frames there are to draw.

dB relative to the loudest bin in the whole spectrogram. Everything at or below the floor is drawn in the map's darkest colour, so a low floor shows the noise and a high floor hides it. Display only — it changes no computation.

Window — the trade-off knob

This is the knob the page is about. Every sample you add to N buys frequency resolution and spends time resolution, at a fixed exchange rate.

Δt = N/fs —time resolution
Δf = fs/N —bin spacing of the un-padded DFT
Δt · Δf —the constant you cannot beat

Framing — overlap and hop

Overlap decides how often you look, not how well you see. Too little and an event can fall between frames; past about 75 % you are paying for frames that mostly repeat what the last one said.

The cursor is operable three ways: this slider, that number box, or the spectrogram itself — click it or focus it and use the arrow keys, Page Up/Down, Home and End.

Work done for this picture

A live spectrogram at 87.5 % overlap is many hundreds of FFTs, and there are four spectrograms on this page. So the frame count is capped, and the cap is stated here rather than hidden: a silent cap reads as “we covered everything”. While you drag a slider the caps are lower (coarse); on release the page recomputes (refined).

samples L—
hop—
frames wanted— floor((L − N)/hop) + 1
frames drawn —
bins per frame— NFFT/2 + 1, DC to Nyquist
FFTs this repaint— all four spectrograms plus the four window measurements
cells drawn—
quality—

The same signal, three window lengths — this is the whole point

Short, medium, long — pick your poison

Identical samples, identical window shape, identical overlap. Only N differs. Read left to right: sharp vertical edges means good time resolution; sharp horizontal lines means good frequency resolution. No panel has both, and that is not an implementation limit — it is Δt·Δf = 1.

N = 64

—

—

N = 256

—

—

N = 1024

—

—

—

a heavy border marks the N you have selected above every number in the three captions is measured from that panel's own transform

The spectrogram at your settings

Time → across, frequency ↑ up, magnitude = colour

Click or drag to move the frame cursor; or focus this plot and use the arrow keys. The column under the cursor is drawn full size in panel D.

—

the frame cursor and the window outline are drawn as a white core over a black casing, so they clear 4.60:1 against every colour the map can produce — no single ink can axes and labels are structural ink, never a map colour

A · The signal, and what the cursor's frame saw

The shaded span is the N samples of frame m. The curve inside it is the window shape w[n], drawn to scale — those are the weights that frame's samples were multiplied by.

—

signal x[n] window w[n] over frame m the click / burst edges

D · One column, full size — a stack of DFTs

The magnitude spectrum of frame m alone. This is the column the spectrogram drew as colour, so if you can read this you can read the image.

—

|Xm[k]| in dB the dB floor of the colour map the peak, with its numeric dB and Hz readout

What the page measured, rather than asserted

E · Resolvability, smear and sweep — all measured

Each verdict below is read off this page's own computed output. None of them compares your settings to a rule of thumb and prints a sentence.

two tones — measured dip between the two peaks
click smear — frames more than 10 dB above the median frame
peak of frame m— bin → Hz, and its level
sweep monotone? — does the peak bin really climb, frame after frame

—

The four windows, measured here and published

The two right-hand columns are measured by transforming each window itself, zero-padded to 8192 points, in your browser, right now. The last column is quoted from Harris (1978) for comparison — it is the only published number on this page.

—
Window Half-power width
bins
Δf effective
Hz
Peak side lobe
measured, dB
Peak side lobe
published, dB

The measured half-power width is what turns the ideal Δf = fs/N into the resolution you actually get: a taper widens the main lobe, which is the price of its lower side lobes. So the window shape moves the constant in Δt·Δf, and never removes it.

The maths this page runs

What each view is for

Chain

Slice, window, transform

Five live thumbnails of one frame, so “a spectrogram is a stack of DFTs” is something you can watch instead of something you are told.

All five recompute from the samples under the cursor.

in: x[n], m → out: one pixel column

C

Three windows at once

The comparison one slider cannot make. Short: crisp edges, fat frequency bands. Long: thin frequency lines, edges dragged out in time.

Same samples, same shape, same overlap, three N.

in: x[n] → out: 3 spectrograms

B

The spectrogram, your settings

Full size, with the movable frame cursor and a numeric colour key.

Keyboard-operable: it is a real slider.

in: x[n], N, hop, NFFT → out: image + cursor

A

Where the column came from

The frame's span and the window's actual weights, drawn on the signal.

Move the cursor and watch the span slide by exactly one hop.

in: m → out: span + w[n]

D

One frame, full size

The spectrum the colour column encodes, with the peak's dB and Hz printed.

A heat map cannot be read by colour alone; this is the numeric route in.

in: frame m → out: |Xm[k]| dB

E

Measured verdicts

Are the two tones actually two peaks with a dip between them? How many frames does one click light up? Does the chirp's peak bin really climb?

Read off the computed output, never from a formula.

in: the STFT → out: words plus numbers

Why viridis and not a rainbow. The colour carries the data here, so the map is part of the maths. Viridis is monotone in lightness: equal steps in dB are equal steps in apparent brightness, it survives being printed in grey, and it stays readable for the common colour-vision deficiencies. A rainbow map does none of that — it is not perceptually ordered, so its bright yellow and cyan bands read as contour lines the data does not contain, and its dark-red-to-dark-blue ends compress real differences into mud. This page interpolates viridis in linear-light sRGB between the ten canonical stops, which makes luminance piecewise linear in the value and therefore monotone by construction.
What is missing, said out loud.