Task 4 of 5

Measure the Trade

"Use a Hann window" is folklore until you can say what it costs. Two numbers settle it, and both are in the picture above.

Main-lobe width is how many bins a single pure tone occupies — the frequency resolution you have left. Peak side-lobe level is how far down, in dB, the worst ripple outside that lobe sits — the dynamic range you have bought. The rectangular window (which is all "no window" ever meant: multiply by 1 and stop dead at the edges) wins the first and loses the second, badly. Every other window trades one for the other, and choosing between them is the whole skill.

To see either you have to look between the bins, because a windowed on-bin tone lands on integer bins where these curves are exactly zero. The standard trick is zero padding: run a 1,024-point transform over a 256-sample signal, so 768 of the terms are zero. Nothing is added and nothing is lost, but the spectrum is now sampled four times per bin. Be clear about what that buys — interpolation, never resolution. Zero padding draws the same curve with more dots; only a longer window makes the curve narrower.

the whole trade in one picture — nobody gets both
Goal: write the Blackman window, then tabulate main-lobe width and peak side-lobe level for rectangular, Hann and Blackman on the same on-bin tone.

Requirements

Hint 1 — the Blackman kernel

Three cosine terms, and the third runs at double the frequency — so name the angle once and the whole window is one line:

const i = this.thread.x;
const a = 2 * Math.PI * i / this.constants.n;
const w = 0.42 - 0.5 * Math.cos(a) + 0.08 * Math.cos(2 * a);
return signal[i] * w;

One gpu.js trap while you are in here: do not name a kernel local after one of your own constants. const n = this.constants.n; transpiles to const constants_n = constants_n; and the kernel dies with "cannot access before initialization".

Hint 2 — walking out to the first null

A main lobe falls monotonically to its first zero, and only then do the side lobes start climbing again. So keep stepping while the next sample is smaller than this one:

let i = peakAt;
while (mag[i + 1] < mag[i]) i++;
const bins = 2 * (i - peakAt) / 4;   // 4 grid points per bin
Hint 3 — what the table should say

Widths of 2, 4 and 6 bins, and side lobes at roughly -13, -32 and -58 dB. Read it as a menu: three extra bins of width buy 45 dB of dynamic range. Hamming, not asked for here, sits between Hann and Blackman at 4 bins and about -41 dB.

Same idea elsewhere

Those two numbers are the datasheet entry for every window in every DSP library — Harris's 1978 survey tabulates a few dozen of them and is still the paper people cite. Choosing one is a real engineering decision: a spectrum analyser hunting a -60 dB spur beside a strong carrier needs Blackman's side lobes and can afford the width, while a pitch tracker separating two close partials wants Hann, or no window at all.

All tasks in Windowing & Spectral Leakage

  1. A Tone the Window Does Not Fit
  2. What the Transform Actually Sees
  3. Taper the Edges
  4. Measure the Trade
  5. Give the Amplitude Back

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.