second-order IIR filter coefficients

bertrandfraysse's icon

I implemented the last examples with Chebyshev response.

Firstly, it uses a second-order IIR filter, easy to implement with gen~

secondOrderIIR (x, a0, a1, a2, b1, b2)
{
    History x1, x2, y1, y2;
    y = a0 * x + a1 * x1 + a2 * x2 - b1 * y1 - b2 * y2;
    y2 = y1;
    y1 = y;
    x2 = x1;
    x1 = x;

    return (y);
}

Then it's possible to produce a wide range of filter types.
All we need is to give it the right coefficients to these feedback loops.
It's possible to cascade these filters to produce higher order.

The bandpass coefficients work great. The example is for 1dB ripple

chebychevBandPass (center, bandwidth)
{
ripple = 1.965267;
    bandfreq = PI * bandwidth / samplerate;
    // tan is slower
    var = cos (bandfreq) / sin (bandfreq);
    // to avoid calculate this sum more than one time
    var2 = ripple + var;
    scale = 2 * cos (TWOPI * center / samplerate);
    a0 = ripple / (var2);
    a1 = 0;
    a2 = -a0;
    b1 = -var * scale / var2;
    b2 = (var - ripple) / var2;

    return a0, a1, a2, b1, b2;
}

Then I tried the bandstop coefficients generator with no success, all it outputs is -10000...

chebychevBandStop (center, bandwidth)
{
    ripple = 1.965267;
    bandfreq = PI * bandwidth / samplerate;
    // tan is slower
    var = cos (bandfreq) / sin (bandfreq);
    // to avoid calculate this sum more than one time
    var2 = ripple + var;
    scale = 2 * cos (TWOPI * center / samplerate);
    a0 = ripple / (var2);
    a1 = -ripple * scale / var2;
    a2 = a0;
    b1 = -var * scale / var2;
    b2 = (ripple - var) / var2;

    return a0, a1, a2, b1, b2;
}

So, if anyone has the right coefficients for Band-stop, lowpass and highpass, I'd be grateful.

Here is a patch to listen to a fourth-order chebyshev band-pass filter.

Max Patch
Copy patch and select New From Clipboard in Max.

-

I did the same researches for FIR filters and found butterworth lowpass and highs coefficients.
I'm looking after inverse-chebyshev, elliptic, bessel coefficients too.

Here is a page on the advantages and disadvantages of all these types of filters
http://www.etc.tuiasi.ro/cin/Downloads/Filters/Filters.htm#Butt

Thank you everyone.

stkr's icon

hi @BERTRANDFRAYSSE

is there a reason you are attempting all this in gen~?

what you code here are just biquad sections, so in MSP you can achieve everything here with:

cascade~ & filterdesign (and filterdetail & plot~if you need to visualise).

admittedly it would be nice to have bessel and elliptic available (i have fr-ed this), but everything else is super easy with that combo.

there is a problem doing all this in gen~ - it is super expensive, there is really no point. the lowest resolution you can achieve the coefficients is at param rate (it looks like yours are even at audio rate at the moment), and it is not easy to make the necessary cascaded biquad optimisations in gen~ that can be done in C (cascade~).

if you really need these inside inline of some gen~ code you are writing, it is easier and more efficient to cascade with all memories written out to a Data() and passed back in in a for loop configuration, and do the coefficients in max schedular rate and pass in as params.

just some thoughts, hth.

bertrandfraysse's icon

the first thing is filterdesign doesn't work at audio rate.
The IIR filter seem not to be too CPU intensive, but the coefficients calculation is.
So, I can make the coefficients calculation to be operated only when the frequencies are varying if (change (freq)) {} to avoid calculation when the frequencies are not moving.
I try to build stuff inside of gen~ firstly to better understand how it's working, and to be able to generate feedback loops, and integrate it in other gen~ codes.

Ernest's icon

I just got interested in the same thing. I tried various ways to control gain in biquads and made a little patch with a dozen code examples, including drawing the frequency response from gen~. Maybe you find it interesting.

Max Patch
Copy patch and select New From Clipboard in Max.

Capture.jpg
jpg
bertrandfraysse's icon

This seems very nice, but the patch crashes max, even if audio is off.
I'm still using max 6.

Roman Thilenius's icon

chrashes max7, too. but it is still fun stuff

bertrandfraysse's icon

It crashes before even opening the patch. I can't even see what it is doing

Roman Thilenius's icon

for me it works, but freezes max 7.3 (windows 7) after a while

Ernest's icon

Yes, it requires Max 7.3.1. There are alot of changes to gen~. It does lock up if you chage the static filter type. with large P or Q values. which is to be expected. It's really just a demo of the functions. This is because , when you change the filter, there are still values in the delay blocks which, with the coefficients for a new filter, can create NaNs, or are expected to be zero in the new filter type. Static filters are not instended for state-variable designs. It is possible to clear the delay lines on state change, but the overhead is quite large compated to the filters themselves.

Ernest's icon

That' to say, it shouldn't crash if you choose a filter type, save it, and reopen it. It will restore the settings on last save at open, and if you don't change the filter type, it won't crash.

Roman Thilenius's icon

that is exspected? why that?

if a NaN can cause that the window can no longer be closed and the whole app locks up, then i dont want to know what happens when -inf occurs.

Ernest's icon

because biquads are static filters. Changing coefficients suddenly cause aberrations in the feedback loop which can cause the multiplications not to self adjust and the values increase or descrease until they generate nans.

I adjusted the second bandpass filter so its frequency response is in the same gain range as for the equivalent lowpass and highpass filters in the set.

Max Patch
Copy patch and select New From Clipboard in Max.