% % In this demo, we'll use the strategy of inverse Fourier transforming the % desired frequency response, and then truncating and windowing the resulting % infinite sequence to get a FIR filter. % % % First, read in a 20 second audio clip. (Bruce Cockburn) % [Y,FS,NBITS]=wavread('clip.wav'); % % First, we'll play with a simple 5 point running average filter. % disp('Here are the filter coefficients for a 17 point running average filter'); M=17; w=ones(M,1)/M % % Plot the spectrum of the filter. % figure(1); df=1/1024; f=-0.5:df:0.5; s=zeros(size(f)); for k=1:length(f) for l=1:M, s(k) = s(k) + (w(l)*exp(sqrt(-1)*2*pi*(l-1)*f(k))); end; end; plot(f,20*log10(abs(s))); xlabel('Relative frequency (f/fs)'); ylabel('frequency response (db)'); print -deps runningaverage.ps % % % YFILTERED=conv(Y,w); % % The convolution will increase the length of the signal by M-1 samples. This % happens because the filter has a response that lasts beyond the end of the % the signal. We'll take these extra samples out. % YFILTERED=YFILTERED(1:882000); % % Save the filtered signal. % wavwrite(YFILTERED,FS,NBITS,'clipg.wav'); disp('Figure 1 shows the frequency response of the 17 point running mean filter.'); disp('Play clipg.wav'); disp('press enter to continue'); pause; % % Next, construct an M point filter sequence using (10) from the notes. Feel % free to adjust M to any odd number that you might want. We'll start % with M=15. % % In our case, we want a cutoff at a frequency of 2Khz, which is roughly % 44100/22=2004.5 Hz. So, alpha=22. % % The only trick here is that MATLAB wants the sequence to be from 1 to M % instead of -(M-1)/2 to (M-1)/2, so we shift the index of summation. % alpha=22; M=15; w=zeros(M,1); for i=-(M-1)/2:(M-1)/2, w(i+(M-1)/2+1)=(2/alpha)*sinc(2*i/alpha); end; % % % disp('Here are the truncated filter coefficients.'); w % % Plot the spectrum of the filter. % figure(2); df=1/1024; f=-0.5:df:0.5; s=zeros(size(f)); for k=1:length(f) for l=1:M, s(k) = s(k) + (w(l)*exp(sqrt(-1)*2*pi*(l-1)*f(k))); end; end; plot(f,20*log10(abs(s))); xlabel('Relative frequency (f/fs)'); ylabel('frequency response (db)'); print -deps unwindowedfreq.ps % % Now, apply the filter to our signal. % YFILTERED=conv(Y,w); % % The convolution will increase the length of the signal by M-1 samples. This % happens because the filter has a response that lasts beyond the end of the % the signal. We'll take these extra samples out. % YFILTERED=YFILTERED(1:882000); % % Save the filtered signal. % wavwrite(YFILTERED,FS,NBITS,'cliph.wav'); disp('Figure 2 shows the frequency response of the filter'); disp('To hear the clip, play cliph.wav'); disp('press enter to continue'); pause; % % There's noticable ripple in the frequency response, although it may not % be audible. % % Next, we apply a Bartlett window % window=bartlett(M); w2=w.*window; df=1/1024; f=-0.5:df:0.5; s=zeros(size(f)); for k=1:length(f) for l=1:length(w2), s(k) = s(k) + (w2(l)*exp(sqrt(-1)*2*pi*(l-1)*f(k))); end; end; figure(3); plot(f,20*log10(abs(s))); xlabel('frequency, relative to sampling frequency'); ylabel('frequency response (db)'); print -deps windowedfreq.ps % % Now, apply the filter to our signal. This time, we'll use the filter % command. % YFILTERED=filter(w2,[1],Y); % % Save the filtered signal. % wavwrite(YFILTERED,FS,NBITS,'clipi.wav'); disp('Figure 3 shows the frequency response of the windowed filter'); disp('To hear the clip, play clipi.wav'); disp('press enter to continue'); pause; % % Finally, design a 2Khz low pass filter using the frequency sampling % technique. % N=64; fstep=FS/N; freqs=(-22050:fstep:22050-fstep)'; w3t=ones(N,1); w3t=w3t.*(abs(freqs)<2000); w3=ifft(ifftshift(w3t)); % % Plot the frequency response. % df=1/4096; f=-0.5:df:0.5; s=zeros(size(f)); for k=1:length(f) for l=1:length(w3), s(k) = s(k) + (w3(l)*exp(sqrt(-1)*2*pi*(l-1)*f(k))); end; end; figure(4); plot(f,abs(s)); xlabel('frequency, relative to sampling frequency'); ylabel('|W(f)|'); print -deps freqsamp.ps % % Now, apply the filter to our signal. This time, we'll use the filter % command. % YFILTERED=filter(w3,[1],Y); % % Save the filtered signal. % wavwrite(YFILTERED,FS,NBITS,'clipj.wav'); % % % disp('Figure 4 shows the frequency response of the frequency sampling filter'); disp('This plot is not in db units, because the cutoff is down to 0 (where'); disp('db is not defined) at some frequencies.'); disp('To hear the clip, play clipj.wav'); disp('Notice that there is still a lot of high frequency content left.'); % % All of the following clips try to low pass the original clip. % % clipg 17 point running mean filter % cliph Truncated inverse FFT filter, no window. % clipi Truncated inverse FFT filter, Bartlett window. % clipj 64 point frequency sampling filter % % The filters in clipg and cliph are fairly effective low pass filters at % about 2Khz. In clip i, the use of the Barlett window has smoothed % out the ripple, but at the expense of broadening the frequency response % to about 4Khz- this sounds much closer to the original clip than % clipg or cliph. In clip j, there's lots of energy at some but not % all higher frequencies, so this sounds much like the original clip, but % "weird" %