# [music-dsp] Re: Revisiting C++ Filtering Classes

robert bristow-johnson rbj at audioimagination.com
Wed Jun 3 11:46:29 EDT 2009

```hi Vinnie,

i'm trying to understand what your "bottom line" is.

you want a create a class of IIR filters, right?  these filters are
limited to 2nd-order?  or are you trying to put together filters of
higher order?

you want to understand the math, right?  now, while it's no
substitute for taking a good class in what we used to call "Linear
System Theory" (but now i think the title "Signals and Systems" is
now more in vogue), some of this can be understood, but how deep do
you want to go?

do you understand what "s" is in the analog prototypes and why we
substitute s <- jw when we want to evaluate frequency response?

likewise, do you understand what "z" is in a digital filter and why
we substitute z <- exp(jw) when we want to evaluate frequency response?

so what we do on the jw axis (Re{s}=0) in analog filters is what we
do on the unit circle (|z|=1) for digital filters.  do you understand
why (or do you really need to know)?

so, to transform an analog prototype to a digital filter, we have to
map the imaginary axis to the unit circle and the proper mapping is
that exponential function:  z = exp(s/Fs) where Fs is the sampling
frequency.  so we invert the mapping to find out *what*, in terms of
z, we have to stick into the analog "s".  that inverse mapping is

s = Fs * ln(z)     ("ln" is the natural log.)

but we don't have functional blocks that accomplish ln(z).  we only
have negative powers of z which turn out to be delays of as many
samples as that power of z.

so someone (whoever invented the Bilinear Transform, and i dunno if
that is credited to anyone) decided to approximate that natural log
function by truncating this infinite series at the first term:

ln(x) = 2*(x-1)/(x+1) + 2/3*((x-1)/(x+1))^3 + 2/5*((x-1)/(x+1))
^5 + ...

so the BLT does this approximation:

s = Fs * ln(z) ~= 2*Fs*(z-1)/(z+1) = 2*Fs*(1 - (z^-1))/(1 + (z^-1))

what the BLT does is map the unit circle of the z-plane to the
imaginary axis of the s-plane just like the ln(z) function does
except that the BLT mapping maps a particular z on the unit circle to
a slightly different place on the jw axis on the s-plane than does
the ln(z) function.  this is then understood to be the frequency
warping of the BLT and you can fix it (compensate) at every
significant frequency that you have a control parameter for (just
scaling frequency in the analog domain).  for a simple LPF or HPF,
there is only one degree freedom that you can scale to compensate
frequency warping.  with an BPF there are two (the two bandedges, but
an easier way to look at it is to compensate the center frequency and
the bandwidth).

now, the point of writing this is, this scaling of s to compensate
the effect of frequency warping at the singular "significant
frequency" *and* this scaling with Fs that is explicit with the BLT
can be teamed up together into a single operation.  this is done at
the bottom of the Audio EQ Cookbook, which i might suggest you look
up to save you some work.

--

r b-j                  rbj at audioimagination.com

"Imagination is more important than knowledge."

```