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

Thread: First Order Filters

  1. #1
    Junior Member
    Join Date
    Sep 2018
    Location
    Newberg, OR
    Posts
    3

    First Order Filters

    I've been experimenting with first order filters for a bass preamp. I've been able to get a Low Pass filter working just fine by calculating the coefficients with this code:

    Code:
    // --------------------------------------
    // Calculate first-order LPF coefficients
    
    double coefficients[5]= {0,0,0,0,0};
    
    void calcCoefficients(float freq){
      double k = exp(-2 * PI * freq / AUDIO_SAMPLE_RATE);
      coefficients[0] = 1-k; coefficients[3] = -k;
    }
    I spent a long time trying to get a first order High Pass filter to work using this same structure, but was not successful. According to the references I looked at it should just be a matter of changing coefficients[3] from "-k" to "k" and coefficients[0] to "1 - abs(k)." And apparently there's a need to "invert the spectrum" by changing, "freq /AUDIO_SAMPLE_RATE" to "0.5 - (freq / AUDIO_SAMPLE_RATE)." But nothing I tried seemed to work.

    However, I WAS able to implement a fine first order High Pass filter by simply subtracting the LPF output from its input signal, using a Mixer object! So my current needs for this project are satisfied

    But my question is, "Was I doing something wrong in my implementation of a High Pass filter or did I just run up against numerical precision issues?" I was using the standard 44.1KHz sample rate with a cutoff frequency in 2KHz range.

    Seems like this should have been easy and just wondering if I was missing something!

    Thanks,
    John

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,153
    64 bit double should have plenty of numerical precision for this filter.

    If you're using an AVR chip, double is actually only 32 bits, with 23 used for the mantissa part. That might not be enough for the coefficients.

  3. #3
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,820
    I know, you have a solution to your problem, but a 1st order high-pass filter (6dB/Octave) is easily implemented by taking the difference between two consecutive samples
    Code:
    y[n]=x[n]-x[n-1];

  4. #4
    Junior Member
    Join Date
    Sep 2018
    Location
    Newberg, OR
    Posts
    3
    Apparently there are lots of ways to calculate coefficients for digital filters!

    I found C code examples for a pair of first order filters (thanks Google!) that also seem to be working fine. I'm running these on a Teensy 3.6 in the range of 100Hz - 2kHz.

    Code:
    double coefficients[5]= {0,0,0,0,0};
    
    // Calulate first-order LPF coefficients
    void calcCoefficients_LPF(float freq){
      float RC = 1.0/(2*PI*freq);
      float dt = 1.0/AUDIO_SAMPLE_RATE;
      float alpha = dt/(RC+dt);
    
      double b0 = -alpha;
      double a1 = alpha-1;
    
      coefficients[0] = b0; 
      coefficients[3] = a1;
    }
    
    // Calulate first-order HPF coefficients
    void calcCoefficients_HPF(float freq){
      float RC = 1.0/(2*PI*freq);
      float dt = 1.0/AUDIO_SAMPLE_RATE;
      float alpha = RC/(RC+dt);
    
      double b0 = -alpha;
      double b1 =  alpha;
      double a1 = -alpha;
    
      coefficients[0] = b0; 
      coefficients[1] = b1; 
      coefficients[3] = a1;
    }

    Interesting (to me anyway) that this approach don't use an exponential function -- just add/subtract/multiply/divide...

  5. #5
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    302
    Hi!

    I am a little confused why you use the biquad filters (2nd order) as first order filters. Could you explain that? Maybe biquad filters are also not the best choice for low frequency filters, because they tend to start being unstable below around 400Hz.

    All the best,

    Frank DD4WH

  6. #6
    Junior Member
    Join Date
    Sep 2018
    Location
    Newberg, OR
    Posts
    3
    Hi Frank,

    My thinking was that the biquad object in the library would be the easiest way to implement the first order filter, since its uses a subset of the biquad structure (most of the biquad coefficients are zero). I think any other approach would require me to somehow handle the processing on a sample by sample basis -- and I'm not sure how I'd do that -- maybe by importing buffers, doing the processing and then exporting them(?)

    I'm totally open to suggestions! I had DSP classes in college (years ago), but this is the first time I've had hardware that was easy to program -- and listen to Now I'm trying to sort out some of the "theory vs practice" design issues with DSP filters.

    Thanks for your help!

Posting Permissions

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