Day 03 Day 3

Day 3

Day 3

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

Generate signals, compute the FFT, interpret the frequency domain, design FIR and IIR filters, and build a spectrogram. The core DSP workflow in MATLAB.

The Discrete Fourier Transform

The FFT (Fast Fourier Transform) converts a time-domain signal into the frequency domain. In MATLAB, fft(x) computes it. The key is correctly interpreting the output: you need to compute the frequency axis using the sample rate and the number of points.

matlab_-_fft_and_frequency_spectrum.txt
MATLAB — FFT AND FREQUENCY SPECTRUM
% Signal parameters
Fs  = 1000;           % sampling rate (Hz)
T   = 1/Fs;           % sample period
N   = 1024;           % number of samples
t   = (0:N-1) * T;    % time vector

% Composite signal: 50 Hz + 120 Hz + noise
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t) + 0.5*randn(1,N);

% Compute FFT
X    = fft(x);
X    = X(1:N/2+1);    % keep positive frequencies only
mag  = abs(X) / N;    % magnitude spectrum
mag(2:end-1) = 2*mag(2:end-1);  % double (single-sided)

% Frequency axis
f = Fs * (0:N/2) / N;

% Plot time domain and frequency domain
figure;
subplot(2,1,1);
plot(t(1:200), x(1:200));    % first 200 ms
title('Time Domain Signal'); xlabel('Time (s)'); ylabel('Amplitude');
grid on;

subplot(2,1,2);
plot(f, mag, 'b', 'LineWidth', 1.5);
title('Single-Sided Amplitude Spectrum');
xlabel('Frequency (Hz)'); ylabel('Amplitude');
xlim([0, 200]);
grid on;

% Mark the peaks
[pks, locs] = findpeaks(mag, f, 'MinPeakHeight', 0.3);
hold on;
scatter(locs, pks, 80, 'r', 'filled');
text(locs+2, pks, string(round(locs)) + " Hz", 'FontSize', 9);

Designing FIR and IIR Filters

matlab_-_digital_filters.txt
MATLAB — DIGITAL FILTERS
Fs = 1000;   % sampling rate

% ── FIR Low-pass filter (window method) ───────────────────────────
% fir1(order, cutoff_normalized)  — cutoff is fraction of Nyquist (Fs/2)
cutoff_hz = 100;
cutoff_norm = cutoff_hz / (Fs/2);   % normalize to [0,1]
b_fir = fir1(64, cutoff_norm, 'low');  % 64th order FIR

% Frequency response
[H, f] = freqz(b_fir, 1, 1024, Fs);
figure;
subplot(2,1,1);
plot(f, 20*log10(abs(H)));
title('FIR Low-pass Filter'); xlabel('Frequency (Hz)'); ylabel('Magnitude (dB)');
xlim([0, Fs/2]); ylim([-80, 5]); grid on;
xline(cutoff_hz, 'r--', '100 Hz cutoff');

% ── IIR Butterworth filter ─────────────────────────────────────────
% butter(order, cutoff_normalized)
[b_iir, a_iir] = butter(5, cutoff_norm, 'low');
[H2, ~] = freqz(b_iir, a_iir, 1024, Fs);
subplot(2,1,2);
plot(f, 20*log10(abs(H2)));
title('5th Order Butterworth Low-pass'); xlabel('Frequency (Hz)'); ylabel('Magnitude (dB)');
xlim([0, Fs/2]); ylim([-80, 5]); grid on;
xline(cutoff_hz, 'r--', '100 Hz cutoff');

% ── Apply filters to a noisy signal ───────────────────────────────
t_sig = 0:1/Fs:1-1/Fs;
clean = sin(2*pi*50*t_sig);                         % 50 Hz target
noise = 0.8*sin(2*pi*300*t_sig) + 0.3*randn(size(t_sig));  % HF noise
noisy = clean + noise;

filt_fir = filter(b_fir, 1,        noisy);   % FIR filter
filt_iir = filtfilt(b_iir, a_iir, noisy);    % IIR zero-phase

figure;
plot(t_sig(1:100), noisy(1:100), 'k:'); hold on;
plot(t_sig(1:100), filt_fir(1:100), 'b');
plot(t_sig(1:100), filt_iir(1:100), 'r');
legend({'Noisy', 'FIR filtered', 'IIR zero-phase'});
title('Filtering Comparison'); xlabel('Time (s)'); grid on;

Spectrograms

matlab_-_spectrogram.txt
MATLAB — SPECTROGRAM
Fs = 4000;
t  = 0:1/Fs:2;

% Chirp signal: frequency sweeps from 100 Hz to 1000 Hz
x = chirp(t, 100, 2, 1000);

% Add a burst of 600 Hz from t=0.8 to t=1.2
burst_mask = (t >= 0.8) & (t <= 1.2);
x = x + 0.5 * sin(2*pi*600*t) .* burst_mask;

% Spectrogram using STFT
% spectrogram(x, window, overlap, nfft, Fs)
window  = hann(256);
overlap = 200;
nfft    = 512;

figure;
spectrogram(x, window, overlap, nfft, Fs, 'yaxis');
colormap('jet');
title('Spectrogram: Chirp + Burst');
xlabel('Time (s)'); ylabel('Frequency (Hz)');
colorbar;
ylim([0, 1500]);

% Manual STFT if you need the data (not just the plot)
[S, F, T] = spectrogram(x, window, overlap, nfft, Fs);
power_dB = 10*log10(abs(S).^2 + eps);
fprintf('Spectrogram: %d freq bins × %d time frames\n', size(S,1), size(S,2));
Use filtfilt for zero-phase filtering. filter introduces a time delay (group delay). filtfilt applies the filter forward and backward, achieving zero phase delay — essential for any time-domain analysis where alignment matters.
Exercise
Audio Denoising Pipeline
  1. Generate a 3-second audio signal at Fs=8000 Hz: a 440 Hz tone (A4) + 880 Hz (A5), mixed with white Gaussian noise at 0 dB SNR.
  2. Plot the noisy signal's spectrogram and identify the target frequencies visually.
  3. Design a band-pass FIR filter (400–950 Hz) using fir1 with a Kaiser window and apply it with filtfilt.
  4. Compare the SNR before and after filtering using snr() (Signal Processing Toolbox) or compute it manually.
  5. Plot the before/after spectrograms side by side and annotate the target frequencies with horizontal lines.

Implement a real-time notch filter using iirnotch that removes 60 Hz powerline interference from a signal. Plot the frequency response of the notch filter using freqz. Then apply it to a signal contaminated with 60 Hz, 120 Hz, and 180 Hz harmonics. Show the spectrum before and after.

What's Next

The foundations from today carry directly into Day 4. In the next session the focus shifts to Day 4 — building directly on everything covered here.

Supporting Videos & Reading

Go deeper with these external references.

Day 3 Checkpoint

Before moving on, verify you can answer these without looking:

Live Bootcamp

Learn this in person — 2 days, 5 cities

Thu–Fri sessions in Denver, Los Angeles, New York, Chicago, and Dallas. $1,490 per seat. June–October 2026.

Reserve Your Seat →
Continue To Day 4
Day 4: Simulink