Main Archive Specials Wiki | FAQ Links Submit Forum


Type : 24-dB (4-pole) lowpass
References : Posted by Best Regards,Ove Karlsen

Notes :
There's really not much voodoo going on in the filter itself, it's a simple as possible:

pole1 = (in * frequency) + (pole1 * (1 - frequency));

Most of you can probably understand that math, it's very similar to how an analog condenser works.
Although, I did have to do some JuJu to add resonance to it.
While studing the other filters, I found that the feedback phase is very important to how the overall
resonance level will be, and so I made a dynamic feedback path, and constant Q approximation by manipulation
of the feedback phase.
A bonus with this filter, is that you can "overdrive" it... Try high input levels..

Code :
// Karlsen 24dB Filter by Ove Karlsen / Synergy-7 in the year 2003.
// b_f = frequency 0..1
// b_q = resonance 0..50
// b_in = input
// to do bandpass, subtract poles from eachother, highpass subtract with input.

float b_inSH = b_in // before the while statement.

while (b_oversample < 2) { //2x oversampling (@44.1khz)
float prevfp;
prevfp = b_fp;
if (prevfp > 1) {prevfp = 1;} // Q-limiter

b_fp = (b_fp * 0.418) + ((b_q * pole4) * 0.582); // dynamic feedback
float intfp;
intfp = (b_fp * 0.36) + (prevfp * 0.64); // feedback phase
b_in = b_inSH - intfp; // inverted feedback

pole1 = (b_in * b_f) + (pole1 * (1 - b_f)); // pole 1
if (pole1 > 1) {pole1 = 1;} else if (pole1 < -1) {pole1 = -1;} // pole 1 clipping
pole2 = (pole1 * b_f) + (pole2 * (1 - b_f)); // pole 2
pole3 = (pole2 * b_f) + (pole3 * (1 - b_f)); // pole 3
pole4 = (pole3 * b_f) + (pole4 * (1 - b_f)); // pole 4

lowpassout = b_in;


Added on : 08/08/03 by ove[ AT ]synergy-7[ DOT ]com
Comment :
Seems to be a slight typo in my code.
lowpassout = pole4; // ofcourse :)

Best Regards,
Ove Karlsen

Added on : 20/09/03 by matt at ahsodit dot com
Comment :
Hi Ove, we spoke once on the #AROS IRC channel... I'm trying to put this code into a filter object, but I'm wandering what datatype the input and output should be?

I'm processing my audio data in packets of 8000 signed words (16 bits) at a time. can I put one audio sample words into this function? Since it seems to require a floating point input!


Added on : 17/05/04 by ove_code[ AT ]ihsan-vst[ DOT ]com
Comment :
Hi Matt.

Yes, it does indeed need float inputs.

Best Regards,
Ove Karlsen.

Added on : 20/03/05 by unkargherth[ AT ]terra[ DOT ]es
Comment :
Can somebody explain exactly howto make the band Pass and high pass, i tried as explained and don't work exactly as expected

highpass = in  - pole4

make "some kind of highpass", but not as expected
cut frequency

and for band pass, how we substract the poles between them ?

pole4-pole3-pole2-pole1 ?
pole1-pole2-pole3-pole4 ?

Also, is there a way to get a Notch ?

Added on : 22/03/05 by Christian[ AT ]savioursofsoul[ DOT ]de
Comment :
Below you will find an object pascal version of the filter.




unit KarlsenUnit;


  TKarlsen = class
    fQ      : Single;
    fF1,fF  : Single;
    fFS     : Single;
    fTmp    : Double;
    fOS     : Byte;
    fPole   : Array[1..4] of Single;
    procedure SetFrequency(v:Single);
    procedure SetQ(v:Single);
    constructor Create;
    destructor Destroy; override;
    procedure Process(const I : Single; var L,B,N,H: Single);
    property Frequency: Single read fF write SetFrequency;
    property SampleRate: Single read fFS write fFS;
    property Q: Single read fQ write SetQ;
    property OverSample: Byte read fOS write fOS;


uses sysutils;

const kDenorm = 1.0e-24;

constructor TKarlsen.Create;

destructor TKarlsen.Destroy;

procedure TKarlsen.SetFrequency(v:Single);
if fFS<=0 then raise exception.create('Sample Rate Error!');
if v<>fF then
   fF1:=fF/fFs; // fF1 range from 0..1

procedure TKarlsen.SetQ(v:Single);
if v<>fQ then
   if v<0  then fQ:=0 else
   if v>50 then fQ:=50 else

procedure TKarlsen.Process(const I : Single; var L,B,N,H: Single);
var prevfp : Single;
    intfp  : Single;
    o      : Integer;
for o:=0 to fOS-1 do
   if (prevfp > 1) then prevfp:=1; // Q-limiter
   fTmp:=(fTmp*0.418)+((fQ*fPole[4])*0.582); // dynamic feedback
   intfp:=(fTmp*0.36)+(prevfp*0.64); // feedback phase
   fPole[1]:= (((I+kDenorm)-intfp) * fF1) + (fPole[1] * (1 - fF1));
   if (fPole[1] > 1)
    then fPole[1]:= 1
    else if fPole[1] < -1
          then fPole[1]:= -1;
   fPole[2]:=(fPole[1]*fF1)+(fPole[2]*(1-fF1)); // pole 2
   fPole[3]:=(fPole[2]*fF1)+(fPole[3]*(1-fF1)); // pole 3
   fPole[4]:=(fPole[3]*fF1)+(fPole[4]*(1-fF1)); // pole 4


Added on : 29/03/05 by unkargherth[ AT ]terras[ DOT ]es
Comment :
Thanks Christian!!

Anyway, i tried something similar and seems that what you call Notch is reallya Bandpass and the bandpass makes something really strange

Anyway i'm having  other problems with this filter too. It seems to cut  too Loow for low pass and too high for high pass. Also, resonance sets a peak far away from the cut frequency.And last but not least, the slope isn't 24 db/oct, realkly is much lesser, but not in a consistent way: sometimes is 6, sometimes 12, sometimes 20, etc

Any ideas ?

Added on : 20/07/05 by mail[ AT ]ihsan-dsp[ DOT ]com
Comment :
Your problem sounds a bit strange, maybe you should check your implementation.

Nice to see a pascal version too, Christian!

Although I really recommend one set a lower denormal threshold, maybe a 1/100, it really affects the sound of the filter. The best is probably tweaking that value in realtime to see what sounds best.
Also, doubles for the buffers.. :)

Very Best Regards,
Ove Karlsen

Added on : 20/09/05 by musicdsp[ AT ]dsparsons[ DOT ]co[ DOT ]uk
Comment :
Christian, shouldn't your code end:
//CWB posted

//DSP posted
H:=I-fPole[4]; //Surely pole 4 would give a 24dB/Oct HP, rather than the 6dB version posted
N:=I-fPole[4]-fPole[1]; //Inverse of BP

Any thoughts, anyone?


Added on : 23/09/05 by mail[ AT ]ihsan-dsp[ DOT ]com
Comment :
This filter was really written mostly to demonstrate the Q-limiter though, and also, to write it in the most computationally effiecent way.
Here is a little more featured version.
// Karlsen, Second Order SVF type filter.

// b_in1, b_in2 stereo input
// fvar01 cutoff
// fvar02 slope
// fvar03 mode
// fvar04 res
// fvar05 cutoff/res compensation

// inits, all doubles
//    b_noise = 19.1919191919191919191919191919191919191919;
//     filterbuffers = 0;

    b_noise = b_noise * b_noise;
    int i_noise = b_noise;
    b_noise = b_noise - i_noise;
    double b_lnoise = (b_noise - 0.5) * 2;
    double b_rnoise = ((1-b_noise) - 0.5) * 2;

    b_noise = b_noise + 19;

    b_lnoise = b_lnoise * 65536;
    b_rnoise = b_rnoise * 65536;
    if (b_lnoise > 1) {b_lnoise = 1;} else if (b_lnoise < -1) {b_lnoise = -1;}
    if (b_rnoise > 1) {b_rnoise = 1;} else if (b_rnoise < -1) {b_rnoise = -1;}

    b_lnoise = b_lnoise * 1e-24; // find optimal value
    b_rnoise = b_rnoise * 1e-24;

    b_in1 = b_in1 + (b_lnoise);  // denormal prevention (also doubling as dither and analog noise).
    b_in2 = b_in2 + (b_rnoise);

    float b_slope = (1-fvar2) + 0.5;
    float b_cut = ((fvar1    * fvar1) + ((fvar1 / (b_slope)) * (1 - fvar1))) / ((1 * fvar1) + ((1 / (b_slope)) * (1 - fvar1)));
    b_cut = b_cut*b_cut; // linearize this
    float b_res = fvar4 * 100;
    int i_kmode = fvar3 * 100;

    if (b_cut > 1) {b_cut = 1;}
    if (b_cut < 0) {b_cut = 0;}

    b_in1 = (b_in1 + b_lbuffb1);
    b_in2 = (b_in2 + b_lbuffb2);

    b_lbuf09 = ((b_in1    * b_cut) + ((b_lbuf09 / b_slope) * (1 - b_cut))) / ((1 * b_cut) + ((1 / b_slope) * (1 - b_cut)));
    b_lbuf10 = ((b_in2    * b_cut) + ((b_lbuf10 / b_slope) * (1 - b_cut))) / ((1 * b_cut) + ((1 / b_slope) * (1 - b_cut)));

    b_lbuf11 = ((b_lbuf09    * b_cut) + ((b_lbuf11 / b_slope) * (1 - b_cut))) / ((1 * b_cut) + ((1 / b_slope) * (1 - b_cut)));
    b_lbuf12 = ((b_lbuf10    * b_cut) + ((b_lbuf12 / b_slope) * (1 - b_cut))) / ((1 * b_cut) + ((1 / b_slope) * (1 - b_cut)));

    if (i_kmode == 0) { //lowpass
        b_in1 = b_lbuf11;
        b_in2 = b_lbuf12;
    else if (i_kmode == 1) { // bandpass
        b_in1 = b_lbuf09 - b_lbuf11;
        b_in2 = b_lbuf10 - b_lbuf12;
    else if (i_kmode == 2) { // highpass
        b_in1 = b_in1 - b_lbuf11;
        b_in2 = b_in2 - b_lbuf12;

    b_lbuffb1 = ((b_lbuf09 - b_lbuf11) * ((b_cut * fvar5) + 1)) * b_res;
    b_lbuffb2 = ((b_lbuf10 - b_lbuf12) * ((b_cut * fvar5) + 1)) * b_res;

    b_lbuffb1 = atan(b_lbuffb1);
    b_lbuffb2 = atan(b_lbuffb2);
Works really well with control signals, where you keep the cutoff at a constant level.
Also, a bit more useful with audio, if you linearize the cutoff.

Best Regards,
Ove Karlsen.

Added on : 13/10/05 by musicdsp[ AT ]dsparsons[ DOT ]co[ DOT ]uk
Comment :
I was looking at the b_cut assignment, and was going through looking
at optimising it and found this:

float b_cut = ((fvar1    * fvar1) + ((fvar1 / (b_slope)) * (1 - fvar1)))
/ ((1 * fvar1) + ((1 / (b_slope)) * (1 - fvar1)));

Rename for convenience and clarity

=> (co^2+(co(1-co)))

multiply numerator & denominator by sl to even things up

=> (sl*co^2+(co(1-co)))

expand brackets

=>  sl*co^2+co-co^2


=>  co(sl*co+1-co)

(sl*co+1-co) cancels out, leaving..

=> co

if I've got anything wrong here, please pipe up..


Added on : 13/10/05 by musicdsp[ AT ]dsparsons[ DOT ]co[ DOT ]uk
Comment :
(actually, typing the assigment into Excel reveals the same as my proof..)

Added on : 17/02/06 by mail[ AT ]ihsan-dsp[ DOT ]com
Comment :
Final version, Stenseth, 17. february, 2006.

// Fast differential amplifier approximation

    double b_inr = b_in * b_filterdrive;
    if (b_inr < 0) {b_inr = -b_inr;}
    double b_inrns = b_inr;
    if (b_inr > 1) {b_inr = 1;}
    double b_dax = b_inr - ((b_inr * b_inr) * 0.5);
    b_dax = b_dax - b_inr;
    b_inr = b_inr + b_dax;

    b_inr = b_inr * 0.24;

    if (b_inr > 1) {b_inr = 1;}
    b_dax = b_inr - ((b_inr * 0.33333333) * (b_inr * b_inr));
    b_dax = b_dax - b_inr;
    b_inr = b_inr + b_dax;

    b_inr = b_inr / 0.24;

    double b_mul = b_inrns / b_inr; // beware of zero
    b_sbuf1 = ((b_sbuf1 - (b_sbuf1 * 0.4300)) + (b_mul * 0.4300));

    b_mul = b_sbuf1 + ((b_mul - b_sbuf1) * 0.6910);
    b_in = b_in / b_mul;

// This method sounds the best here..
// About denormals, it does not seem to be much of an issue here, probably because I input the filters with oscillators, and not samples, or other, where the level may drop below the denormal threshold for extended periods of time. However, if you do, you probably want to quantize out the information below the threshold, in the buffers, and raise/lower the inputlevel before/after the filter. Adding low levels of noise may be effective aswell. This is described somewhere else on this site.

    double b_cutsc = pow(1024,b_cut) / 1024; // perfect tracking..

    b_fbuf1 = ((b_fbuf1 - (b_fbuf1 * b_cutsc)) + (b_in * b_cutsc));
    b_in = b_fbuf1;
    b_fbuf2 = ((b_fbuf2 - (b_fbuf2 * b_cutsc)) + (b_in * b_cutsc));
    b_in = b_fbuf2;
    b_fbuf3 = ((b_fbuf3 - (b_fbuf3 * b_cutsc)) + (b_in * b_cutsc));
    b_in = b_fbuf3;
    b_fbuf4 = ((b_fbuf4 - (b_fbuf4 * b_cutsc)) + (b_in * b_cutsc));
    b_in = b_fbuf4;

Soundwise, it's somewhere between a transistor ladder, and a diode ladder..

Ove Karlsen.
PS: I prefer IRL communication these days, so if you need to reach me, please dial my cellphone, +047 928 50 803.

Added on : 02/11/06 by read[ AT ]bw
Comment :
Another iteration, please delete all other posts than this.

Arif Ove Karlsen's 24dB Ladder Approximation, 3.nov 2007

As you may know, The traditional 4-pole Ladder found in vintage hardware synths,
had a particular sound. The nonlinearities inherent in the suboptimal components, often
added a particular flavour to the sound.
Digital does mathematical calculations much better than any analog solution, and therefore, when the filter was emulated by digital filter types, some of the character got lost.
I believe this mainly boils down to the resonance limiting occuring in the analog version.
Therefore I have written a very fast ladder approximation, not emulating any of what may seem neccesary, such as pole saturaion, which in turn results in nonlinear cutoff frequency, and loss of volume at lower cutoffs. However this can be implemented, if wanted, by putting the neccesary saturation functions inside the code. If you seek the true analog sound, you may want to do a full differential amplifier emulation aswell.
But - I believe in the end, you would end up wanting a perfect filter, with just the touch that makes it sound analog, resonance limiting.

So here it is, Karlsen Ladder, v4. A very resource effiecent ladder. Can furthermore be optimized with asm.

rez = pole4 * rezamount; if (rez > 1) {rez = 1;}
input = input - rez;
pole1 = pole1 + ((-pole1 + input) * cutoffreq);
pole2 = pole2 + ((-pole2 + pole1) * cutoffreq);
pole3 = pole3 + ((-pole3 + pole2) * cutoffreq);
pole4 = pole4 + ((-pole4 + pole3) * cutoffreq);
output = pole4;


I can be reached by email @ 1a2r4i54f5o5v2ek1a1r5ls6en@3ho2tm6ail1.c5o6m!no!nums

Added on : 08/03/07 by pissed[ AT ]off[ DOT ]com
Comment :
I modeled some instruments using this filter... everything was fine until... i tried to change sample rate.

(my implementation is 100% as Ove's)

This filter is good only if You wannt to use one sample rate.


Added on : 10/03/07 by whygivemyemail[ AT ]okIwill[ DOT ]com
Comment :
Samplerate? Do you mean cutoff frequency?

Added on : 12/03/07 by the[ AT ]same[ DOT ]as[ DOT ]above
Comment :
I mean sampling frequency. Everything is ok with only one SR eg. 44100. When You change it to eg. 192000 the filter gives completelly different cutoff frequency and resonance.

Added on : 21/06/13 by pleasee[ AT ]otherpost
Comment :
Please see

for the ultimate development of this filter.

Peace Be With You,
Ove Karlsen

Added on : 27/08/13 by mark1[ DOT ]br[ AT ]gmail[ DOT ]com
Comment :
Hi,Just browsing arnoud the net for forex trading system and came across your blog. I've been trying to add as much info as I can about  on my site. But must admit I get a bit confused... there's just some many sites, tips, information ... you name about  it's hard to know where to begin!I'm thinking of adding a forex trading system on my site, when I do, your all more that welcome to come a leave tips and help...Until then take care!Steward.

Added on : 28/08/13 by tlezybzn[ AT ]ivmbsbsw[ DOT ]com
Comment :
I with no reasonable doubt say that the info you <a href="">proedivd</a> above was right to the point as we all know it managed forex can be very challenging and thus we should applaus to those that put in wore to provide us with all needed ideals and infomation. My self i`m very thankfull. You can get more ideals and info from my website

Added on : 29/08/13 by senseiofwhatnot[ AT ]gmail[ DOT ]com
Comment :
File Handles:handle 1: console_mp.log       -91458 files in iwd files  - Game Initialization   -gamename: IW4gamedate: Feb  2 2010            We wnaetd to send a logging packet but we haven't connected to the LSP server yet, so we're dropping the packet.            Working directory: C:\MW2 FATALGamerProfile   Updating and possibly saving for controller #0.Dev: Exception on  aiW Auth 13.37 , overridden.Resolving resolved to heartbeat to master.mw2.irاÛÙجا ÙÛÙÙÙÙ ÙÛÚÛ ÙØ´ÙÙ ÙÙÛد٠ت٠server List ÙÙØ· Û´ تا Û¶ سرÙر ت٠ÙÛستÙ.از Û² تا Ø¢Û Ù¾Û Ø¯Ûگ٠استÙاد٠کرد٠Ùشد [url=]xwwiwp[/url] [link=]wkpttqawosd[/link]

Added on : 30/08/13 by bbcr[ DOT ]sp[ AT ]bbcr[ DOT ]com[ DOT ]br
Comment :
I just finished <a href="">reanidg</a> Along Came a Demon on my Kindle. I enjoyed your story very much and will buy your other books in this series. I don't remember how I have swerved into <a href="">reanidg</a> paranormal mysteries but I am enjoying more of them. It's interesting, I previously read a mystery with werewolves, witches, etc. as characters but didn't like it that much. I thought I may have been too old (I am 64) and made a note that these books were for Twilight-type people (the movie). So why I thoroughly enjoyed your book with a demon character is a mystery. I am also getting to understand the self-publishing industry and happily support that. I am a person from the US who is living in Cornwall for the next 3 years with my husband who works for the US govt. So I enjoyed <a href="">reanidg</a> your blog about England and pasties, sausage rolls, clotted cream, etc. Just want you to know how much I enjoyed your book. Cheers!

Added on : 07/09/13 by kefu[ AT ]huijibuy[ DOT ]com
Comment :
Thanks for this, NormaJean! I'm glad you enjoyed Along Came a Demon and dvoesicred not all paranormal books are about sparkly Twilight-type vampires, etc. I'm also pleased you support Indie authors, there are a lot of good ones out there.I love Cornwall and would happily live there, but I'd be fat as a pig, totally unable to resist all that Cornish cream, etc. I hope you enjoy your 3 years there.Cheers,Linda. [url=]gclysk[/url] [link=]aycafwvcq[/link]

Added on : 03/03/14 by 9mvt83dde9s[ AT ]gmail[ DOT ]com
Comment :
A Number Of variables influence the costs of automobile insurance policy. Some are unquestionably valid. Some, QuotesChimp consider, aren't. Conserving that discourse for later (notice site 12 3), the next concerns would be the variables insurance providers examine when they pinpoint the premium you are going to spend.

Add your own comment
Comments are displayed in fixed width, no HTML code allowed!


Are you human?

Site created and maintained by Bram
Graphic design by line.out | Server sponsered by fxpansion