Page 1 of 1

Process nth order filter

PostPosted: Tue Apr 07, 2020 8:42 am
by juha_tp
Lets say one have a nth order (n>2) filter ... how to process it without breaking it to SOS?

Are there any ready to use implementations available (I checked quite a many examples but didn't find one (bypassed some asm listings there cause of I'm not good in reading asm code))?

Re: Process nth order filter

PostPosted: Tue Apr 07, 2020 5:36 pm
by martinvicanek
SOS means second order sections aka biquads, right?
You could use a direct form like

y = b0*x + b1*x1 + ... + bn*xn;
y = y - a1*y1 - a2*y2 - ... - an*yn;

xn = xn-1;
...
x1 = x;

yn = yn-1;
...
y1 = y;

However, in single precision rounding errors will quickly make it unstable even for moderate order n. That's why we moslty use biquads. ;)

A minor remark on why I broke the filter equation y = ... in two lines: Flowstone's code compiler has a limitation regarding the size of single line formulas it can handle. (It won`t throw an error if you exceed this limit).

Re: Process nth order filter

PostPosted: Wed Apr 08, 2020 6:26 am
by juha_tp
OK, yes, second order sections.

I found my own SM example for biquad case:

Code: Select all
monoin inL;
monoin inR;
monoout outL;
monoout outR;

float a0, a1, a2;
float b0, b1, b2;
float inL1, inL2, inR1, inR2;
float outL1, outL2, outR1, outR2;

a0= ...
a1= ...
a2= ...
b1= ...
b2= ...

// Proces left channel
outL = a0*inL + a1*inL1 + a2*inL2 - b1*outL1 - b2*outL2;

// Process right channel
outR = a0*inR + a1*inR1 + a2*inR2 - b1*outR1 - b2*outR2;

// save previous I/Os
outL2 = outL1;
outL1 = outL;
inL2 = inL1;
inL1 = inL;

outR2 = outR1;
outR1 = outR;
inR2 = inR1;
inR1 = inR;


so, extending that would then be the way to go.