DSPRelated.com
Forums

FIR Filter Help

Started by Unknown February 13, 2005
sorry, samseed==yeti

Here's what I'm trying to do for a low-pass filter. When I play the
"filtered" audio, it seems that the high freq. samples (above 2000Hz?)
are static, but the lower samples sound normal. Is this an expected
result? Is this because the freqs above 2000 are getting attenuated and
they sound like static? I was under the impression that the freqs above
2000Hz would not be audible at all...

Also, is it better to have more taps?

//low-pass coefficiants--->2000Hz
double a0 =-0.028991204;
double a1 =0.008665846;
double a2 =0.033431057;
double a3 =-0.022146257;
double a4 =-0.03713305;
double a5 =0.0438389;
double a6 =0.03991636;
double a7 =-0.08839387;
double a8 =-0.041643668;
double a9 =0.2891702;
double a10 =0.5012413;
double a11 =0.2891702;
double a12 =-0.041643668;
double a13 =-0.08839387;
double a14 =0.03991636;
double a15 =0.0438389;
double a16 =-0.03713305;
double a17 =-0.022146257;
double a18 =0.033431057;
double a19 =0.008665846;
double a20 =-0.028991204;

samples[t]= (short)(a0*(audioShortData[t]+audioShortData[t-1])+
        	    a1*(audioShortData[t]+audioShortData[t-1])+
                    a2*(audioShortData[t]+audioShortData[t-1])+
                    a3*(audioShortData[t]+audioShortData[t-1])+
	            a4*(audioShortData[t]+audioShortData[t-1])+
	            a5*(audioShortData[t]+audioShortData[t-1])+
	            a6*(audioShortData[t]+audioShortData[t-1])+
		    a7*(audioShortData[t]+audioShortData[t-1])+
		    a8*(audioShortData[t]+audioShortData[t-1])+
		    a9*(audioShortData[t]+audioShortData[t-1])+
		    a10*(audioShortData[t]+audioShortData[t-1])+
		    a11*(audioShortData[t]+audioShortData[t-1])+
		    a12*(audioShortData[t]+audioShortData[t-1])+
		    a13*(audioShortData[t]+audioShortData[t-1])+
		    a14*(audioShortData[t]+audioShortData[t-1])+
		    a15*(audioShortData[t]+audioShortData[t-1])+
		    a16*(audioShortData[t]+audioShortData[t-1])+
		    a17*(audioShortData[t]+audioShortData[t-1])+
		    a18*(audioShortData[t]+audioShortData[t-1])+
		    a19*(audioShortData[t]+audioShortData[t-1])+
		    a20*(audioShortData[t]+audioShortData[t-1])
);

doh, sample[t] is equal to audioShortData[t].

I forgot to change them all...

samseed wrote:
> Thanks Jerry. Yes, I am familiar with Smith's book, I've printed out a > few of those chapters.
I printed out one chapter, then I bought the book. I like to read in bed, and there's no room for two people and a monitor. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
<yeti349@yahoo.com> wrote in message 
news:1108483029.863256.74540@z14g2000cwz.googlegroups.com...
> Here's what I'm trying to do for a low-pass filter. When I play the > "filtered" audio, it seems that the high freq. samples (above 2000Hz?) > are static, but the lower samples sound normal. Is this an expected > result? Is this because the freqs above 2000 are getting attenuated and > they sound like static? I was under the impression that the freqs above > 2000Hz would not be audible at all...
It should work something like your Goldwave example. Static is an indication of a bug.
> Also, is it better to have more taps?
Better? You can get sharper filtering with more taps, at the cost of it taking longer to process, requiring more memory, etc.. Those factors may not be an issue for your Java implementation, but often with real-time applications, they are!
> //low-pass coefficiants--->2000Hz > double a0 =-0.028991204; > double a1 =0.008665846; > double a2 =0.033431057; > double a3 =-0.022146257;
<snip>
> > samples[t]= (short)(a0*(audioShortData[t]+audioShortData[t-1])+ > a1*(audioShortData[t]+audioShortData[t-1])+ > a2*(audioShortData[t]+audioShortData[t-1])+ > a3*(audioShortData[t]+audioShortData[t-1])+
<snip> This isn't right. You had the right formula in your earlier post with just 3 taps, but now with 20, you're not following the same pattern. Review your formula for 3 taps, or Jerry's modification of it, then extend that to the extra taps. Make sense? It should look something like this: samples[t]= (short)(a0*(audioShortData[t])+ a1*(audioShortData[t-1])+ a2*(audioShortData[t-2]) + a3*(audioShortData[t-3]) + ... Also, I find it much easier to write the convolution (that's the part above where we are multiplying all the filter coefficients by the audio samples) in terms of a loop. That way it is easier to change to more/fewer taps and you are less likely to make a silly typing mistake. I don't know Java, but in C, it would look roughly something like this for your 20-tap filter: double coefs[20] = {-0.028991204, 0.008665846, ...} double accumulator = 0; for (int i = 0; i<20; i++) accumulator = accumulator + coefs[i]*audioShortData[t-i]; samples[t] = (short) accumulator; Also, I would highly recommend implementing a really simple 2-tap filter to make sure you don't have any other program errors. Or maybe even better, a filter that has one tap set to 1.0 and all the rest to 0. Then, you should get out exactly what you put in. If you can get that to work, you know you are on the right track. Simplification and partitioning is the essence of good debugging! -Jon
> samples[t]= (short)(a0*(audioShortData[t]+audioShortData[t-1])+ > a1*(audioShortData[t]+audioShortData[t-1])+ > a2*(audioShortData[t]+audioShortData[t-1])+ > a3*(audioShortData[t]+audioShortData[t-1])+
good lord, how did I over look that...sigh
>double coefs[20] = {-0.028991204, 0.008665846, ...} >double accumulator = 0; >for (int i = 0; i<20; i++) > accumulator = accumulator + coefs[i]*audioShortData[t-i];
>samples[t] = (short) accumulator;
great, java is basically the same!
ok here's what I have:

for (int t=0; t < audioShortData.length; t++) {

    double a0 =-0.028991204;
    double a1 =0.008665846;
    double a2 =0.033431057;

    audioShortData[t] = (short)(a0*audioShortData[t-2]+
           		        a1*audioShortData[t-1]+
                                a2*audioShortData[t]);

}

I'm not hearing any change in the audio.

Jerry Avins wrote:

> samseed wrote: > >> Thanks Jerry. Yes, I am familiar with Smith's book, I've printed out a >> few of those chapters. > > > I printed out one chapter, then I bought the book. I like to read in > bed, and there's no room for two people and a monitor. > > Jerry
Aren't there HUD's aimed at gaming market that would attach to your spectacles ;) Perhaps with bluetooth adapter to rid yourself of tangle prone cable. This is only half in jest. There are enough innovators here to produce a viable product. Perhaps ;]
an update.

Ok, my low-pass filter is working. Thank you all for setting me on the
right track. Although the filtered output is very quiet, there is an
obvious filtering of the higher frequencies. Also when I open both
files in GoldWave and compare the waveforms, the higher freqs are
clearly being filtered out.

My next steps are refining the low-pass and incorporating a high-pass
to construct a crude band-pass filter.

yeti349@yahoo.com wrote:
> an update. > > Ok, my low-pass filter is working. Thank you all for setting me on the > right track. Although the filtered output is very quiet, there is an > obvious filtering of the higher frequencies. Also when I open both > files in GoldWave and compare the waveforms, the higher freqs are > clearly being filtered out. > > My next steps are refining the low-pass and incorporating a high-pass > to construct a crude band-pass filter.
That may be educational, but it's not an efficient way, and it may increase the severity of the inevitable numerical errors. (At the very least, the signal that comes through the resultant bandpass will be subject to to round-off episodes. Design a single band-pass filter. Or rather, let a program design it for you. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;