Fixed FFT calls to run under T3.5 and T3.6

pull/16/merge
boblark 1 year ago
parent a3ec83fe5d
commit 2c66f6cdea
  1. 24
      AudioFilterConvolution_F32.cpp
  2. 45
      AudioFilterConvolution_F32.h
  3. 9
      examples/TestConvolutinalFilter/TestConvolutinalFilter.ino

@ -24,6 +24,7 @@
6) Optimize the time execution
*******************************************************************/
// Revised for OpenAudio_Arduino Teensy F32 library, 8 Feb 2022
// Revised 18 January to work for Teensy 3.5 and T3.6. Bob L
#include "AudioFilterConvolution_F32.h"
@ -48,11 +49,15 @@ void AudioFilterConvolution_F32::impulse(float32_t *FIR_coef)
{
FIR_filter_mask[i] = 0.0;
}
arm_cfft_f32( &arm_cfft_sR_f32_len1024, FIR_filter_mask, 0, 1);
// T3.5 or T3.6
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_f32(&fft_instFwd, FIR_filter_mask);
#elif defined(__IMXRT1062__)
arm_cfft_f32(&arm_cfft_sR_f32_len1024, FIR_filter_mask, 0, 1); // T4.x
#endif
// for 1st time thru, zero out the last sample buffer to 0
arm_fill_f32(0, last_sample_buffer_L, 128*4);
arm_fill_f32(0, last_sample_buffer_L, 128*4);
state = 0;
enabled = 1; //enable audio stream again
}
@ -69,7 +74,11 @@ void AudioFilterConvolution_F32::update(void)
case 0:
if (passThru ==0) {
arm_cmplx_mult_cmplx_f32(FFT_buffer, FIR_filter_mask, iFFT_buffer, FFT_length); // complex multiplication in Freq domain = convolution in time domain
arm_cfft_f32(&arm_cfft_sR_f32_len1024, iFFT_buffer, 1, 1); // perform complex inverse FFT
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_f32(&fft_instRev, iFFT_buffer);
#elif defined(__IMXRT1062__)
arm_cfft_f32(&arm_cfft_sR_f32_len1024, iFFT_buffer, 1, 1);
#endif
k = 0;
l = 1024;
for (int i = 0; i < 512; i++) {
@ -135,7 +144,11 @@ void AudioFilterConvolution_F32::update(void)
FFT_buffer[k++] = buffer[i]; // imag
}
// calculations are performed in-place in FFT routines
arm_cfft_f32(&arm_cfft_sR_f32_len1024, FFT_buffer, 0, 1);// perform complex FFT
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_f32(&fft_instFwd, FFT_buffer);
#elif defined(__IMXRT1062__)
arm_cfft_f32(&arm_cfft_sR_f32_len1024, FFT_buffer, 0, 1); // perform complex FFT
#endif
} //end if passTHru
break;
}
@ -264,3 +277,4 @@ void AudioFilterConvolution_F32::initFilter ( float32_t fc, float32_t Astop, int
enabled = 0; // set to zero to disable audio processing until impulse has been loaded
impulse(FIR_Coef); // generates Filter Mask and enables the audio stream
}

@ -96,7 +96,7 @@
* use of this class.
*
* Removed #defines that were not needed. Thanks K7MDL. Bob 6 Mar 2022
* Added needed part of arm_const_structs.h. Thanks Paul Bob 16 Jan 2023
* Separated Teensy 3 and 4 parts. Thanks Paul Bob 16 Jan 2023
*
* ************************************************************ */
@ -104,11 +104,12 @@
#define AudioFilterConvolution_F32_h_
#include <AudioStream_F32.h>
#include <arm_math.h>
#include "arm_math.h"
#include "arm_common_tables.h"
// #include <arm_const_structs.h> not available for teensy3, so here is needed line
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
#if defined(__IMXRT1062__)
#include "arm_const_structs.h"
#endif
#define MAX_NUMCOEF 513
@ -124,13 +125,30 @@ class AudioFilterConvolution_F32 :
public AudioStream_F32
{
public:
AudioFilterConvolution_F32(void) : AudioStream_F32(1, inputQueueArray_F32) {
AudioFilterConvolution_F32(void) :
AudioStream_F32(1, inputQueueArray_F32)
{
fs = AUDIO_SAMPLE_RATE;
//block_size = 128; // Always
//block_size = 128; // Always
// INFO: __MK20DX128__ T_LC; __MKL26Z64__ T3.0; __MK20DX256__ T3.1 and T3.2
// __MK64FX512__) T3.5; __MK66FX1M0__ T3.6; __IMXRT1062__ T4.0 and T4.1
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_init_f32(&fft_instFwd, 1024, 0, 1);
arm_cfft_radix4_init_f32(&fft_instRev, 1024, 1, 1);
// arm CMSIS library has predefined structures of type arm_cfft_instance_f32
// arm_cfft_sR_f32_len1024 is one of the structures
#endif
};
AudioFilterConvolution_F32(const AudioSettings_F32 &settings) : AudioStream_F32(1, inputQueueArray_F32) {
AudioFilterConvolution_F32(const AudioSettings_F32 &settings) :
AudioStream_F32(1, inputQueueArray_F32)
{
// Performs the first initialize
fs = settings.sample_rate_Hz;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_init_f32(&fft_instFwd, 1024, 0, 1);
arm_cfft_radix4_init_f32(&fft_instRev, 1024, 1, 1);
#endif
};
virtual void update(void);
@ -140,8 +158,6 @@ public:
int type, float32_t dfc);
float32_t* getCoeffPtr(void) {return &FIR_Coef[0];}
//#define Alternate filter init
private:
float32_t fs;
audio_block_f32_t *inputQueueArray_F32[1];
@ -161,13 +177,20 @@ private:
float32_t iFFT_buffer[2048] __attribute__((aligned(4)));
float32_t last_sample_buffer_L[512];
void impulse(float32_t *coefs);
int aaa = 0;
float32_t Izero (float32_t x);
float32_t m_sinc(int m, float32_t fc);
void calc_FIR_coeffs (float32_t * coeffs, int numCoeffs,
float32_t fc, float32_t Astop,
int type, float32_t dfc,
float32_t Fsamprate);
};
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
arm_cfft_radix4_instance_f32 fft_instFwd, fft_instRev;
// #elif defined(__IMXRT1062__)
// arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 is built into cmsis
#endif
};
// end of read only once
#endif

@ -58,7 +58,7 @@ void setup(void) {
//convFilt1.initFilter(800.0f, 40.0f, BANDPASS, 1200.0f);
// IK8YFW SSB - Centered at 1500Hz, 60 db SL, 2=BPF, width = 3000Hz
//convFilt1.initFilter(1500.0f, 60.0f, BANDPASS, 3000.0f);
convFilt1.initFilter(1500.0f, 60.0f, BANDPASS, 3000.0f);
// Band Reject filter, Centered at 6000Hz, 50 db SL, 3=BRF, width = 2000Hz
//convFilt1.initFilter(6000.0f, 60.0f, BANDREJECT, 2000.0f);
@ -86,13 +86,12 @@ void setup(void) {
*/
// Alternatively, the passthrough case:
convFilt1.passThrough(1);
convFilt1.initFilter();
//convFilt1.passThrough(1);
// Design for direct FIR. This sets frequency response.
// Bin for 4kHz at 44.117kHz sample rate and 400 coeff's is (4000/44117) * (512/2) = 23.2
// for(int ii=0; ii<47; ii++) attenFIR[ii] = 0.0f;
// for(int ii=47; ii<256; ii++) attenFIR[ii] = -150.0f;
// for(int ii=0; ii<47; ii++) attenFIR[ii] = 0.0f;
// for(int ii=47; ii<256; ii++) attenFIR[ii] = -150.0f;
// FIRGeneralNew(float *adb, uint16_t nFIR, float *cf32f, float kdb, float *pStateArray);
// filterFIRgeneral1.FIRGeneralNew(attenFIR, 512, coeffFIR, 60.0, stateFIR);

Loading…
Cancel
Save