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, mapping 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.