I want to design a filter to remove all frequency components from a .wav file except those within $\pm 25\,\text{Hz}$ of $523\,\text{Hz}$ as well as its harmonics (up to the Nyquist frequency).
Attempt
I tried to suppress frequencies below 523-25 Hz using a high-pass filter, and suppress the ones higher than 523+25 Hz using a low pass filter. Here's my code:
[s, Fs] = wavread('x.wav');
for N=2:1:(Fs/(2*(523+25)))
% High-pass filter
FsNorm = (523-25).*N / (Fs/2);
[b,a] = butter(10, FsNorm, 'high');
sHigh = filtfilt(b, a, s);
% Low pass
FsNorm = (523+25).*N / (Fs/2);
[b,a] = butter(10, FsNorm, 'low');
sLow = filtfilt(b, a, s);
end
wavwrite(sLow, Fs, 'x_filtered');
The code doesn't work, the resulting file is mute. My intention is to apply each filter to the output of the previous filter, but I don't know how to implement this in code.
I used $(523+25) N_{max} < \frac{F_s}{2}$ to include all the harmonics up to the Nyquist frequency.
So what do I need to do to get this filter to work?
Edit:
Here's my new code:
[s, Fs] = wavread('x.wav');
sNew = zeros(size(s));
for N=2:1:(Fs/(2*(523+25)))
% High-pass filter
FsNorm = (523-25).*N / (Fs/2);
[b,a] = butter(10, FsNorm, 'high');
sHigh = filter(b, a, s);
% Low pass
FsNorm = (523+25).*N / (Fs/2);
[b,a] = butter(10, FsNorm, 'low');
sLow = filter(b, a, s);
Now sum the results
sNew = sHigh + sLow;
end
sNew
wavplay(sNew,Fs);
wavwrite(sNew, Fs, 'x_filtered');
I still get sNew=0
and the sound is still mute. What's wrong?
filtfilt
instead offilter
? $\endgroup$filtfilt
is even the correct call to use in this case. $\endgroup$filtfilt
unless you know exactly why you need it. $\endgroup$user20703
's answer. But the second part of that answer is, I believe, incorrect.keith
's answer seems to be the way to go. $\endgroup$s = sNew;
will zero out your input signal. Why is that there? $\endgroup$