need code for a lowpass filter

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 20, 2006 at 19:50

can anyone post a reply with code for a cookbook lowpass filter with resonance/q, ive got one from www.buzzmachines.com but i couldnt get
the resonance working, i kept at it for ages and theres no errors from what
i copied, its funny, the cutoff worked but as soon as i added resonance
it goes into a sick distortion sweep, which i thought was cool at first but
its not working, i need resonance cause im making a 303 clone.
even to point me to a decent sound developing site would be good, i got lost googling looking at analogue filters couldnt find anything digital.
ive got code for an iir filter and fir filter, but they dont have resonance so
they are pretty much useless to me… my last program used an fir filter
and a tight bandpass on top for resonance, which sounded ok, but it screws
up towards the bassend. i need resonance.
thankyou.
i know a little bit, like i know you have to keep memory for the ins and outs, but
beyond that im without knowledge.

17 Replies

Please log in or register to post a reply.

B6c7df5127183be9b43032c9d834fc49
0
Moulinex 101 Sep 20, 2006 at 20:50

Don’t know if you will find exactly what you need there but here where I use to go:

http://www.musicdsp.com/

Moulinex

C24eb7e6aaefba78b94c831ddc7b4d0b
0
donBerto 101 Sep 20, 2006 at 20:51

could you show us the code that you do have? also, if you do, please use the code tags (if you didn’t already know ;) )

A9102969e779768e6f0b8cb87e864c94
0
dave_ 101 Sep 21, 2006 at 09:40

Have a look at winamp’s DSP plugin you can see the filter alogrithms that it uses and its good to play around with for quick tests (ie no compiling).

What exactly do you mean by resonance? I’ve not come across that term in dsp.

I suspect you just need to properly design a filter with feedback

And a quick google search confirms my suspicions: How do i implement resonance in a filter?

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 25, 2006 at 13:20

maybe i should have googled for longer…. sorry dave :)
dont you know what resonance is, it accents the cutoff freq, its
awesome for techno.
i figured out my problem.
the filter i had was working, it was just wrapping, buzz must have an
automatic clipper, so when i used it i didnt clip it and was getting short
wrap around distortion, so it works anyway… i always post to early.
heres the code if anyone else wants to use it, it rings really nicely, with
a bit of distortion the resonance really wirrs.

SETTING UP THE TAPS
its a 2nd order iir filter.

                        float alpha, omega, sn, cs;
                        float a0, a1, a2, b0, b1, b2;

                        omega = 2.0f * PI * CUTOFF/SAMPSPERSEC;
                        sn = sin (omega); cs = cos (omega);
                        alpha = sn / RESONANCE;
                        b0 = (1.0f - cs) / 2.0f;
                        b1 = 1.0f - cs;
                        b2 = (1.0f - cs) / 2.0f;
                        a0 = 1.0f + alpha;
                        a1 = -2.0f * cs;
                        a2 = 1.0f - alpha;
                        filtCoefTab[0] = b0/a0;
                        filtCoefTab[1] = b1/a0;
                        filtCoefTab[2] = b2/a0;
                        filtCoefTab[3] = -a1/a0;
                        filtCoefTab[4] = -a2/a0;

APPLYING TAPS TO SAMPLES, (x is the in memory, y is the infinite impulse memory)
            temp_y = filtCoefTab[0] * IN +
                        filtCoefTab[1] * x1 +
                        filtCoefTab[2] * x2 +
                        filtCoefTab[3] * y1 +
                        filtCoefTab[4] * y2;
            y2 = y1; y1 = temp_y; x2 = x1; x1 = IN ; OUT = temp_y;

dont forget to clip it, or itll wrap right around a signed short… that probably
goes for any filter with Q, they boost the area way too much for a short.

ill visit all the sites… i really need to read more before i continue.

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 25, 2006 at 14:28

If you have code for an IIR filter (which should be enough for your needs), then take your transfer function in Laplace domain (which you probably have) and replace all s by (2/Ts)*(1 - z\^-1)/(1 + z\^-1) with Ts = 1/fs being the sampling period.

You have enough with that information?

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 25, 2006 at 15:51

that gives resonance to a filter?

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 25, 2006 at 17:16

It doesn’t give resonance to a filter, but it allows you to translate an analog filter (given by a transfer function in Laplace domain) to a digital IIR filter (given in Z domain).

First: the analog world …

For a low pass filter with resonance peak, you need a second order filter. Let’s do a low pass RLC filter

*----[R]----[sL]----*------*
                    |
Vin               [1/sC]    Vout
                    |
*-------------------*------*

Not the best ascii art, and not even genuine electrical symbols, but you get the idea. The filter consists of a resistor R, an inductor L and a capacitor C.

Pretend all the components are just resistors, and solve for Vout:

Vout = Vin * (1/sC) / (R + sL + 1/sC)

After a bit of rearrangement, we get our transfer function in laplace domain:

H(s) = Vout/Vin = 1 / (1 + sRC + s\^2 LC)

The cutoff frequency is w_c = 1 / sqrt(LC). Well, actually, w_c is not really a frequency measured in Hertz but in radians per second. If you have your cutoff frequency f_c measured in Hertz, you need to multiply it by 2pi: w_c = 2pi * f_c

The Q factor is given by sqrt(L / C) / R.

Given this, we can rewrite the transfer function to:

H(s) = 1 / (1 + s / (Q*w_c) + s\^2 / w_c\^2)

So, with this you can already play: use w_c to set the cutoff frequency and use a high Q (Q > 1) to get a resonance peak. Use Q = sqrt(2) to have a 2nd order butterworth filter.

Now you have to translate this to Z domain by substituting s by (2/T_s)*(1 - z\^-1)/(1 + z\^-1)

After some rearrangments, you hopefully get:

H(z) = (b_0 + b_1 * z\^-1 + b_2 * z\^-2) / (a_0 + a_1 * z\^-1 + a_2 * z\^-2)

with the following taps (best to check, cause i’m not 100% sure, but it looks ok):

b_0 = 1
b_1 = 2
b_2 = 1

and

a_0 = 1 + 2 / (T_s * Q * w_c) + 4 / (T_s * w_c)\^2
a_1 = 2 * (1 - 4 / (T_s * w_c)\^2)
a_2 = 1 - 2 / (T_s * Q * w_c) + 4 / (T_s * w_c)\^2

This, you should be able to put in your digital IIR filter (possibly your IIR filter requires a_0 to be equal to 1, but that’s easily done by dividing all taps by the a_0 you find above).

Using this approach, you can translate any linear passive analog filter to taps for your IIR digital filter.

Cheers,
Bramz

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 25, 2006 at 17:25

thanks for the speed lesson, i understand.
you convert the analog circuit to math equations.
i definitely know a little more now… any filter ay.
maths is magic. shit so thats how you make coefficients.
its like going in backwards… I GET IT!
if only i knew algebra was so useful back in year 8 when i flunked it.
still a bit wishy washy tho… but thanks for explaining how
taps work.
substituting s makes it possible to make taps.
so you use the transfer function combined with the z domain
to make the taps. im not quite sure how it works, but thanks anyway.

6aa952514ff4e5439df1e9e6d337b864
0
roel 101 Sep 25, 2006 at 21:26

Well, it is really impossible to understand z-transforms and laplace transforms without knowing complex function theory. You can use it as a tool without understanding it though, not a problem imho, it is quite hard stuff. Anyway, you can also intuitively see low pass filtering as blurring, like you blur a picture, only 1D this time. Intuition is good sometimes. You can even bruteforce make a bode plot (to get its characteristics) by feeding a sine-function into your software filter and checking the amplitude and phaseshift of your output.

By the way bramz, did you study electrical engineering / physics?

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 25, 2006 at 22:39

maths is so awesome, even tho im useless at it.

i dont gather how you get
H(z) = (b_0 + b_1 * z\^-1 + b_2 * z\^-2) / (a_0 + a_1 * z\^-1 + a_2 * z\^-2)

from substituting (2/T_s)*(1 - z\^-1)/(1 + z\^-1) for s in

H(s) = 1 / (1 + s / (Q*w_c) + s\^2 / w_c\^2) which is the transfer equation
which you insanely gathered from the analogue circuitry.

then somehow using knowledge i dont have getting the all important
b_0 = 1
b_1 = 2
b_2 = 1
and
a_0 = 1 + 2 / (T_s * Q * w_c) + 4 / (T_s * w_c)\^2
a_1 = 2 * (1 - 4 / (T_s * w_c)\^2)
a_2 = 1 - 2 / (T_s * Q * w_c) + 4 / (T_s * w_c)\^2

which is most amazingly simple coefficients applied to each sample
offsetting -1 to -2 from the current sample.

but maybe one day ill understand…

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 26, 2006 at 09:20

@roel

By the way bramz, did you study electrical engineering / physics?

Yes, I did EE, though it’s been a while so it’s a bit rusty =)

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 26, 2006 at 14:20

H(z) = (b_0 + b_1 * z\^-1 + b_2 * z\^-2) / (a_0 + a_1 * z\^-1 + a_2 * z\^-2) is just the general form of the IIR, you have to fill in all those parameters of course.

To get from H(s) to H(z) is simply by substituting s by that (2/T_s)*(1 - z\^-1)/(1 + z\^-1). But you get a big fraction with more fractions in the numerator and denominator, so that’s not nice. You have to simplify it by multiplying numerator and denominator by (1+z\^-1)\^2 and simplify them until you get a single fraction of simply polynomials. Then you group the polynomials for z\^-2, z\^-1 and everything else, and you get the parameters from H(z).

This transformation is actually pretty basic algebra. It’s all about simplifying polynomials and fractions … i’ts a bit tedious though ;)

6aa952514ff4e5439df1e9e6d337b864
0
roel 101 Sep 26, 2006 at 16:21

@bramz

Yes, I did EE, though it’s been a while so it’s a bit rusty =)

Not bad at all :) I only had this black magic stuff a few years ago, but I barely remind it. I only remember a few buzzwords and the name Cauchy. Brrrr.

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 26, 2006 at 17:21

@roel

Not bad at all :) I only had this black magic stuff a few years ago, but I barely remind it. I only remember a few buzzwords and the name Cauchy. Brrrr.

A few months ago I spend an entire day to remember me this stuff =) I needed to implement a few digital filters that were specified as analog circuits … wikipedia can be your friend at moments like that …

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 27, 2006 at 05:48

oh right. thanks man, thanks for everything.

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 104 Sep 27, 2006 at 08:30

i stumbled apon

http://www.musicdsp.org/archive.php?classid=3#118

and found three iir low pass and hi pass filters one pole one zero
one zero and one pole by “bram” did you write em?
theres a notch there too, and im making a 7 band eq with them.
so i might put you in the credits for my music program. :)

25bbd22b0b17f557748f601922880554
0
bramz 101 Sep 28, 2006 at 00:00

No, I did not post those, there must be another Bram on this planet =)

AFAIK, a notch filter is a band stop filter with a very narrow stop band (high Q factor). So, i’m not sure how you’re going to do a equalizer with that =)

You can make a notch filter with a RLC circuit, similar to the low pass filter. It looks like this:

*----[R]----*------*
             |
            [sL]
Vin          |     Vout
           [1/sC]  
             |
 *-----------*------*

The transfer function in Laplace domain is the following:

H(s) = Vout/Vin = (sL + 1/sC) / (R + sL + 1/sC)

See if you can get taps for your IIR filter from this =)

1) multiply numerator and denominator by sC to simplify the function a bit.
2) use w_c = 1/sqrt(LC) and Q = sqrt(L/C)/R to get a function that depends directly on w_c and Q. Notice that w_c and Q are the same as above.
3) replace s by that funky z\^-1 stuff.
4) Simplify so that you keep a nice fraction of two simple polynomials in z\^-1

Cheers,
Bramz