|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* FFT_Overrlapped_F32 |
|
|
|
* FFT_Overrlapped_OA_F32 |
|
|
|
* |
|
|
|
* |
|
|
|
* Purpose: Encapsulate the ARM floating point FFT/IFFT functions |
|
|
|
* Purpose: Encapsulate the ARM floating point FFT/IFFT functions |
|
|
|
* in a way that naturally interfaces to my float32 |
|
|
|
* in a way that naturally interfaces to my float32 |
|
|
@ -16,7 +16,6 @@ |
|
|
|
* Jan-Jul 2017 |
|
|
|
* Jan-Jul 2017 |
|
|
|
* |
|
|
|
* |
|
|
|
* Typical Usage as FFT: |
|
|
|
* Typical Usage as FFT: |
|
|
|
*
|
|
|
|
|
|
|
|
* //setup the audio stuff
|
|
|
|
* //setup the audio stuff
|
|
|
|
* float sample_rate_Hz = 44100.0; //define sample rate
|
|
|
|
* float sample_rate_Hz = 44100.0; //define sample rate
|
|
|
|
* int audio_block_samples = 32; //define size of audio blocks
|
|
|
|
* int audio_block_samples = 32; //define size of audio blocks
|
|
|
@ -46,23 +45,37 @@ |
|
|
|
* audio_block_f32_t *out_audio_block = IFFT_obj.execute(complex_2N_buffer); |
|
|
|
* audio_block_f32_t *out_audio_block = IFFT_obj.execute(complex_2N_buffer); |
|
|
|
* //note that the "out_audio_block" is mananged by IFFT_obj, so don't worry about releasing it.
|
|
|
|
* //note that the "out_audio_block" is mananged by IFFT_obj, so don't worry about releasing it.
|
|
|
|
* |
|
|
|
* |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* https://forum.pjrc.com/threads/53668-fft-ifft?highlight=IFFT willie.from.texas 9-10-2018
|
|
|
|
|
|
|
|
* I've been using the CMSIS Version 5.3.0 DSP Library since May 2018 (see github.com/ARM-software/CMSIS_5). |
|
|
|
|
|
|
|
* I might be the only person on this forum using it. The library allows me to use the 32-bit floating point |
|
|
|
|
|
|
|
* capability of the Teensy 3.6. I have been able to use it in real-time with 16-bit sample rates |
|
|
|
|
|
|
|
* out of both ADCs up to around 450 kHz (i-q data). I'm very happy with the performance I am obtaining. |
|
|
|
|
|
|
|
* Here is the FFT/IFFT performance I am getting with the library: |
|
|
|
|
|
|
|
* # Points Forward rfft Inverse rfft Forward cfft Inverse cfft |
|
|
|
|
|
|
|
* 512 201 us 247 us 239 us 294 us |
|
|
|
|
|
|
|
* 1024 362 us 454 us 588 us 714 us |
|
|
|
|
|
|
|
* 2048 846 us 1066 us 1376 us 1620 us |
|
|
|
|
|
|
|
* 4096 1860 us 2304 us 2504 us 2990 us |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* |
|
|
|
* License: MIT License |
|
|
|
* License: MIT License |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#ifndef _FFT_Overlapped_F32_h |
|
|
|
#ifndef _FFT_Overlapped_OA_F32_h |
|
|
|
#define _FFT_Overlapped_F32_h |
|
|
|
#define _FFT_Overlapped_OA_F32_h |
|
|
|
|
|
|
|
|
|
|
|
#include "AudioStream_F32.h" |
|
|
|
#include "AudioStream_F32.h" |
|
|
|
#include <arm_math.h> |
|
|
|
#include <arm_math.h> |
|
|
|
#include "FFT_F32.h" |
|
|
|
#include "FFT_OA_F32.h" |
|
|
|
//#include "utility/dspinst.h" //copied from analyze_fft256.cpp. Do we need this?
|
|
|
|
//#include "utility/dspinst.h" //copied from analyze_fft256.cpp. Do we need this?
|
|
|
|
|
|
|
|
|
|
|
|
// set the max amount of allowed overlap...some number larger than you'll want to use
|
|
|
|
// set the max amount of allowed overlap...some number larger than you'll want to use
|
|
|
|
#define MAX_N_BUFF_BLOCKS 32 //32 blocks x 16 sample blocks enables NFFT = 512, if the Teensy could keep up.
|
|
|
|
#define MAX_N_BUFF_BLOCKS 32 //32 blocks x 16 sample blocks enables NFFT = 512, if the Teensy could keep up.
|
|
|
|
|
|
|
|
|
|
|
|
class FFT_Overlapped_Base_F32 { //handles all the data structures for the overlapping stuff. Doesn't care if FFT or IFFT
|
|
|
|
class FFT_Overlapped_Base_OA_F32 { //handles all the data structures for the overlapping stuff. Doesn't care if FFT or IFFT
|
|
|
|
public: |
|
|
|
public: |
|
|
|
FFT_Overlapped_Base_F32(void) {}; |
|
|
|
FFT_Overlapped_Base_OA_F32(void) {}; |
|
|
|
~FFT_Overlapped_Base_F32(void) { |
|
|
|
~FFT_Overlapped_Base_OA_F32(void) { |
|
|
|
if (N_BUFF_BLOCKS > 0) { |
|
|
|
if (N_BUFF_BLOCKS > 0) { |
|
|
|
for (int i = 0; i < N_BUFF_BLOCKS; i++) { |
|
|
|
for (int i = 0; i < N_BUFF_BLOCKS; i++) { |
|
|
|
if (buff_blocks[i] != NULL) AudioStream_F32::release(buff_blocks[i]); |
|
|
|
if (buff_blocks[i] != NULL) AudioStream_F32::release(buff_blocks[i]); |
|
|
@ -117,13 +130,13 @@ class FFT_Overlapped_Base_F32 { //handles all the data structures for the overl |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class FFT_Overlapped_F32: public FFT_Overlapped_Base_F32 |
|
|
|
class FFT_Overlapped_OA_F32: public FFT_Overlapped_Base_F32 |
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
//constructors
|
|
|
|
//constructors
|
|
|
|
FFT_Overlapped_F32(void): FFT_Overlapped_Base_F32() {}; |
|
|
|
FFT_Overlapped_OA_F32(void): FFT_Overlapped_Base_F32() {}; |
|
|
|
FFT_Overlapped_F32(const AudioSettings_F32 &settings): FFT_Overlapped_Base_F32() { } |
|
|
|
FFT_Overlapped_OA_F32(const AudioSettings_F32 &settings): FFT_Overlapped_Base_F32() { } |
|
|
|
FFT_Overlapped_F32(const AudioSettings_F32 &settings, const int _N_FFT): FFT_Overlapped_Base_F32() {
|
|
|
|
FFT_Overlapped_OA_F32(const AudioSettings_F32 &settings, const int _N_FFT): FFT_Overlapped_Base_F32() { |
|
|
|
setup(settings,_N_FFT); |
|
|
|
setup(settings,_N_FFT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -144,14 +157,13 @@ class FFT_Overlapped_F32: public FFT_Overlapped_Base_F32 |
|
|
|
FFT_F32 myFFT; |
|
|
|
FFT_F32 myFFT; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IFFT_Overlapped_OA_F32: public FFT_Overlapped_Base_F32 |
|
|
|
class IFFT_Overlapped_F32: public FFT_Overlapped_Base_F32 |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
//constructors
|
|
|
|
//constructors
|
|
|
|
IFFT_Overlapped_F32(void): FFT_Overlapped_Base_F32() {}; |
|
|
|
IFFT_Overlapped_OA_F32(void): FFT_Overlapped_Base_F32() {}; |
|
|
|
IFFT_Overlapped_F32(const AudioSettings_F32 &settings): FFT_Overlapped_Base_F32() { } |
|
|
|
IFFT_Overlapped_OA_F32(const AudioSettings_F32 &settings): FFT_Overlapped_Base_F32() { } |
|
|
|
IFFT_Overlapped_F32(const AudioSettings_F32 &settings, const int _N_FFT): FFT_Overlapped_Base_F32() {
|
|
|
|
IFFT_Overlapped_OA_F32(const AudioSettings_F32 &settings, const int _N_FFT): FFT_Overlapped_Base_F32() { |
|
|
|
setup(settings,_N_FFT); |
|
|
|
setup(settings,_N_FFT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -170,8 +182,4 @@ class IFFT_Overlapped_F32: public FFT_Overlapped_Base_F32 |
|
|
|
private: |
|
|
|
private: |
|
|
|
IFFT_F32 myIFFT; |
|
|
|
IFFT_F32 myIFFT; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |