#include "FFT_Overlapped_OA_F32.h" void FFT_Overlapped_OA_F32::execute(audio_block_f32_t *block, float *complex_2N_buffer) //results returned inc omplex_2N_buffer { int targ_ind; //get a pointer to the latest data //audio_block_f32_t *block = AudioStream_F32::receiveReadOnly_f32(); if (!block) return; //add a claim to this block. As a result, be sure that this function issues a "release()". //Also, be sure that the calling function issues its own release() to release its claim. block->ref_count++; //shuffle all of input data blocks in preperation for this latest processing AudioStream_F32::release(buff_blocks[0]); //release the oldest one...this is the release the corresponds to the claim above for (int i = 1; i < N_BUFF_BLOCKS; i++) buff_blocks[i - 1] = buff_blocks[i]; buff_blocks[N_BUFF_BLOCKS - 1] = block; //append the newest input data to the complex_buffer blocks //copy all input data blocks into one big block...the big block is interleaved [real,imaginary] targ_ind = 0; //Serial.print("Overlapped_FFT_F32: N_BUFF_BLOCKS = "); Serial.print(N_BUFF_BLOCKS); //Serial.print(", audio_block_samples = "); Serial.println(audio_block_samples); for (int i = 0; i < N_BUFF_BLOCKS; i++) { for (int j = 0; j < audio_block_samples; j++) { complex_2N_buffer[2*targ_ind] = buff_blocks[i]->data[j]; //real complex_2N_buffer[2*targ_ind+1] = 0; //imaginary targ_ind++; } } //call the FFT...windowing of the data happens in the FFT routine, if configured myFFT.execute(complex_2N_buffer); } audio_block_f32_t* IFFT_Overlapped_OA_F32::execute(float *complex_2N_buffer) { //real results returned through audio_block_f32_t //Serial.print("Overlapped_IFFT_F32: N_BUFF_BLOCKS = "); Serial.print(N_BUFF_BLOCKS); //Serial.print(", audio_block_samples = "); Serial.println(audio_block_samples); //call the IFFT...any follow-up windowing is handdled in the IFFT routine, if configured myIFFT.execute(complex_2N_buffer); //prepare for the overlap-and-add for the output audio_block_f32_t *temp_buff = buff_blocks[0]; //hold onto this one for a moment...it'll get overwritten later for (int i = 1; i < N_BUFF_BLOCKS; i++) buff_blocks[i - 1] = buff_blocks[i]; //shuffle the output data blocks buff_blocks[N_BUFF_BLOCKS - 1] = temp_buff; //put the oldest output buffer back in the list //do overlap and add with previously computed data int output_count = 0; for (int i = 0; i < (N_BUFF_BLOCKS-1); i++) { //Notice that this loop does NOT do the last block. That's a special case after. for (int j = 0; j < audio_block_samples; j++) { buff_blocks[i]->data[j] += complex_2N_buffer[2*output_count]; //add only the real part into the previous results output_count++; } } //now write in the newest data into the last block, overwriting any garbage that might have existed there for (int j = 0; j < audio_block_samples; j++) { buff_blocks[N_BUFF_BLOCKS - 1]->data[j] = complex_2N_buffer[2*output_count]; //overwrite with the newest data output_count++; } //send the oldest data. Don't issue the release command here because we will release it the next time through this routine //transmit(buff_blocks[0]); //don't release this buffer because we re-use it every time this is called return buff_blocks[0]; //send back the pointer to this audio block...but don't release it because we'll re-use it here };