Here's some code and a Desmos graph. The blue line represents our desired analog filter, the other one is the approximation.
https://www.desmos.com/calculator/xhqqysafgx (https://www.desmos.com/calculator/xhqqysafgx)
Code: Select all (#)
Coefficient calculations:
float w = 2*pi * freq / samplerate;
float ww = w*w;
float asd = (w - 2)*(w + 2);
float wq2 = 2*w/q;
float alpha = sqrt(asd*asd + wq2*wq2);
float a = 0.5 * (ww - alpha);
float b = 0.5 * (ww + alpha);
float c = 0.5 * (b - sqrt((b - 2)*(b + 2)));
float a1 = a*c;
float a2 = c*c;
float b0 = 1 + a1 + a2;
float b1 = 0, b2 = 0;
if (false) //bandpass
{
b0 = b0/w;
b1 = -b0;
b2 = 0;
}
else if (false) //hp
{
b0 = b0/(w*w);
b1 = -2*b0;
b2 = b0;
}
Somewhere in the processing loop:
float x = in[chan][i];
float tmp = x*b0 + x1*b1 + x2*b2 - a1*y1 - a2*y2;
x2 = x1; x1 = x; y2 = y1; y1 = tmp;
out[chan][i] = tmp;