George MacKerron: code blog

GIS, software development, and other snippets

Using vDSP_deq22 as a bandpass filter

For reasons that may become clearer in future, I needed to use a bandpass filter in an iOS app. The DSP part of Apple’s Accelerate framework makes this lightning fast both for the programmer to implement and for the machine to execute … if the programmer knows how use vDSP_deq22, which is documented, at best, concisely.

The following functions produce the five-coefficient filter definition you need to pass to vDSP_deq22. Since this took me a little while to put together, I thought I’d share.

void makeBandpassFilterWithFcAndQ(float* filter, double Fs, double Fc, double Q) {
 
  // Fs = sampling rate, Fc = centre freq
  // with thanks to http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
  // and https://github.com/bartolsthoorn/NVDSP
 
  double K = tan(M_PI * Fc / Fs);
  double norm = 1.0 / (1.0 + K / Q + K * K);
  filter[0] = (float)(K / Q * norm);
  filter[1] = 0.0f;
  filter[2] = -filter[0];
  filter[3] = (float)(2.0 * (K * K - 1.0) * norm);
  filter[4] = (float)((1.0 - K / Q + K * K) * norm);
}
 
void makeBandpassFilterWithFreqRange(float* filter, double Fs, double Fbtm, double Ftop) {
 
  // with thanks to 
  // http://stackoverflow.com/questions/15627013/how-do-i-configure-a-bandpass-filter
  // -- this sets Q such that there's -3dB gain (= 50% power loss) at Fbtm and Ftop
 
  double Fc = sqrt(Fbtm * Ftop);
  double Q = Fc / (Ftop - Fbtm);
  makeBandpassFilterWithFcAndQ(filter, Fs, Fc, Q);
}

And you use it like so:

float filter[5];
makeBandpassFilterWithFreqRange(filter, sampleRate, filterLoRate, filterHiRate);
vDSP_deq22(rawFloats, rawStride, filter, filteredFloats, filteredStride, numRawFloats - 2); 
  // rawFloats and filteredFloats are pointers, of course

Share

Written by George

February 4th, 2014 at 2:37 pm

Posted in iPhone,Mac

  • takeanice

    Thanks for the post! But I don´t really understand the input values. Is rawFloats an array of measured values (like audio samples or image brightness values)? Or do I have to provide it in the frequency domain for the function to work? And is sampleRate the number of samples per second? I don´t know much about signal processing, but trying to teach it myself a little…