Final project for ECE 485: Digital Audio Processing — an LMS (least-mean-squares) adaptive filter used to cancel noise from speech, evaluated on the NOIZEUS speech corpus at multiple SNR levels using babble noise.
Full write-up and results are in docs/Adaptive Noise Cancellation Presentation.pdf.
Highlights:
- Recovered speech from real babble-noise mixtures with up to +9.7 dB SNR improvement at the hardest tested condition (0 dB input SNR)
- Benchmarked across 4 SNR levels and 5 NOIZEUS speakers, with sensitivity sweeps over step size (
mu), filter length (M), and reference-noise correlation - Found that convergence is driven almost entirely by step size — filter length can be cut 16x (64 → 4 taps) with negligible SNR loss, a useful result for latency/compute-constrained deployments
- Entire LMS pipeline implemented from scratch in base MATLAB, no toolboxes required
Each script implements the same core adaptive noise cancellation setup:
- A primary input
d= clean speech + noise - A reference input
x= a filtered/correlated version of the noise (simulating a second microphone that picks up noise but not speech) - An adaptive FIR filter (length
M) updated sample-by-sample via the LMS rule to predict the noise component indfromx - The filter's error signal
e = d - yis the cleaned (denoised) speech estimate
Performance is measured as SNR improvement (output SNR − input SNR) and visualized via learning curves (smoothed MSE over iterations).
LMS recovers intelligible speech from real babble-noise mixtures. Filtering sp01_babble_sn0.wav (0 dB input SNR) with the adaptive filter removes the noise floor between speech segments while preserving the speech envelope:
The filter improves SNR at every noise level tested, with the largest gains at the hardest (0 dB) condition — a +9.7 dB improvement — tapering to +3.6 dB at 15 dB input SNR, since there's less noise left to remove. The bottom panel overlays smoothed learning curves for all four SNR conditions, which converge to a similar error floor regardless of starting noise level:
Step size (mu) drives performance far more than filter length (M). Sweeping both parameters at a fixed 10 dB input SNR shows output SNR rising steadily from ~10 dB to ~15–16 dB as mu increases from 0.005 to 0.8, for both babble and white noise. Filter length, by contrast, is essentially flat across M = 4 to 64 taps — a 16x increase in filter length buys almost no improvement:
Practically, this means a short, cheap filter performs nearly as well as a long one — a useful result for deploying LMS noise cancellation under compute or latency constraints, where tuning mu matters far more than adding filter taps.
scripts/ MATLAB scripts (see below)
data/ NOIZEUS clean speech + babble-noise-mixed .wav files
docs/ Project presentation (PDF)
| Script | Description |
|---|---|
scripts/lms_demo.m |
Simplest demo: sp01.wav + synthetic white noise, single LMS run, with plots and audio playback. Good starting point for understanding the algorithm. |
scripts/lms_real_noise.m |
Loads the pre-mixed NOIZEUS babble files (sp01_babble_snX.wav) for SNR = 0/5/10/15 dB, recovers the true noise as noisy − clean, and runs LMS at each level with plots and audio playback. |
scripts/lms_real_noise_v2.m |
Same setup as lms_real_noise.m, but adds an aggregate SNR-improvement bar chart and a combined learning-curve comparison across SNR levels. Audio playback is disabled. |
scripts/lms_noizeus_experiments.m |
The most complete experiment script. Loops over all 5 speakers × 4 SNR levels using synthetically generated Gaussian noise calibrated to each target SNR (rather than the pre-mixed babble files), then runs three additional sensitivity sweeps: step size (mu), filter length (M), and reference-noise correlation. |
Note the methodology difference: lms_real_noise.m/lms_real_noise_v2.m cancel the actual babble noise recovered from the NOIZEUS mixtures, while lms_noizeus_experiments.m uses synthetic Gaussian noise shaped to match the same target SNRs, which makes it easier to isolate and sweep individual parameters.
- MATLAB (no additional toolboxes required — uses only base functions:
audioread,soundsc,filter,movmean)
Open any script in scripts/ and run it directly (e.g. press Run in MATLAB, or run scripts/lms_demo.m). Each script resolves the data/ folder relative to its own location, so it works regardless of MATLAB's current working directory. Figures are generated automatically; some scripts also play audio via soundsc.
data/ contains the NOIZEUS clean speech files (sp01.wav–sp05.wav) and their corresponding babble-noise-mixed versions at 0/5/10/15 dB SNR (spXX_babble_snY.wav), from the NOIZEUS noisy speech corpus.



