If you just want coefficients for a single filter specification, you can use the code generated by this nice online code generator. It will produce C-code that you can use for a specified samplerate and cutoff-frequency. It will also do Chebyshev and Bessel filters as well as lowpass, highpass, bandpass and bandstop filters for you.
However, if your program needs adjustable cutoff or samplerate, you can not use this script.
The first part of this post will take a glance at the required analytical steps and the second part will simply give you the code.
One of the standard techniques is to use the analytical frequency response of the filter and then use bilinear transformation to obtain IIR filter coefficients.
The required steps require some math for which I found this lecture very helpful:
1) Take analytical transfer function: H(s)
2) Do bilinear transform: H( (z-1)/(z+1) )
3) "Warp" cutoff frequency to find cutoff in the "bilinear domain"
4) Express function as
5) Use these coefficients for time-domain filtering with the linear difference equation:
Notice that in order to simplify the derivation of the filter, you can safely set the sample time T to 2.
Doing this for a 2 pole Butterworth filter gives the following code in C++:
void getLPCoefficientsButterworth2Pole(const int samplerate, const double cutoff, double* const ax, double* const by)
{
double PI = 3.1415926535897932385;
double sqrt2 = 1.4142135623730950488;
double QcRaw = (2 * PI * cutoff) / samplerate; // Find cutoff frequency in [0..PI]
double QcWarp = tan(QcRaw); // Warp cutoff frequency
double gain = 1 / (1+sqrt2/QcWarp + 2/(QcWarp*QcWarp));
by[2] = (1 - sqrt2/QcWarp + 2/(QcWarp*QcWarp)) * gain;
by[1] = (2 - 2 * 2/(QcWarp*QcWarp)) * gain;
by[0] = 1;
ax[0] = 1 * gain;
ax[1] = 2 * gain;
ax[2] = 1 * gain;
}
which then can be used in a filter like this:
double xv[3];
double yv[3];
void filter(double* samples, int count)
{
double ax[3];
double by[3];
getLPCoefficientsButterworth2Pole(44100, 5000, ax, by);
for (int i=0;i<count;i++)
{
xv[2] = xv[1]; xv[1] = xv[0];
xv[0] = samples[i];
yv[2] = yv[1]; yv[1] = yv[0];
yv[0] = (ax[0] * xv[0] + ax[1] * xv[1] + ax[2] * xv[2]
- by[1] * yv[0]
- by[2] * yv[1]);
samples[i] = yv[0];
}
}
And that is it. To reduce summation error you may want to use Kahan summation!
39 Kommentare:
Hi,
Can you please post a sample code showing how I can apply LP butterworth on sample data at 8000hz, cf=100 and order =4?
I calculated the aCoeff and bCoeff using a Java applet I found on the web but I do not know how to write a code to use them to actually apply the filter on the data.
Thanks.
Hi sara!
Using the website here: http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html I have entered your specification. What is gives you is this code snippet:
#define NZEROS 4
#define NPOLES 4
#define GAIN 4.649932749e+05
static float xv[NZEROS+1], yv[NPOLES+1];
static void filterloop()
{ for (;;)
{ xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = next input value / GAIN;
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4];
yv[4] = (xv[0] + xv[4]) + 4 * (xv[1] + xv[3]) + 6 * xv[2]
+ ( -0.8144059977 * yv[0]) + ( 3.4247473473 * yv[1])
+ ( -5.4051668617 * yv[2]) + ( 3.7947911031 * yv[3]);
next output value = yv[4];
}
}
in which you just have to replace the three bold parts to iterate over your input and output arrays! :-) This is C++ of cause but it should make clear all you need.
Basically your output is a weighted sum of both the last few samples of the signal and the last few samples of the calculated output. So the output it out[i] = a[0]*in[i]+a[1]*in[i-1]...-(b[0]*out[i]...)!
Thank you for posting the code and the link.
I tried to understand how the a and b coeff are in play here in the generated code and I couldn't.
Can you pelase explain how these code relates to the a and b coeff?
Thanks.
Hi.
I was wondering how you got the formulas for the coefficients for the getLPCoefficientsButterworth2Pole function.
Also, if I wanted to write something like
getLPCoefficientsButterworth5Pole, what formulas would I use?
Thanks!
Hi,
I'm wondering if the coefficients the applet gave me are correct because the graphs it shows seem a bit odd to me.
I want to perform a high-pass filter on EEG data. I want to remove anything bellow 0.18 (lets up to 0.2) Hz and the sampling rate is 128. Since this is pretty simple, 1 order should suffice. I put those parameters into the applet and I get:
#define NZEROS 1
#define NPOLES 1
#define GAIN 1.004417893e+00
static float xv[NZEROS+1], yv[NPOLES+1];
static void filterloop()
{ for (;;)
{ xv[0] = xv[1];
xv[1] = next input value / GAIN;
yv[0] = yv[1];
yv[1] = (xv[1] - xv[0])
+ ( 0.9912030770 * yv[0]);
next output value = yv[1];
}
}
I know the gain is supposed to attenuate the signal, but I'm not sure this is good or bad.. or irrelevant since it's so little.
What confuses me is the 0.991203770 coefficient. Isn't that too small? Thanks in advance!
Hi,
I'm wondering if the coefficients the applet gave me are correct because the graphs it shows seem a bit odd to me.
I want to perform a high-pass filter on EEG data. I want to remove anything bellow 0.18 (lets up to 0.2) Hz and the sampling rate is 128. Since this is pretty simple, 1 order should suffice. I put those parameters into the applet and I get:
#define NZEROS 1
#define NPOLES 1
#define GAIN 1.004417893e+00
static float xv[NZEROS+1], yv[NPOLES+1];
static void filterloop()
{ for (;;)
{ xv[0] = xv[1];
xv[1] = next input value / GAIN;
yv[0] = yv[1];
yv[1] = (xv[1] - xv[0])
+ ( 0.9912030770 * yv[0]);
next output value = yv[1];
}
}
I know the gain is supposed to attenuate the signal, but I'm not sure this is good or bad.. or irrelevant since it's so little.
What confuses me is the 0.991203770 coefficient. Isn't that too small? Thanks in advance!
[url=http://www.ukgamingstore.co.uk/]cheap gaming computers[/url]
[url=http://www.ukgamingstore.co.uk/intel-core-i5-gaming-computers]intel core i3 gaming pc uk[/url]
[url=http://www.ukgamingstore.co.uk/intel-core-i7-gaming-laptops]intel core i7 gaming laptop uk[/url]
[url=http://www.ukgamingstore.co.uk/gaming-headsets]gaming headsets[/url]
Great article, totally what I was looking for.
Check out my web page any repairs to garage doors Sandton
WOW just what I was looking for. Came here by searching for blackwater jobs
Visit my blog :: {Accounting services Gauteng
Hey there! I've been reading your blog for a long time now and finally got the bravery to go ahead and give you a shout out from Houston Texas! Just wanted to tell you keep up the fantastic work!
Here is my page :: home decor
I was recommended this website by my cousin. I am not sure whether this post is written by him as no one else know such detailed about my trouble.
You are wonderful! Thanks!
Here is my blog post - hydraulic equipment
May I just say what a relief to find an individual who truly understands what they're discussing on the web. You certainly know how to bring an issue to light and make it important. More people ought to check this out and understand this side of the story. I was surprised you are not more popular since you certainly possess the gift.
Feel free to visit my website - click here
Thanks for a marvelous posting! I certainly enjoyed reading it, you are a great
author.I will always bookmark your blog and will
come back later in life. I want to encourage you to continue your great job, have a nice morning!
my web-site ... frontline vs advantage for dogs
It's perfect time to make some plans for the future and it is time to be happy. I've read this post and if I could I wish
to suggest you some interesting things or advice. Perhaps you can write next articles referring
to this article. I want to read even more things
about it!
Look into my blog post 1899 gold coins for sale
Undeniably believe that which you stated.
Your favorite reason appeared to be at the net the easiest
thing to keep in mind of. I say to you, I definitely get irked whilst other people consider worries that they just don't know about. You managed to hit the nail upon the highest and also outlined out the entire thing without having side-effects , other people can take a signal. Will likely be again to get more. Thanks
Here is my web blog ... weight dumbell sets
Great weblog right here! Additionally your web site lots up fast!
What host are you the use of? Can I get your associate link to your host?
I desire my website loaded up as fast as yours lol
My web page :: companion pet clinic portland
Hi there to every body, it's my first go to see of this weblog; this web site carries amazing and in fact fine stuff for readers.
Also visit my webpage nightclub flyer
Hello there! This is my first comment here so I just wanted to
give a quick shout out and say I genuinely enjoy reading your
blog posts. Can you recommend any other blogs/websites/forums that cover the same subjects?
Thank you!
Visit my page - phen375 australia
What's Happening i am new to this, I stumbled upon this I've discovered
It positively useful and it has aided me out loads.
I am hoping to give a contribution & assist different
customers like its aided me. Good job.
Look into my web blog: paleo recipes
Hello There. I discovered your weblog the use
of msn. This is a really well written article.
I'll make sure to bookmark it and return to learn more of your helpful information. Thank you for the post. I'll certainly comeback.
Also visit my web-site; hot rod art prints
Excellent blog here! Also your website loads up fast!
What web host are you using? Can I get your affiliate link to your host?
I wish my website loaded up as fast as yours
lol
Visit my weblog; pezzi di ricambio
Keep this going please, great job!
My page acquista ricambi
Currently it sounds like Wordpress is the top blogging
platform available right now. (from what I've read) Is that what you are using on your blog?
Also visit my web site - hot rods and custom cars for sale
Thanks in favor of sharing such a good opinion, article is fastidious, thats why i have read it entirely
Have a look at my weblog: goodwill online store
What i don't realize is actually how you are not actually much more smartly-appreciated than you may be right now. You're so intelligent.
You understand therefore significantly in the case of this matter, produced me in my opinion imagine it from
a lot of varied angles. Its like men and women are not interested except it's something to do with Girl gaga! Your individual stuffs outstanding. All the time take care of it up!
Feel free to surf to my homepage: wiki.jugendwerksreisen.de
each time i used to read smaller articles which also clear their
motive, and that is also happening with this post which I am reading at this place.
Check out my site :: faraday flashlights
Hi! I just wanted to ask if you ever have any issues with hackers?
My last blog (wordpress) was hacked and I ended up losing
months of hard work due to no backup. Do you have any methods to prevent hackers?
Also visit my web-site: osqa1.stacky.net
Hey just wanted to give you a brief heads up and let you know a few of the
images aren't loading properly. I'm not sure why but I think its a linking issue.
I've tried it in two different browsers and both show the same results.
Here is my web blog ... vegetables juice
I am regular visitor, how are you everybody?
This piece of writing posted at this web site is genuinely pleasant.
Feel free to surf to my site :: juice fast
If you are going for best contents like I do,
simply visit this site every day since it provides quality contents,
thanks
Also visit my blog post ... Wheatgrass Juicers
I rarely comment, but i did a few searching and wound up here "Butterworth Lowpass Filter Coefficients in C++".
And I actually do have 2 questions for you if it's allright. Could it be only me or does it seem like a few of these responses appear like they are written by brain dead folks? :-P And, if you are writing at other social sites, I would like to keep up with anything new you have to post. Would you make a list of the complete urls of all your public pages like your twitter feed, Facebook page or linkedin profile?
my homepage :: Escorts.Littlerocknews.Org
I do not even know how I ended up here, but I thought this post was
good. I do not know who you are but certainly you're going to a famous blogger if you aren't already ;) Cheers!
My blog; “eat your fruits and vegetables”. now
Hello there! I could have sworn I've visited this site before but after looking at some of the articles I realized it's new to me.
Anyhow, I'm certainly happy I came across it and I'll be bookmarking it and checking back regularly!
Look at my homepage: makeup bridal
It's going to be ending of mine day, however before ending I am reading this fantastic post to increase my knowledge.
my web site ... www.performancecompetence.com
Hi there just wanted to give you a brief heads up and let
you know a few of the images aren't loading correctly. I'm not sure why
but I think its a linking issue. I've tried it in two different internet browsers and both show the same results.
Here is my web site; phen375 buy
in your calculation for y[n], y[0] and y[1] are always equal.
I am successfully using this as a low-pass filter, but I wish you can modify the code for a Bandpass filter. Then it can do low-pass and high-pass functions.
I think you code has issue , the gain value is loop to MUL xv/yv. It should MUL once.
Follow code is from mkfilter/mkshape/gencode A.J. Fisher
#define NZEROS 2
#define NPOLES 2
#define GAIN 8.890472632e+03
static float xv[NZEROS+1], yv[NPOLES+1];
static void filterloop()
{ for (;;)
{ xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = next input value / GAIN;
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = (xv[0] + xv[2]) + 2 * xv[1]
+ ( -0.9702284757 * yv[0]) + ( 1.9697785558 * yv[1]);
next output value = yv[2];
}
}
Kommentar veröffentlichen