Fourier & Z transform review
Before we can describe what a digital filter does, we need two transforms. The Fourier transform decomposes a signal into frequency components. The Z transform generalizes this to discrete-time systems — it maps filter coefficients directly to frequency-domain behavior, connecting the numbers you write in C to the response you hear on the RadioSonic board.
This lesson focuses on building intuition, not re-deriving the mathematics. By the end you should be able to look at a pole-zero plot and make a reasonable prediction about a filter's frequency response before running a single line of code.
Demo code — FFT of a two-tone test signal
import numpy as np import matplotlib.pyplot as plt Fs = 44100 # RadioSonic sample rate (Hz) N = 4096 # FFT length t = np.arange(N) / Fs x = np.sin(2*np.pi*500*t) + 0.5*np.sin(2*np.pi*2000*t) X = np.fft.rfft(x, N) f = np.fft.rfftfreq(N, 1/Fs) mag = 20*np.log10(np.abs(X)/N + 1e-12) plt.plot(f, mag) plt.xlabel("Frequency (Hz)"); plt.ylabel("Magnitude (dBFS)") plt.show()
The Z transform and what poles & zeros mean
For a discrete-time filter, the Z transform produces a rational function H(z). Numerator roots are zeros — frequencies the filter nulls. Denominator roots are poles — frequencies it resonates at. For a stable IIR filter, all poles must lie strictly inside the unit circle. This is the geometric picture you will use in Section 4 when we implement biquad sections on the board.
Lab 2 — Convolution & correlation on the RadioSonic platform
Use the Jupyter Notebook to compute convolution and correlation on signals captured live from your board. Observe impulse and frequency response from real measured audio — not simulated signals.