|
|
@ -31,15 +31,15 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <Arduino.h> |
|
|
|
#include <Arduino.h> |
|
|
|
#include "analyze_fft1024_F32.h" |
|
|
|
#include "analyze_fft1024_F32.h" |
|
|
|
// #include "utility/dspinst.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Move audio data from an audio_block_f32_t to the FFT instance buffer.
|
|
|
|
// Move audio data from an audio_block_f32_t to the FFT instance buffer.
|
|
|
|
|
|
|
|
// This is for 128 numbers per block
|
|
|
|
static void copy_to_fft_buffer(void *destination, const void *source) |
|
|
|
static void copy_to_fft_buffer(void *destination, const void *source) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const float *src = (const float *)source; |
|
|
|
const float *src = (const float *)source; |
|
|
|
float *dst = (float *)destination; |
|
|
|
float *dst = (float *)destination; |
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) { |
|
|
|
for (int i=0; i < 128; i++) { |
|
|
|
*dst++ = *src++; // real sample
|
|
|
|
*dst++ = *src++; // real sample
|
|
|
|
*dst++ = 0.0f; // 0 for Imag
|
|
|
|
*dst++ = 0.0f; // 0 for Imag
|
|
|
|
} |
|
|
|
} |
|
|
@ -54,14 +54,15 @@ static void apply_window_to_fft_buffer(void *buffer, const void *window) |
|
|
|
buf[2*i] *= *win++;
|
|
|
|
buf[2*i] *= *win++;
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AudioAnalyzeFFT1024_F32::update(void) |
|
|
|
void AudioAnalyzeFFT1024_F32::update(void) { |
|
|
|
{ |
|
|
|
|
|
|
|
audio_block_f32_t *block; |
|
|
|
audio_block_f32_t *block; |
|
|
|
block = receiveReadOnly_f32(); |
|
|
|
uint32_t tt; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
block = AudioStream_F32::receiveReadOnly_f32(); |
|
|
|
if (!block) return; |
|
|
|
if (!block) return; |
|
|
|
|
|
|
|
|
|
|
|
// What all does 7EM cover??
|
|
|
|
// tt=micros();
|
|
|
|
#if defined(__ARM_ARCH_7EM__) |
|
|
|
|
|
|
|
switch (state) { |
|
|
|
switch (state) { |
|
|
|
case 0: |
|
|
|
case 0: |
|
|
|
blocklist[0] = block; |
|
|
|
blocklist[0] = block; |
|
|
@ -93,10 +94,12 @@ void AudioAnalyzeFFT1024_F32::update(void) |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 7: |
|
|
|
case 7: |
|
|
|
blocklist[7] = block; |
|
|
|
blocklist[7] = block; |
|
|
|
|
|
|
|
// We have 4 previous blocks pointed to by blocklist[]:
|
|
|
|
copy_to_fft_buffer(fft_buffer+0x000, blocklist[0]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x000, blocklist[0]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x100, blocklist[1]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x100, blocklist[1]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x200, blocklist[2]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x200, blocklist[2]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x300, blocklist[3]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x300, blocklist[3]->data); |
|
|
|
|
|
|
|
// and 4 new blocks, just gathered:
|
|
|
|
copy_to_fft_buffer(fft_buffer+0x400, blocklist[4]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x400, blocklist[4]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x500, blocklist[5]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x500, blocklist[5]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x600, blocklist[6]->data); |
|
|
|
copy_to_fft_buffer(fft_buffer+0x600, blocklist[6]->data); |
|
|
@ -105,32 +108,55 @@ void AudioAnalyzeFFT1024_F32::update(void) |
|
|
|
if (pWin) |
|
|
|
if (pWin) |
|
|
|
apply_window_to_fft_buffer(fft_buffer, window); |
|
|
|
apply_window_to_fft_buffer(fft_buffer, window); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__IMXRT1062__) |
|
|
|
|
|
|
|
// Teensyduino core for T4.x supports arm_cfft_f32
|
|
|
|
|
|
|
|
// arm_cfft_f32 (const arm_cfft_instance_f32 *S, float32_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag)
|
|
|
|
|
|
|
|
arm_cfft_f32 (&Sfft, fft_buffer, 0, 1); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
// For T3.x go back to old (deprecated) style
|
|
|
|
arm_cfft_radix4_f32(&fft_inst, fft_buffer); |
|
|
|
arm_cfft_radix4_f32(&fft_inst, fft_buffer); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
count++; // Next do non-coherent averaging
|
|
|
|
for (int i=0; i < 512; i++) { |
|
|
|
for (int i=0; i < 512; i++) { |
|
|
|
float magsq = fft_buffer[2*i]*fft_buffer[2*i] + fft_buffer[2*i+1]*fft_buffer[2*i+1]; |
|
|
|
float magsq = fft_buffer[2*i]*fft_buffer[2*i] + fft_buffer[2*i+1]*fft_buffer[2*i+1]; |
|
|
|
|
|
|
|
if(count==1) // Starting new average
|
|
|
|
|
|
|
|
sumsq[i] = magsq; |
|
|
|
|
|
|
|
else if (count<=nAverage) // Adding on to average
|
|
|
|
|
|
|
|
sumsq[i] += magsq; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (count >= nAverage) { // Average is finished
|
|
|
|
|
|
|
|
count = 0; |
|
|
|
|
|
|
|
float inAf = 1.0f/(float)nAverage; |
|
|
|
|
|
|
|
for(int i=0; i<512; i++) { |
|
|
|
if(outputType==FFT_RMS) |
|
|
|
if(outputType==FFT_RMS) |
|
|
|
output[i] = sqrtf(magsq); |
|
|
|
output[i] = sqrtf(inAf*sumsq[i]); |
|
|
|
else if(outputType==FFT_POWER) |
|
|
|
else if(outputType==FFT_POWER) |
|
|
|
output[i] = magsq; |
|
|
|
output[i] = inAf*sumsq[i]; |
|
|
|
else if(outputType==FFT_DBFS) |
|
|
|
else if(outputType==FFT_DBFS) { |
|
|
|
output[i] = 10.0f*log10f(magsq)-54.1854f; // Scaled to FS sine wave
|
|
|
|
if(sumsq[i]>0.0f) |
|
|
|
|
|
|
|
output[i] = 10.0f*log10f(inAf*sumsq[i])-54.1854f; // Scaled to FS sine wave
|
|
|
|
else |
|
|
|
else |
|
|
|
output[i] = 0.0f; |
|
|
|
output[i] = -193.0f; // lsb for 23 bit mantissa
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
output[i] = 0.0f; |
|
|
|
|
|
|
|
} // End, set output[i] over all 512
|
|
|
|
|
|
|
|
|
|
|
|
outputflag = true; |
|
|
|
outputflag = true; |
|
|
|
release(blocklist[0]); |
|
|
|
} // End of average is finished
|
|
|
|
release(blocklist[1]); |
|
|
|
|
|
|
|
release(blocklist[2]); |
|
|
|
AudioStream_F32::release(blocklist[0]); |
|
|
|
release(blocklist[3]); |
|
|
|
AudioStream_F32::release(blocklist[1]); |
|
|
|
|
|
|
|
AudioStream_F32::release(blocklist[2]); |
|
|
|
|
|
|
|
AudioStream_F32::release(blocklist[3]); |
|
|
|
|
|
|
|
|
|
|
|
blocklist[0] = blocklist[4]; |
|
|
|
blocklist[0] = blocklist[4]; |
|
|
|
blocklist[1] = blocklist[5]; |
|
|
|
blocklist[1] = blocklist[5]; |
|
|
|
blocklist[2] = blocklist[6]; |
|
|
|
blocklist[2] = blocklist[6]; |
|
|
|
blocklist[3] = blocklist[7]; |
|
|
|
blocklist[3] = blocklist[7]; |
|
|
|
state = 4; |
|
|
|
state = 4; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} // End switch(state)
|
|
|
|
#else |
|
|
|
// Serial.print("uSec: "); Serial.println(micros()-tt);
|
|
|
|
release(block); |
|
|
|
} // End update()
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|