Notch filtering of tonal noise
Null out tonal noise in a noisy speech signal. Compare second-order FIR and IIR filters.
Contents
Load data
clear [s, Fs] = wavread('clean.wav'); % speech signal [x, Fs] = wavread('noisy.wav'); % speech signal with tonal noise
Plot waveforms
N = length(x); t = (0:N-1)'/Fs; % t : time axis figure(1) clf plot(t, s, t, x-0.1) legend('Clean speech', 'Speech with tonal noise') xlabel('Time (sec)') box off
plot detail
figure(1) clf plot(t, s, t, x-0.1) xlim([0.5 0.9]) legend('Clean speech', 'Speech with tonal noise') xlabel('Time (sec)') box off orient landscape print -dpdf data
Make FIR notch filter
fn = 500; % frequency to null out I = sqrt(-1); b = [1 -2*cos(2*pi*fn/Fs) 1]; % filter coefficients a = 1; b = b/polyval(b, -1); % make peak gain = 1 % b = b/sum(b); % make dc gain = 1
Display FIR pole-zero diagram
The zeros are on the unit circle at angle 2*pi*fn/Fs.
figure(1)
clf
zplane(b, a)
title('FIR notch filter')
Display FIR frequency response
[H, om] = freqz(b, a);
Display frequency response (normalized frequency)
figure(3) clf plot(om/(2*pi), abs(H)) xlabel('Normalized frequency (cycles/sample)') title('Frequency response') box off
Display frequency response (Hz)
figure(3) clf plot(om/(2*pi)*Fs, abs(H)) xlabel('Frequency (cycles/second = Hz)') title('Frequency response') box off
Apply FIR filter to noisy speech
The filter suppresses tonal noise, but it also attenuates the speech waveform, leading to distortion. That is because the notch is vey wide.
y = filter(b, a, x); figure(1) clf plot(t, x, t, y - 0.1) xlim([0.5 0.7]) legend('Noisy signal', 'Filtered (FIR)') xlabel('Time (sec)')
Make IIR notch filter
Put poles at same angle, inside unit circle.
b = [1 -2*cos(2*pi*fn/Fs) 1]; % filter coefficients r = 0.95; a = [1 -2*r*cos(2*pi*fn/Fs) r^2]; % filter coefficients b = b/sum(b)*sum(a); % make dc gain equal to 1
Display IIR pole-zero diagram
figure(1)
clf
zplane(b, a)
title('IIR notch filter')
Display IIR frequency response
The notch is quite narrow, not like the FIR filter. Now, the filter will attenuate fewer frequencies.
[H, om] = freqz(b, a); figure(2) clf plot(om/(2*pi)*Fs, abs(H)) xlabel('Frequency (Hz)') title('Frequency response (IIR) filter') box off
Apply IIR filter to noisy speech
y2 = filter(b, a, x); figure(1) clf plot(t, x, t, y2 - 0.1) legend('Noisy signal', 'Filtered (IIR)') xlim([0.5 0.7]) xlabel('Time (sec)')
Compare FIR and IIR filtered signals
The output of the IIR filter preserves the shape of the speech waveform better than the FIR filter.
figure(1) clf plot(t, s+0.1, t, x, t, y - 0.1, t, y2 - 0.2) xlim([0.5 0.7]) legend('Clean signal','Noisy signal', 'Filtered (FIR)', 'Filtered (IIR)') xlabel('Time (sec)') title('Tonal noise suppression by notch filtering') orient tall print -dpdf signals
Listen to filter output
% soundsc(y, Fs)
soundsc(x, Fs)
pause
soundsc(y2, Fs)