First Order Filters

Status
Not open for further replies.
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
 
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.
 
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];
 
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...
 
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
 
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!
 
Status
Not open for further replies.
Back
Top