Paul Kellet Resonant Filter: freq from/to hz?

I was working/studing a basic Resonant Filter, using the Paul Kellet one as test case: https://www.musicdsp.org/en/latest/Filters/29-resonant-filter.html

The freq is feed in normalized value 0..1.

So the question: how can I convert these values into hz? Getting the mapping function from/to normalized/hz?

I Guess 0.14 is 1000hz, and probably the upper side (max) is around 6khz, but I'd like somethings concrete in math.

Thanks

• I'm working on this. One thing that makes this laborious is that the appearance of buf0 in the line that defines buf1 isn't the buf0 from the previous sample. Commented Jul 4, 2023 at 21:18
• From the code f = 2.0*sin(pi*freq/samplerate); Does that answer your question ? Commented Jul 5, 2023 at 12:27
• @Hilmar , I am not sure that this formula relating f to the true resonant frequency (the angle of the poles) or the apparent resonant frequency (the frequency of maximum gain) is better than an approximation. Commented Jul 5, 2023 at 21:48

As is standard, it’s probably normalized by nyquist, a.k.a $$f_s/2$$ where $$f_s$$ is the sampling rate.

$$f_{norm} = 2f_{Hz}/f_s$$

EDIT: Robert brought up that this may not be the case in the comments, and this answer will be amended in case something fishier is going on.

• If you see a DSP-ish application that normalizes frequency between 0 and 1, then it'll either be normalized from 0Hz to Nyquist (i.e., sampling/2), or 0Hz to sampling -- just to keep you on your toes. Very seldom it'll be normalized to something else again, because it made sense at the time. It's best to start by digging through the documentation, although for a well-known app, asking here isn't a bad plan B. Commented Jul 4, 2023 at 21:09
• But I am not sure that the f parameter in the code is directly proportional to the resonant frequency. It might be a different function. We gotta come up with the transfer function and then look at the denominator coefficients. Commented Jul 4, 2023 at 21:19
• @robertbristow-johnson Yeah, to be completely honest I didn't spend too much time on it, as it's late where I am. I'll give it a shot tomorrow. In the meantime, if you find something please write your answer and I'll gladly delete mine ;)
– Jdip
Commented Jul 4, 2023 at 21:28

I am not certain, but I think the transfer function is:

$$H(z) = \frac{b_0}{a_0 + a_1 z^{-1} + a_2 z^{-2}}$$

Where \begin{align} b_0 &= f^2 \\ a_0 &= 1 \\ a_1 &= -2 + (2-g_\mathrm{fb})f-g_\mathrm{fb}f^2 \\ a_2 &= \big(1-(1-g_\mathrm{fb})f\big)(1-f) \end{align}

and $$f=$$f and $$g_\mathrm{fb}=$$fb in the code.

Okay the Cookbook (after normalization of $$a_0$$) has for the denominator (where the poles are):

\begin{align} a_0 &= 1 \\ \\ a_1 &= -2 \frac{ \cos(\omega_0)}{1 + \sin(\omega_0)/(2Q)} \\ \\ a_2 &= \frac{1 - \sin(\omega_0)/(2Q)}{1 + \sin(\omega_0)/(2Q)} \end{align}

Somehow we gotta make one look like the other to get an expression for $$\omega_0$$ and for $$Q$$. I remember doing this for Hal Chamberlin's SVF and it was a mess. I think I have to assume that $$\omega_0 \ll \pi$$ and that $$Q>1$$.

• Thanks for the reply. So, if fb depends on res, and f depends on fp, are you saying that change res will change freq/cutoff? Commented Jul 6, 2023 at 5:46
• I suspect that is true. I gotta fiddle with this a little more to get a result that is consistent with a basic biquad that has a resonant frequency and Q parameter. Commented Jul 6, 2023 at 14:29
• Before you do that Robert, are you sure you have the correct transfer function? I had slightly different coefficients for the denominator…
– Jdip
Commented Jul 6, 2023 at 15:55
• I might have it wrong. I have done it twice and gotten different answers, but I thought my second attempt was more careful Commented Jul 6, 2023 at 16:10
• I've implemented it on C++, using freq in the range [0,1]; but, once set a fixed freq, changing the res param doesn't "move" the freq, watching the signal (white noise input) throught a spectrum. So, not really sure about this :( Have you investigate more? Commented Jul 12, 2023 at 14:11