AnsweredAssumed Answered

Audio overlap-add method issue Fir filter FFT convolution

Question asked by aghariani@audio-3d.com on Apr 7, 2015
Latest reply on Jun 18, 2015 by SachinV

Hi ,

 

I am trying to make an FFt convolution on the board ADSP-BF706 Eval-Kit mini, applying a filter to the input audio and i have a buffer of coeffs longer than 8192 point. I tried FIR filter with only 1024 coeffs and it works fine but it cannot work for more than that size.

So I need to use the overlapp-add method to do this but i have an issue on doing that, the output audio is not fine i have like saturation on the sound. You could see the source code just below.


I am using Fract32 type for all the algorithme, the sample rate is 48khz buffer size is 512 (256 Left + 256 Right) and i have float coeffs than i use the float_to_fr32() function to convert them all to fract32.

 

An example of implementation for only one block for the overlap add method :

#include <filter.h>

#include <fract2float_conv.h>

 

#define FFT_SIZE                       512

#define scale_method                  1

#define SAMPLES_PER_CHAN   256

complex_fract32 a_coeffsSeg[512], w[512],complexSegmentLeftIn[512] ,complexSegmentRightIn[512] ,complexSegmentLeftOut[512], complexSegmentRightOut[512];

fract32 LeftIn [512], RightIn [512];

int *block;

 

// Initialisation FFT

twidfftrad2_fr32(w, FFT_SIZE);

 

//Prepare Coeffs

for(i = 0; i < SAMPLES_PER_CHAN ; i++){

  a_coeffs[i] = float_to_fr32(*(((float*) testCoefs) + i)); // Get coeffs

}

for(; i < FFT_SIZE; i++){

  a_coeffs[i] =   0x00000000;

}

rfft_fr32(a_coeffs, a_coeffsSeg , w, 1, FFT_SIZE, &block, scale_method);

 

/* and now the process for the overlap add method

* dataIn is the input buffer

*/

i = 0;

for (n = 0; n < SAMPLES_PER_CHAN; n++){

     LeftIn  [n]  = dataIn[i++];

     RightIn[n]  = dataIn[i++];

}

for (; n < FFT_SIZE; n++){

      LeftIn [n]  = 0x00000000;

      RightIn[n] = 0x00000000;

}


rfft_fr32(LeftIn , complexSegmentLeftIn , w, 1, FFT_SIZE, &block, scale_method);

rfft_fr32(RightIn, complexSegmentRightIn, w, 1, FFT_SIZE, &block, scale_method);

 

// complex_fract32 multiplication buffleft * a_coeffsSeg and buffright * a_coeffsSeg

for ( i = 0; i < FFT_SIZE; i++){

  outL[i] = cmlt_fr32(complexSegmentLeftIn [i], a_coeffsSeg [i]);

}

for ( i = 0; i < FFT_SIZE; i++){

  outR[i] = cmlt_fr32(complexSegmentRightIn[i], a_coeffsSeg [i]);

}

 

ifft_fr32(outL , complexSegmentLeftOut , w, 1, FFT_SIZE, &block, scale_method);

ifft_fr32(outR, complexSegmentRightOut, w, 1, FFT_SIZE, &block, scale_method);

 

i = 0;

for (n = 0; n < SAMPLES_PER_CHAN; n++){

     dataOut[i++] = add_fr1x32( complexSegmentRightOut[n].re, tmpRight[n]);

     dataOut[i++] = add_fr1x32( complexSegmentLeftOut [n].re,  tmpLeft [n]);

}

for (n = 0; n < SAMPLES_PER_CHAN; n++){

     tmpRight[n] = complexSegmentRightOut[n].im;

     tmpLeft [n]  = complexSegmentLeftOut [n].im; 

}

 

Anyone could tell me if i am doing something on the wrong way.

Outcomes