[sdiy] Re: IIR and FIR

Magnus Danielson magnus at rubidium.dyndns.org
Fri Jun 6 16:36:24 CEST 2008


From: Scott Gravenhorst <music.maker at gte.net>
Subject: Re: [sdiy] Re: IIR and FIR
Date: Fri, 06 Jun 2008 06:47:19 -0700
Message-ID: <200806061347.m56DlJjr029869 at linux7.lan>

Scott,

> >Now, this is a bit problematic. Bilinear transformed filters (which have good
> >properties) tend to use arctan compensation. Doing that in realtime is
> >expensive. However, for higher sample rates the filter cut-off stays close to
> >0 and things can be approximated and behave fairly linear.
> >
> >If you map your integrators bilinearly you get for each integrator
> >
> >i1 = i0
> >i0 = i1 + i*T
> >o  = i0 + i1
> 
> I googled "bilinear transform", but I didn't see what you wrote above...  I
> read about the process a while back, but I intend to do more reading.  Where
> can I read about integrators transformed bilinearly to explain what you've
> done?

I personally fall back to the reference book, Rabiner and Gold "Theory and
Applications of Digital Signal Processing" (it was my first major book in
anything and I ordered it when in 9th grade and I still remember it took
2 months and 3 weeks to get it, and I was quite impressed that they had to
bring it over from the USA as it was out of stock in Europe).

The bilinear transform works it magic by replacing the LaPlace variable s with
the discrete time variant z (of the Z-transform fame, which is the LaPlace
transform in discrete time). That way you can convert a filter in the LaPlace
domain into the z-domain. The magic transformation is:

    2 1 - z^-1
s = - --------
    T 1 + z^-1

Where 2/T represents the sample frequency where T is the sample time.

Now, the LaPlace domain of an integrator is

       1
H(s) = -
       s

transforming it becomes

       T 1 + z^-1
H(z) = - --------
       2 1 - z^-1

The z^-1 form is very handy, as this means "delay one sample".

It is trivial to show that it is equalent to

i1 = i0
i0 = i1 + i*T
o  = i0 + i1

except for a scaling error of 2.

Since in a SVF the integrators are the only pole/zero material, bilinear
transforming these are enought.

There is a "problem" with bilinear transforming, it distorts the dimensioned
frequency scale. By scaling the filter components properly by replacing the
linear omega frequency with the Omega defined as

        2     omega*T
Omega = - tan(-------)
        T        2

You can correct it. However, as omega*T/2 comes small (as T gets smaller with
rising sampling frequency) you can approximate tan(x) = x and you get

        2 omega*T
Omega = - ------- = omega
        T    2

i.e. it turns out trivial as I hinted before.

So really, this is all the magic really.

> >where i is the input, o the output and T is the sample time. i0 and i1 is the
> >integrator state variables.
> >
> >Converting a normal SVF into this form is trivial and only a slight variation
> >of what you already have around:
> >
> >http://www.fpga.synth.net/pmwiki/pmwiki.php?n=FPGASynth.SVF
> >
> >However, you can approximate the sin such that f = 2 pi Fc / Fs. I think you
> >are getting my point... the real trick is the sample rate and the handy
> >reductions it allows you to do.
> 
> I actually just ignored the sin() bit because my corner frequencies would be low enough
> that the sine function output would be fairly linear anyway, amounting to mostly a
> constant for the calculation.  I used an arbitrary "faux frequency" value instead of doing
> the full calculation and control the corner frequency with the raw values from the
> modulator (an EG) instead.  It works, but is uncalibrated, a fact that doesn't matter in
> my application.

Only if used for tuned oscillator uses I would care.

> I'm curious now, my choice of using an SVF wasn't based on superior knowledge of filters,
> I tried it because I like the ones I've heard in the analog domain.  Did I just get
> extremely lucky (I did know about the sample rate thing ahead of doing it)? - because the
> thing seems to work _very_ well.  

You are indeed very lucky. Other filters would be much harder to convert and
your naive integrator mapping can work well under the conditions you gave it.

SVF is in this sense ideal for experiments like this. There is a theoretical
neatness to them that can take some time to fully apprechiate. Having said
that, it doesn't mean other filters are meaningless, they might have other
benefits.

> I would, however, like to see what other digital filter topologies can be used and compare
> their "effort coefficient", something Veronica eluded to in her last post.

Veronica actually made a very important point of another kind. In any form of
filters using feedback you run into troubles where non-linearites may form an
oscillator. You can have oscillations occuring down there in the noise. Smal
adjustments in the coefficients may break those oscillations quiet.

Another aspect is that noise-shaping before reducing the bits is also part of
the trick-of-trades that reduces the problems of a finit number of bits.
Doing stuff in floating points numers or wide enought bit-path is among the
critical issues.

> For music, filters that can be swept or modulated are useful, especially if
> resonance is also numerically controllable.  So there are two major control
> requirements I place on filters used in the audio path for timbre control -
> frequency control and resonance control.  SVF is a good one, but it likes a
> high sample rate.  High sample rate isn't always possible,
> especially as the number of synth features increases.

Well, this is where you run into design issues. I'd rather have a "clean"
system with a thad too low of features than a formidable cascade of less well
behaving things.

Cheers,
Magnus



More information about the Synth-diy mailing list