Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Problems designing an FIR band pass filter on MATLAB?

  1. Dec 3, 2017 #1
    1. The problem statement, all variables and given/known data
    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.

    2. Relevant 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:
    where BW is the bandwidth (4800Hz) and the Fs is the sampling frequency (44.1kHz) Fc1 is the lower cutoff frequency, 200Hz.

    3. 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:

    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.

    Attached Files:

  2. jcsd
  3. Dec 3, 2017 #2
    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.
  4. Dec 4, 2017 #3


    User Avatar
    Gold Member

    Can you paste your code in text format so we can copy and paste it?
  5. Dec 4, 2017 #4
    Sure thing,

    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);
    k = 0:2*N;
    title('Ideal Lowpass Filter')

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

    y = conv(wh,X);
  6. Dec 4, 2017 #5


    User Avatar
    Gold Member

    Why don't you start by looking at the frequency components. You can't expect your code to just work.
  7. Dec 4, 2017 #6


    User Avatar
    Gold Member

    use the function fvtool
  8. Dec 4, 2017 #7
    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: Dec 4, 2017
  9. Dec 4, 2017 #8
    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.
  10. Dec 4, 2017 #9
    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?
  11. Dec 4, 2017 #10


    User Avatar
    Gold Member

    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!
  12. Dec 4, 2017 #11
    I just did exactly that and it fixed my problems. My filters all work very well now! Thank you very much for your help.
  13. Dec 4, 2017 #12


    User Avatar
    Gold Member

    :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.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook

Have something to add?