[reson~] : a scientific explanation?

lowfilter's icon

Hi there!

I'm having an issue with the [reson~] filter when I want to get a bit more precise in terms of sciences.

The documentation gives us this information:

y[n] = g*(x[n] - r*x[n-2]) - c1*y[n-1] - c2*y[n-2]
with r, c1 and c2 calculated from Q and central frequency.

I was wondering how these parameters are calculated, exactly, and why?

I think that r is calculated so the amplitude of the output signal (if a white noise is filtered, for example) stays constant even when the center frequency is close to 0 or Fs/2, but I struggle to find how this is calculated.

Moreover, I think that g is also calculated to let this amplitude constant all over the frequency range, and this seems to be calculated in quite a complicated way too.

The patcher I have attached shows this behaviour.

By comparing the z transfer function of the equation above with the usual bandpass filter transfer function, I end up with this conclusion:

c1 = (2 * Q * w0^2 * Ts^2 - 8*Q) / (Q * w0^2 * Ts^2 + 2 * w0 * Ts + 4*Q)

c2 = (Q * w0^2 * Ts^2 - 2 * w0 * Ts + 4*Q) / (Q * w0^2 * Ts^2 + 2 * w0 * Ts + 4*Q)

with w0 = (2 / Ts) * Atan(pi * center_frequency * Ts)

Maybe it would be possible to get the [reson~] source code somewhere? If not, could anyone give me a bit more information about how these parameters are calculated?

Thanks in advance!

TEST-RESON.maxpat
Max Patch
lowfilter's icon

and I was also wondering what is the frequency range used to calculate Q. Is it at -3dB, -6dB, or anything else?

Timothy Place's icon

The perform method basically boils down to this:

yn = gainscale * (xn - r * xm2) + c1 * ym1 + c2 * ym2;

And the coefficients are calculated like this:

bw = cf * x->r_1overq;
x->r_r = r = exp(-(x->r_2pioversr * bw));
x->r_scale = 1 - r;
x->r_c1 = 2. * r * cos(cf * x->r_2pioversr);
x->r_c2 = - (r * r);
x->r_cf = cf;

HTH

lowfilter's icon

ok!

Thank you very much, that helps a lot!

Liofeu's icon

Do you mean

yn = gain * scale * (xn - r * xm2) + c1 * ym1 + c2 * ym2;

and not

yn = gainscale * (xn - r * xm2) + c1 * ym1 + c2 * ym2; ?

where gain is the second inlet of the reson~object ?

thanks