# Notch filtering of tonal noise

Null out tonal noise in a noisy speech signal. Compare second-order FIR and IIR filters.

## Contents

```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)
```