Corrected comments, no code change

pull/13/head
boblark 3 years ago
parent 21b07971f4
commit 8ac9b2f536
  1. 14
      AudioFilterBiquad_F32.h
  2. 22
      AudioFilterFIRGeneral_F32.h

@ -1,5 +1,5 @@
/* /*
* AudioFilterBiquad_F32.cpp * AudioFilterBiquad_F32.h
* Chip Audette, OpenAudio, Apr 2017 * Chip Audette, OpenAudio, Apr 2017
* MIT License, Use at your own risk. * MIT License, Use at your own risk.
* *
@ -20,11 +20,11 @@
* begin of the ARM CMSIS. We can't do that with multiple stages. If you * begin of the ARM CMSIS. We can't do that with multiple stages. If you
* encouter this, add myBiquad.begin(); to your INO after the * encouter this, add myBiquad.begin(); to your INO after the
* coefficients have been set. Feb 2021 * coefficients have been set. Feb 2021
* *
* The sign of the coefficients for feedback, the a[], here use the * The sign of the coefficients for feedback, the a[], here use the
* convention of the ARM CMSIS library. Matlab reverses the signs of these. * convention of the ARM CMSIS library. Matlab reverses the signs of these.
* I believe these are treated per those rules!! Bob * I believe these are treated per those rules!! Bob
* *
* Algorithm for CMSIS library * Algorithm for CMSIS library
* Each Biquad stage implements a second order filter using the difference equation: * Each Biquad stage implements a second order filter using the difference equation:
* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] * y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
@ -100,11 +100,11 @@ class AudioFilterBiquad_F32 : public AudioStream_F32
} }
// ARM DSP Math library filter instance. // ARM DSP Math library filter instance.
// Does the initialization of ARM CMSIS DSP BiQuad structure. This MUST follow the // Does the initialization of ARM CMSIS DSP BiQuad structure. This MUST follow the
// setting of coefficients to catch the max number of stages and do the // setting of coefficients to catch the max number of stages and do the
// double to float conversion for the CMSIS routine. // double to float conversion for the CMSIS routine.
void begin(void) { void begin(void) {
// Initialize FIR instance (ARM DSP Math Library) // Initialize BiQuad instance (ARM DSP Math Library)
//https://www.keil.com/pack/doc/CMSIS/DSP/html/group__BiquadCascadeDF1.html //https://www.keil.com/pack/doc/CMSIS/DSP/html/group__BiquadCascadeDF1.html
arm_biquad_cascade_df1_init_f32(&iir_inst, numStagesUsed, &coeff32[0], &StateF32[0]); arm_biquad_cascade_df1_init_f32(&iir_inst, numStagesUsed, &coeff32[0], &StateF32[0]);
} }
@ -115,7 +115,7 @@ class AudioFilterBiquad_F32 : public AudioStream_F32
void setSampleRate_Hz(float _fs_Hz) { sampleRate_Hz = _fs_Hz; } void setSampleRate_Hz(float _fs_Hz) { sampleRate_Hz = _fs_Hz; }
// Deprecated // Deprecated
void setBlockDC(void) { void setBlockDC(void) {
// https://www.keil.com/pack/doc/CMSIS/DSP/html/group__BiquadCascadeDF1.html#ga8e73b69a788e681a61bccc8959d823c5 // https://www.keil.com/pack/doc/CMSIS/DSP/html/group__BiquadCascadeDF1.html#ga8e73b69a788e681a61bccc8959d823c5
// Use matlab to compute the coeff for HP at 40Hz: [b,a]=butter(2,40/(44100/2),'high'); %assumes fs_Hz = 44100 // Use matlab to compute the coeff for HP at 40Hz: [b,a]=butter(2,40/(44100/2),'high'); %assumes fs_Hz = 44100

@ -9,7 +9,7 @@
* for the library structures and wonderful Teensy products. * for the library structures and wonderful Teensy products.
* *
* There are enough different FIR filter Audio blocks to need a summary. Here goes: * There are enough different FIR filter Audio blocks to need a summary. Here goes:
* *
* AudioFilterFIR (Teensy Audio Library by PJRC) handles 16-bit integer data, * AudioFilterFIR (Teensy Audio Library by PJRC) handles 16-bit integer data,
* and a maximum of 200 FIR coefficients, even only. (taps). For Teensy Audio. * and a maximum of 200 FIR coefficients, even only. (taps). For Teensy Audio.
* AudioFilterFIR_F32 (OpenAudio_ArduinoLibrary by Chip Audette) handles 32-bit floating point * AudioFilterFIR_F32 (OpenAudio_ArduinoLibrary by Chip Audette) handles 32-bit floating point
@ -32,21 +32,21 @@
* FIR filters suffer from needing considerable computation of the multiply-and-add * FIR filters suffer from needing considerable computation of the multiply-and-add
* sort. This limits the number of taps that can be used, but less so as time goes by. * sort. This limits the number of taps that can be used, but less so as time goes by.
* In particular, the Teensy 4.x, if it *did nothing but* FIR calculations, could * In particular, the Teensy 4.x, if it *did nothing but* FIR calculations, could
* use about 6000 taps inmonaural, which is a huge number. But, this also * use about 6000 taps inmonaural, which is a huge number. But, this also
* suggests that if the filtering task is an important function of a project, * suggests that if the filtering task is an important function of a project,
* using, say 2000 taps is practical. * using, say 2000 taps is practical.
* *
* FIR filters can be (and are here) implemented to have symmetrical coefficients. This * FIR filters can be (and are here) implemented to have symmetrical coefficients. This
* results in constant delay at all frequencies (linear phase). For some applications this can * results in constant delay at all frequencies (linear phase). For some applications this can
* be an important feature. Sometimes it is suggested that the FIR should not be * be an important feature. Sometimes it is suggested that the FIR should not be
* used because of the latency it creates. Note that if constant delay is needed, the FIR * used because of the latency it creates. Note that if constant delay is needed, the FIR
* implementation does this with minimum latency. * implementation does this with minimum latency.
* *
* For this block, AudioFilterFIRGeneral_F32, memory storage for the FIR * For this block, AudioFilterFIRGeneral_F32, memory storage for the FIR
* coefficiients as well as working storage for the ARM FIR routine is provided * coefficiients as well as working storage for the ARM FIR routine is provided
* by the calling .INO. This allows large FIR sizes without always tying up a * by the calling .INO. This allows large FIR sizes without always tying up a
* big memory block. * big memory block.
* *
* This block normally calculates the FIR coefficients using a Fourier transform * This block normally calculates the FIR coefficients using a Fourier transform
* of the desired amplitude response and a Kaiser window. This flexability requires * of the desired amplitude response and a Kaiser window. This flexability requires
* the calling .INO to provide an array of response levels, in relative dB, * the calling .INO to provide an array of response levels, in relative dB,
@ -57,17 +57,17 @@
* else dbA[i] = -140.0f; * else dbA[i] = -140.0f;
* } * }
* firg1.FIRGeneralNew(&dbA[0], 300, &equalizeCoeffs[0], 50.0f, &workSpace[0]); * firg1.FIRGeneralNew(&dbA[0], 300, &equalizeCoeffs[0], 50.0f, &workSpace[0]);
* *
* As an alternate to inputting the response function, the FIR coefficients can be * As an alternate to inputting the response function, the FIR coefficients can be
* entered directly using LoadCoeffs(nFIR, cf32f, *pStateArray). This is a very quick * entered directly using LoadCoeffs(nFIR, cf32f, *pStateArray). This is a very quick
* operation as only pointers to coefficients are involved. Several filters can be * operation as only pointers to coefficients are involved. Several filters can be
* stored in arrays and switched quickly this way. If this is done, pStateArray[] * stored in arrays and switched quickly this way. If this is done, pStateArray[]
* as initially setup should be large enough for all filters. There will be "clicks" * as initially setup should be large enough for all filters. There will be "clicks"
* associated with filter changes and these may need to be muted. * associated with filter changes and these may need to be muted.
* *
* How well the desired response is achieved depends on the number of FIR coefficients * How well the desired response is achieved depends on the number of FIR coefficients
* being used. As noted above, for some applications it may be desired to use * being used. As noted above, for some applications it may be desired to use
* large numbers of taps. The achieved response can be evaluated * large numbers of taps. The achieved response can be evaluated
* by the function getResponse(nPoints, pResponse) which fills an .INO-supplied array * by the function getResponse(nPoints, pResponse) which fills an .INO-supplied array
* pResponse[nPoints] with the frequency response of the equalizer in dB. The nPoints * pResponse[nPoints] with the frequency response of the equalizer in dB. The nPoints
* are spread evenly between 0.0 and half of the sample frequency. * are spread evenly between 0.0 and half of the sample frequency.
@ -99,11 +99,11 @@
* frequency response. * frequency response.
* LoadCoeffs(nFIR, cf32f, *pStateArray); // To directly load FIR coefficients cf32f[] * LoadCoeffs(nFIR, cf32f, *pStateArray); // To directly load FIR coefficients cf32f[]
* getResponse(nFreq, *rdb); // To obtain the amplitude response in dB, rdb[] * getResponse(nFreq, *rdb); // To obtain the amplitude response in dB, rdb[]
* *
* Status: Tested T3.6, T4.0 No known bugs * Status: Tested T3.6, T4.0 No known bugs
* *
* Examples: TestFIRGeneralLarge4.ino TestFIRGeneralLarge5.ino * Examples: TestFIRGeneralLarge4.ino TestFIRGeneralLarge5.ino
* *
* Copyright (c) 2020 Bob Larkin * Copyright (c) 2020 Bob Larkin
* Any snippets of code from PJRC or Chip Audette used here brings with it * Any snippets of code from PJRC or Chip Audette used here brings with it
* the associated license. * the associated license.

Loading…
Cancel
Save