↑ ↓ to move · enter to open

S02 · Sound · Frequencies, FFT, epicycles

the fourier transform

A chord is several pure tones played at once, and your ear hears them separately. The Fourier transform does the same thing with arithmetic. It takes any wave and finds the recipe: which steady frequencies, at which strengths, add up to it. Below you wrap a signal around a circle, draw a wave and hear its recipe, and watch spinning circles trace a picture.

LAB 1

winding a signal around a circle

A signal is a number that changes over time, like the air pressure at your ear. A frequency is how many times per second something repeats, measured in hertz (Hz). Here the signal is built from up to three pure waves. Now wrap that signal around a circle: as time runs, a pen turns around the center at the test frequency, and its distance from the center is the signal's value. Most test frequencies smear the drawing evenly around the circle, so its balance point (the center of mass) sits near the middle. When the test frequency matches one of the waves, the loud parts always land on the same side, and the balance point jumps out.

winding
2.00 Hz

How to read this: Top: the signal over 4 seconds. Middle: the same signal wrapped around a circle, turning at the test frequency. Bottom: how far the gold balance point sits from the center at every test frequency. Each peak is a wave hiding in the signal.

  • the signal
  • amber dot and line: the pen at this moment (the same instant on strip and circle)
  • faint amber loop: the signal wound around the circle
  • center of mass (balance point)
  • balance-point distance vs. test frequency
  • the current test frequency
  • colored ticks on the bottom axis: where Wave 1, 2, 3 really are

Try this: Press Sweep and watch the gold dot fly outward each time the dashed line crosses a colored tick. Then switch to Centered: the +1 lift is a wave of frequency 0, so its peak at 0 Hz vanishes.

—
Test frequency
—
Center of mass distance
—
Center of mass angle
—
Matches

Now

The transform

c(f) = (1/T) ∫0T g(t) · e−2πi f t dt ≈ (1/N) Σn g(tn) e−2πi f tn

e−2πi f t is a point on a circle of radius 1 that turns f times per second, clockwise. Multiplying by g(t) stretches it to the signal's value. Averaging all those points gives the center of mass c(f), a complex number: its distance says how much of frequency f is in the signal, and its angle gives the timing (the phase).

A wave of strength a at the test frequency moves the center out to a/2. The other half of its strength shows up at −f, winding the other way. The lift of +1 is a constant, which is frequency 0, so it shows up as a peak at 0 Hz.

CodePython

LAB 2

draw a wave, see its recipe

Draw one cycle of any wave in the top box (drag with a mouse or finger), or pick a preset. The page stores it as 256 numbers called samples. It then finds the strength of each harmonic: harmonic 1 repeats once per cycle, harmonic 2 twice, harmonic 3 three times, and so on. That list of strengths is the spectrum. Keep only the strongest few ingredients and rebuild the wave from them in gold. Then play both and listen to how few you need.

draw here
5 of 129
Pitch

How to read this: Each bar below the wave is one ingredient: bar 1 repeats once per cycle, bar 2 twice, and so on. Taller = louder. Gold bars are the ones kept to build the gold wave above.

  • your wave
  • rebuilt from the top k
  • kept harmonics
  • dropped harmonics

Try this: With Square selected, drag "Keep top k" from 1 up to 10 and watch the gold wave square up. Then press "Play top k".

Sound plays only when you press a play button, quietly, for up to 6 seconds.
—
Energy kept
—
RMS error of rebuild
—
Energy in both views (should match)
—
Wavelength in air at this pitch

The recipetop 6

Discrete Fourier transform

Xk = Σn=0N−1 xn e−2πi kn/N xn = (1/N) Σk Xk e+2πi kn/N
FFT: Xk = Ek + e−2πi k/N Ok Xk+N/2 = Ek − e−2πi k/N Ok
Parseval: Σ |xn|² = (1/N) Σ |Xk|²

The first line is Lab 1 with a finite list: wind the 256 samples around the circle k times and add them up. Doing that for every k takes N² = 65,536 multiplications. The fast Fourier transform (FFT) splits the samples into even and odd positions, transforms each half, and combines them with one twist each. Repeating the split gives N·log₂N = 2,048 multiplications. This recursion is the radix-2 FFT published by Cooley and Tukey in 1965. Compare the recursions in 005 · Recursion.

Parseval's theorem says the energy is the same in both views. That's what "energy kept" measures: the share of the total that the kept harmonics carry.

Why a square wave sounds buzzy

A square wave holds only odd harmonics, with strengths 1, 1/3, 1/5, 1/7 of the first. Those upper harmonics are what make it sound bright and buzzy next to a pure sine. Rebuilt from a few of them, the corners ring and overshoot by about 9% of the jump. This is the Gibbs phenomenon, and more harmonics squeeze the ripple closer to the corner without removing it. More on harmonics and timbre in S00 · Waves & harmonics.

Web Audio ignores the 0 Hz part (a constant offset), which you couldn't hear anyway. Sound travels at about at , so each pitch has a wavelength in air of speed ÷ frequency.

CodePython

LAB 3

circles drawing pictures

A closed drawing can be a signal too. Walk around the outline and record 256 points. Treat each point as one complex number, x + iy, so a single number holds both coordinates. The Fourier transform of that list is a set of circles, each spinning at a whole number of turns per lap, some clockwise and some counterclockwise. Stack them tip to tail and the last tip retraces the drawing. Pick a shape or draw your own closed loop in the box.

draw a closed loop
20 of 256

How to read this: Each amber circle spins at its own steady speed and rides on the tip of the one before. The gold dot at the end of the chain draws the shape; the green dots are the points it is trying to hit.

  • one Fourier ingredient each (bigger = stronger)
  • the pen tip
  • bright gold: drawn this lap
  • faint gold: the full path it will draw
  • your original points

Try this: Pick Star, drag Circles down to 3, then slowly back up and watch the star's points appear.

—
Circles used
—
Energy kept
—
Worst miss (share of size)
—
Biggest circles (turns per lap)

Each circle is one coefficient

z(t) = Σk ck e2πi k t ck = Xk / N 0 ≤ t < 1

Coefficient ck is a circle of radius |ck| that turns k times per lap and starts at angle arg ck. Negative k turns clockwise. c0 doesn't turn at all: it is the center of the drawing.

The page sorts circles by size and keeps the biggest. With all 256 the tip passes exactly through every recorded point. A few dozen already give a recognizable picture, because most of the shape lives in slow, large circles. Sharp corners need many small fast ones.

Why this matters

Keeping the big coefficients and dropping the small ones is the core idea of lossy compression. JPEG applies a close relative, the discrete cosine transform, to 8×8 blocks of pixels. MP3 applies another, the modified discrete cosine transform, to short slices of sound, and spends the fewest bits on what the ear can't notice. See S04 · How MP3s shrink audio.

CodePython