# Fir filter Hamming window 161 order bandpass filter implementation

I'm running an FIR filter hamming window order 161 bandpass with pass frequency range 20Hz-200Hz, but output doesn't sound like the filter is working. It's just distorted output. Following is the code and 162 coefficients. note I'm using c5545 dsp booster pack whih comes with aic3206 codec inbuilt

coeff:-0.00035514,-0.0003342,-0.00031519,-0.0002975,-0.00028048,-0.00026346,-0.00024575,-0.00022664,-0.00020539,-0.00018126,-0.00015351,-0.00012138,-8.4119e-05,-4.0977e-05,8.7845e-06,6.5896e-05,0.00013107,0.00020499,0.00028834,0.00038174,0.00048581,0.00060111,0.00072817,0.00086749,0.0010195,0.0011846,0.0013631,0.0015553,0.0017614,0.0019817,0.0022161,0.0024647,0.0027276,0.0030046,0.0032955,0.0036002,0.0039183,0.0042495,0.0045934,0.0049494,0.005317,0.0056956,0.0060845,0.006483,0.0068902,0.0073053,0.0077274,0.0081555,0.0085887,0.0090258,0.0094659,0.0099077,0.01035,0.010792,0.011233,0.01167,0.012103,0.012531,0.012952,0.013366,0.013771,0.014165,0.014548,0.014918,0.015275,0.015617,0.015943,0.016253,0.016544,0.016817,0.017071,0.017304,0.017515,0.017705,0.017873,0.018018,0.018139,0.018237,0.01831,0.018359,0.018384,0.018384,0.018359,0.01831,0.018237,0.018139,0.018018,0.017873,0.017705,0.017515,0.017304,0.017071,0.016817,0.016544,0.016253,0.015943,0.015617,0.015275,0.014918,0.014548,0.014165,0.013771,0.013366,0.012952,0.012531,0.012103,0.01167,0.011233,0.010792,0.01035,0.0099077,0.0094659,0.0090258,0.0085887,0.0081555,0.0077274,0.0073053,0.0068902,0.006483,0.0060845,0.0056956,0.005317,0.0049494,0.0045934,0.0042495,0.0039183,0.0036002,0.0032955,0.0030046,0.0027276,0.0024647,0.0022161,0.0019817,0.0017614,0.0015553,0.0013631,0.0011846,0.0010195,0.00086749,0.00072817,0.00060111,0.00048581,0.00038174,0.00028834,0.00020499,0.00013107,6.5896e-05,8.7845e-06,-4.0977e-05,-8.4119e-05,-0.00012138,-0.00015351,-0.00018126,-0.00020539,-0.00022664,-0.00024575,-0.00026346,-0.00028048,-0.0002975,-0.00031519,-0.0003342,-0.00035514


Edited code:

here is the code i used to convert the float coeff to fixed point int. still it doesn't work 
int N=17;
int i,n;
int index1=0;
int index2=N;
Int16 x[2*17];
Int16 z[2*17];
float y1new,y2new;
I2S_writeLeft(0);
I2S_writeRight(0);
for(n=0;n<N;n++){
coeff1[n]=round(coeff[n]*65536);
}
for ( sec = 0 ; sec < 30 ; sec++ )
{
for ( msec = 0 ; msec < 1000 ; msec++ )
{
for ( sample = 0 ; sample < 8 ; sample++ )
{
/* Read 16-bit left channel Data */

/* Read 16-bit right channel Data */

// As a new sample is received put it in two places
x[index1] = data1;
x[index2] = data1;
z[index1] = data2;
z[index2] = data2;
y1new=0;
y2new=0;
for(i=0;i<N;i++){
y1new = y1new + coeff1[i]*x[index2-i];
y2new = y2new + coeff1[i]*z[index2-i];
}

index1 = (index1+1)%N;
index2 = index1+N;
data1=round(y1new/65536);
data2=round(y2new/65536);
/* Write 16-bit left channel Data */
I2S_writeLeft(data1);

/* Write 16-bit right channel Data */
I2S_writeRight(data2);
}
if(sw3Pressed == TRUE)
{
break;
}

}
if(sw3Pressed == TRUE)
{
break;
}

}


• Running your coeffs through fvtool in matlab the magnitude response looks like a lowpass filter and not a bandpass filter. – Irreducible Mar 28 '18 at 8:06
• fl=20/16000; fh=200*2/16000; wn=[fl,fh]; b=fir1(16,wn,'bandpass'); csvwrite('coeff.h',b); freqz(b,1,8192,16000) this is the code. they were generated by matlab – Dr.Pot Mar 29 '18 at 8:11

Are you converting your coefficients to fixed point arithmetic? Maybe using a different Qi

EDIT: in your code you're writting a 32 bit floating point to a 16 bit function (at least the comment said that), probably the data from your codec is a 16 bit signed integer, so you need to convert your coeficients to integers and use fixed point arithmetic or convert your input to floating point and before writting to the output convert the output to an integer.

• Please use comments to ask for clarification or more details. – MBaz Mar 28 '18 at 15:46
• No I just used the exact values generated by matlab in my code – Dr.Pot Mar 29 '18 at 8:14
• Hi. What do you mean converting coefficients to integer? coeff values are less than 1 – Dr.Pot Mar 29 '18 at 21:12
• here is the code i used to convert the float coeff to fixed point int. still it doesn't work – Dr.Pot Apr 2 '18 at 5:39
• Please look at the updated code at the top, changed code to implement fixed point bit conversion of coeffs. But it still doesn't work. – Dr.Pot Apr 2 '18 at 6:36

You are using simply the Hamming window, not a filter with a Hamming window. You should first construct your basic sinc FIR, then multiply that, element wise, with the window. I don't know your requirements, but, for example, considering a sampling frequency of f0=1024, wc1=20, wc2=200, N=161, you get this impulse response:

[8.271000348697398*10^-4,-4.005705674586021*10^-5,5.295367364956051*10^-4,0.002393066734599492,0.004921821759432649,0.007220158325130953,0.0084484982317697,0.008134200102254907,0.006355564916819758,0.003727846760386229,0.001191040935974927,-3.278871443899911*10^-4,-2.57487614429514*10^-4,0.001396932356852497,0.004038250464381994,0.006680203763999663,0.008299599293271053,0.008212844748323863,0.006338876479588884,0.003248142380583287,-2.711429741182299*10^-5,-0.00235900216488486,-0.002937407884857515,-0.001579970520602455,0.001179041359396353,0.004261210947769193,0.006423313033375057,0.006711041312070553,0.004822626767540098,0.001245096116571405,-0.002895471634774978,-0.006225334281313758,-0.007621229501046421,-0.006635931356601788,-0.003691526664524759,4.028168191795361*10^-5,0.003039788619072278,0.003986857774999568,0.002259079382890321,-0.00180517205866057,-0.006986332153640902,-0.01159247473520406,-0.01406245832827337,-0.01355077422676097,-0.01027790911162972,-0.005505336605885325,-0.001124729222780451,0.001008192280744322,-2.357100534790199*10^-4,-0.004796321648929437,-0.01137276218296066,-0.01782648539361997,-0.02191901380400041,-0.02213498938322603,-0.01829459360740204,-0.01171705480380689,-0.004844333193264914,-4.236804040492915*10^-4,-5.143398798411001*10^-4,-0.005666274802851579,-0.01458268396492148,-0.02442822326901363,-0.03172662971439864,-0.03357694012510566,-0.02878200215535023,-0.01847909317325192,-0.006000691963658145,0.00406378955865214,0.007362737526424468,0.001380132111733462,-0.01339200434941131,-0.03314022101915493,-0.05146500752236288,-0.06103185117181874,-0.05570332124486767,-0.03253499829996801,0.006981302471188885,0.0568514539841485,0.1077829359401652,0.1493781500300271,0.1727347724935315,0.1727347724935315,0.1493781500300271,0.1077829359401652,0.0568514539841485,0.006981302471188885,-0.03253499829996801,-0.05570332124486767,-0.06103185117181874,-0.05146500752236288,-0.03314022101915493,-0.01339200434941131,0.001380132111733462,0.007362737526424468,0.00406378955865214,-0.006000691963658145,-0.01847909317325192,-0.02878200215535023,-0.03357694012510566,-0.03172662971439864,-0.02442822326901363,-0.01458268396492148,-0.005666274802851579,-5.143398798411001*10^-4,-4.236804040492915*10^-4,-0.004844333193264914,-0.01171705480380689,-0.01829459360740204,-0.02213498938322603,-0.02191901380400041,-0.01782648539361997,-0.01137276218296066,-0.004796321648929437,-2.357100534790199*10^-4,0.001008192280744322,-0.001124729222780451,-0.005505336605885325,-0.01027790911162972,-0.01355077422676097,-0.01406245832827337,-0.01159247473520406,-0.006986332153640902,-0.00180517205866057,0.002259079382890321,0.003986857774999568,0.003039788619072278,4.028168191795361*10^-5,-0.003691526664524759,-0.006635931356601788,-0.007621229501046421,-0.006225334281313758,-0.002895471634774978,0.001245096116571405,0.004822626767540098,0.006711041312070553,0.006423313033375057,0.004261210947769193,0.001179041359396353,-0.001579970520602455,-0.002937407884857515,-0.00235900216488486,-2.711429741182299*10^-5,0.003248142380583287,0.006338876479588884,0.008212844748323863,0.008299599293271053,0.006680203763999663,0.004038250464381994,0.001396932356852497,-2.57487614429514*10^-4,-3.278871443899911*10^-4,0.001191040935974927,0.003727846760386229,0.006355564916819758,0.008134200102254907,0.0084484982317697,0.007220158325130953,0.004921821759432649,0.002393066734599492,5.295367364956051*10^-4,-4.005705674586021*10^-5,8.271000348697398*10^-4]


You can multiply this, element wise, with your window. BTW, your window coefficients are downscaled by a factor of approximately 54.395. This is the window I get:

[0.08000000000000002,0.0803502520611919,0.08140047486865282,0.08314906910628267,0.08559337195349054,0.08872966114023118,0.09255316061540825,0.09705804782001243,0.1022374625539182,0.1080835174228373,0.114587309849519,0.1217389356309068,0.1295275040206056,0.137941154313693,0.1469670739086153,0.156591517818667,0.1667998296033383,0.1775764636876553,0.1889050090355284,0.2007682141410511,0.2131480132996994,0.2260255541194192,0.2393812262297095,0.2531946911449826,0.267444913236722,0.2821101917672749,0.2971681939364971,0.3125959888909221,0.3283700826436701,0.3444664538519133,0.3608605903974197,0.377527526714465,0.3944418818082722,0.4115778979060787,0.4289094796819766,0.4464102339957886,0.4640535100854676,0.4818124401518113,0.4996599802736878,0.5175689515914672,0.5355120816959413,0.5534620461597044,0.5713915101477487,0.5892731700439097,0.6070797950297692,0.6247842685527005,0.6423596296199047,0.6597791138555558,0.6770161942585302,0.6940446215986537,0.7108384643899491,0.7273721483800123,0.7436204954953796,0.759558762183581,0.7751626770934887,0.7904084780365817,0.8052729481728389,0.8197334513661572,0.8337679666554523,0.8473551217889509,0.8604742257706041,0.8731053003690614,0.8852291105412222,0.8968271937240332,0.9078818879499261,0.9183763587430815,0.9282946247555586,0.9376215821042515,0.9463430273716122,0.9544456792351128,0.9619171986925085,0.9687462078521025,0.9749223072593993,0.9804360917337572,0.985279164690928,0.9894441509296694,0.9929247078629597,0.9957155351767122,0.9978123829012786,0.9992120578834522,0.9999124286491134,0.9999124286491134,0.9992120578834522,0.9978123829012786,0.9957155351767122,0.9929247078629597,0.9894441509296694,0.985279164690928,0.9804360917337572,0.9749223072593993,0.9687462078521025,0.9619171986925085,0.9544456792351128,0.9463430273716122,0.9376215821042515,0.9282946247555586,0.9183763587430815,0.9078818879499261,0.8968271937240332,0.8852291105412222,0.8731053003690614,0.8604742257706041,0.8473551217889509,0.8337679666554523,0.8197334513661572,0.8052729481728389,0.7904084780365817,0.7751626770934887,0.759558762183581,0.7436204954953796,0.7273721483800123,0.7108384643899491,0.6940446215986537,0.6770161942585302,0.6597791138555558,0.6423596296199047,0.6247842685527005,0.6070797950297692,0.5892731700439097,0.5713915101477487,0.5534620461597044,0.5355120816959413,0.5175689515914672,0.4996599802736878,0.4818124401518113,0.4640535100854676,0.4464102339957886,0.4289094796819766,0.4115778979060787,0.3944418818082722,0.377527526714465,0.3608605903974197,0.3444664538519133,0.3283700826436701,0.3125959888909221,0.2971681939364971,0.2821101917672749,0.267444913236722,0.2531946911449826,0.2393812262297095,0.2260255541194192,0.2131480132996994,0.2007682141410511,0.1889050090355284,0.1775764636876553,0.1667998296033383,0.156591517818667,0.1469670739086153,0.137941154313693,0.1295275040206056,0.1217389356309068,0.114587309849519,0.1080835174228373,0.1022374625539182,0.09705804782001243,0.09255316061540825,0.08872966114023118,0.08559337195349054,0.08314906910628267,0.08140047486865282,0.0803502520611919,0.08000000000000002]


You are using an unreasonably small bandwidth (that implies an even more unreasonably small transition width) compared to your sampling frequency. You should either choose a smaller sampling frequency, or a higher order. For example, using a Kaiser window and letting Kaiser determine the order, with a side-lobe attenuation of 60dB and a transition width of 40*2/16000, I get an order of 1451:

And here's a zoom on the passband on the graph on the right (x-axis is in samples, 8192/2 being Nyquist):

As far as I see it, you have 4 options: quit, go on blindly ahead, lower sampling frequency, use a (much) higher order -- for Hamming, you may need a higher order than for a Kaiser, and for an equiripple you'll most probably achieve a lower one than Kaiser, and an even lower one if you can tolerate a higher ripple in the passband.

• ['code'] fl=20/16000; fh=200*2/16000; wn=[fl,fh]; b=fir1(16,wn,'bandpass'); csvwrite('coeff.h',b); freqz(b,1,8192,16000) here is the matlab code i used to generate those coefficients – Dr.Pot Mar 29 '18 at 8:16
• Seems like I've only one choice that is to reduce sampling rate to probably 4000 or so. I can't increase the order since it would induce latency for processing. – Dr.Pot Apr 2 '18 at 6:40
• Do you need that high a sampling rate? for 200Hz, a 512Hz sampling rate would work just fine, 1k, or 1024 for (quite a bit of) extra room. Note that, according to my example (f0=16kHz), results in N=1451, which means for 4kHz => 1451/4 ~ 363. 4k seems too much, but, of course, you know your requirements. – a concerned citizen Apr 2 '18 at 9:57
• well, I need atleast 4000hz for my application as my bandpass can go to 1500hz later but now i'm cutting at 200hz. But the issue is even I decrease the sample rate to 8000 and filter order to 16, still it's not working. please look at the updated code, do you think my float coeff conversion to 16bit integer is right? – Dr.Pot Apr 2 '18 at 22:46
• Since your order didn't work and needed to be increased, or the order kept but the sampling rate decreased, you can't expect to reduce both and have it working, that's very counter-intuitive. And your code doesn't deal with creating the filter, only with the filtering process. So, rather than going on blindly, woudn't it be better for you to state your requirements and then see what filter can come out of it, instead of poking around at numbers, aimlessly? – a concerned citizen Apr 3 '18 at 6:16