Problems designing an FIR band pass filter on MATLAB?

  • #1
45
5

Homework Statement


So I've been tasked with designing and band pass filter for my signals class. We're given the specifications that it needs to go from 200-5000Hz, and we need to use a kaiser window as the window function.

Homework Equations


There are 2 parameters, beta and N, given by these equations here:
upload_2017-12-3_22-46-45.png

where attenuation is the error d given by ATT = -20log_10 (d).
Imulse response of an ideal band pass filter is given by:
upload_2017-12-3_22-49-4.png

where BW is the bandwidth (4800Hz) and the Fs is the sampling frequency (44.1kHz) Fc1 is the lower cutoff frequency, 200Hz.

The Attempt at a Solution


So I've been at this one all weekend and I really feel like I'm doing nothing wrong. I picked an arbitrary error 0.01, which gives me and attenuation of 40dB, beta of 3.395321052 and an N of 493. I plug all these things into MATLAB and create a window function using the kaiser() function (The N used in the kaiser function is 2*N+1 to match the lengths). I then create an ideal filter by using a for loop on the equation with k = -N:N so it's centered on the origin. Afterwards I've multiplied the 2 functions together, making sure to use the element wise multiplication. At this point I think I'm should have my filter. I then convoluted it with the audio file I'm supposed to filter and it doesn't work. I'm at a loss here and I'm hoping someone could go over my code and tell my if I'm making a dumb move. The ProjectData file is just the audio file. I'm not allowed to use the kaiserord() function or the fir1() function, although I did just for fun and it worked fine so I know there's nothing wrong with my chosen attenuation.

Here is my script:
upload_2017-12-3_23-1-39.png



Thanks in advanced for any help guys and I apologize for the wordy attempt, I just wanted to make sure I covered all my bases here.
 

Attachments

Answers and Replies

  • #2
45
5
I should also mention that when I listen to the filtered audio file it (it actually has a ton of high and low frequency static for the purposes of my assignment) it sounds only slightly different from the original. When I used the other functions like fir1() it sounded significantly better, so I know my filter isn't doing its job.
 
  • #3
donpacino
Gold Member
1,439
282
Can you paste your code in text format so we can copy and paste it?
 
  • #4
45
5
Can you paste your code in text format so we can copy and paste it?
Sure thing,

clear
clc
load('ProjectData2.mat')
Fs = 44100;
Fc = 200;
C = 2*Fc/Fs;
h_ideal = [];

Beta = 8.7058%3.395321052;
N = 1414%493;


for k = -N:N
A1 = C*sinc(C*k);
h_ideal = horzcat(h_ideal,A1);
end
k = 0:2*N;
subplot(2,1,1)
plot(k,h_ideal)
title('Ideal Lowpass Filter')
xlabel('Frequency')
ylabel('Gain')

w = (kaiser(2*N+1,Beta)).';
wh = w.*h_ideal;
subplot(2,1,2)
plot(k,wh)
title('Final Filter')

y = conv(wh,X);
 
  • #5
donpacino
Gold Member
1,439
282
Why don't you start by looking at the frequency components. You can't expect your code to just work.
 
  • #6
donpacino
Gold Member
1,439
282
use the function fvtool
 
  • #7
45
5
Wow I really needed this tool. I've been trying to find a way to plot the frequency response for awhile (mostly playing around with fft() and ifft(), I googled for any more tools and didn't come across this.) Thanks for the help.
 
Last edited:
  • #8
45
5
So I used the tool to check my magnitude plots (I'm actually making a low pass and high pass as well I just didn't want to clutter my post too much) and I can tell that my band pass filter is off. My low pass seems to be fine. I'm really not sure how to go about fixing it considering we were given the impulse response to the filter and I followed it correctly. If it's worth mentioning looking over my notes I realized my bandwidth was off and that it was actually 5000kHz, not Hz. I adjusted for that and I'm still not getting a correct magnitude plot.
 
  • #9
45
5
After a little more tweaking I was able to get the desired band pass, but my gain is like 40dB, is there any way to lower it?
 
  • #10
donpacino
Gold Member
1,439
282
Ok, glad to hear you were able to fix the frequency problem!!!

The dc gain of an fir filter is proportional to the product of its coefficients (I think). Therefore you need to scale the output by the inverse of the products to get unity gain at dc. To change it at non dc (aka your bandpass range) you'll need to modify that a bit.

In short you will just divide your output by the amount needed. So if you need a unity gain filter in the pass-band, just divide by 40 dB!
 
  • #11
45
5
Ok, glad to hear you were able to fix the frequency problem!!!

The dc gain of an fir filter is proportional to the product of its coefficients (I think). Therefore you need to scale the output by the inverse of the products to get unity gain at dc. To change it at non dc (aka your bandpass range) you'll need to modify that a bit.

In short you will just divide your output by the amount needed. So if you need a unity gain filter in the pass-band, just divide by 40 dB!
I just did exactly that and it fixed my problems. My filters all work very well now! Thank you very much for your help.
 
  • #12
donpacino
Gold Member
1,439
282
:D nice.

I want to point out, all I really did was recommend you test your code, you did the rest. Matlab's online help documents are AMAZING. If you are ever stuck, read through them, and you might find out about new solutions or tools you can use to test.

And I recommend building test code or graphs into your code for debug purposes. I'm sure you've heard about software programs having 10k-100k lines of code. Often a large majority of that is test code to ensure the product and code is working correctly.
 

Related Threads on Problems designing an FIR band pass filter on MATLAB?

  • Last Post
Replies
0
Views
1K
  • Last Post
Replies
0
Views
5K
  • Last Post
Replies
2
Views
9K
Replies
16
Views
89K
  • Last Post
Replies
5
Views
2K
Replies
0
Views
3K
Replies
0
Views
3K
  • Last Post
Replies
5
Views
11K
  • Last Post
Replies
12
Views
8K
Top