Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: AudioFilterStateVariable: why is the code written twice?

  1. #1
    Junior Member
    Join Date
    Oct 2020
    Posts
    13

    AudioFilterStateVariable: why is the code written twice?

    I've been looking through the code for the AudioFilterStateVariable (...\Arduino\hardware\teensy\avr\libraries\Audio\f ilter_variable.cpp), trying to understand the filter better.

    the part that does the state variable filter ("Chamberlin Filter") looks like it has the filter coded twice (sort of).

    // now do the state variable filter as normal, using fmult
    input = (*in++) << 12;
    lowpass = lowpass + MULT(fmult, bandpass);
    highpass = ((input + inputprev)>>1) - lowpass - MULT(damp, bandpass);
    inputprev = input;
    bandpass = bandpass + MULT(fmult, highpass);
    lowpasstmp = lowpass;
    bandpasstmp = bandpass;
    highpasstmp = highpass;
    lowpass = lowpass + MULT(fmult, bandpass);
    highpass = input - lowpass - MULT(damp, bandpass);
    bandpass = bandpass + MULT(fmult, highpass);
    lowpasstmp = signed_saturate_rshift(lowpass+lowpasstmp, 16, 13);
    bandpasstmp = signed_saturate_rshift(bandpass+bandpasstmp, 16, 13);
    highpasstmp = signed_saturate_rshift(highpass+highpasstmp, 16, 13);
    *lp++ = lowpasstmp;
    *bp++ = bandpasstmp;
    *hp++ = highpasstmp;


    is was expecting something more like...

    input = (*in++) << 12;
    lowpass = lowpass_delayed + MULT(fmult, bandpass_delayed);
    highpass = input - lowpass - MULT(damp, bandpass_delayed);
    bandpass = bandpass_delayd + MULT(fmult, highpass);

    bandpass_delayed = bandpass;
    lowpass_delayed = lowpass;

    *lp++ = signed_saturate_rshift(lowpass, 16, 12);
    *bp++ = signed_saturate_rshift(bandpass, 16, 12);
    *hp++ = signed_saturate_rshift(highpass, 16, 12);



    It looks like there is a two sample box car filter on the input ( ((input + inputprev)>>1) ) and an averaging of the two "instances" of the filtering ( signed_saturate_rshift(lowpass+lowpasstmp, 16, 13) ).

    Can anyone tell me the reasoning behind the design?

  2. #2
    Junior Member
    Join Date
    Oct 2020
    Posts
    13
    Ok. I found some explanations here...

    https://www.musicdsp.org/en/latest/F...sampled-stable

    the extra code boils down to trying to make the filter more stable.

  3. #3
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,257
    Its because its 2-times oversampled.

  4. #4
    Junior Member
    Join Date
    Oct 2020
    Posts
    13
    Hi MarkT,
    I did finally see that it was 2x over sampled, but I figured it would just adjust the parameters accordingly and run the simpler code. But the musicdsp.org site had some more explanaitions.
    Thanks for the response.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,090
    Changing to 3X oversample is on my todo list....


    Quote Originally Posted by tigger View Post
    Can anyone tell me the reasoning behind the design?
    The filter's feedback loop becomes unstable when the configured corner frequency is too high (relative to the sample rate), particularly when combined with low resonance. Oversampling by 2X guarantees we use only the bottom half of the range, which makes most applications stable.

  6. #6
    Junior Member
    Join Date
    Oct 2020
    Posts
    13
    Quote Originally Posted by PaulStoffregen View Post
    Changing to 3X oversample is on my todo list....
    Thanks Paul. Do you think this will help with the harsh noise that happens with this filter?
    See the following thread...
    https://forum.pjrc.com/threads/67358...unwanted-noise

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •