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.

Hi Ahmed,

Apologies for the delay in response. I am not sure whether you are still looking into it. I was going through your code and have following concerns,

1.The Below code section copies the 256 coefficients from 8192, For next block, Start of the coefficients would be offsetted 256 bytes, Is it properly taken care

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

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

}

2.For one block overlap add code looks fine, but output data is not available just after one block. You have to perform the overlap and add to all the blocks and then extract the data . In the code you have attached, I am not sure whether this is properly taken care. I can see that you are always adding the current result with previous one. But you are not supposed to just add the things together. You are supposed to only add overlapping sections by using a delay line . So I think there can be some problem here. Please let me know if I am missing something here or misunderstanding your logic.

Below is the pseudo code for entire algorithm, can you please cross check whether everything is taken care,

1. Get SAMPLES_PER_CHAN number of data points, Zero extend it to FFT_SIZE.Take the FFT of data points(x[k])

2. Loop the below steps for number of blocks(BLOCK NO)

a. Get SAMPLES_PER_CHAN size FFT coefficient(h[k]), Zero extend it to FFT_SIZE, Take the FFT of the coefficients

b.perform Y[k]= H[k].X[k]

c.perform IIFT of the Y[k]

d.Perform Overlap and add using a DELAY LINE buffer. This delay line should have size equal to Total taps+SAMPLE_PER_CHAN .Add Y[n] to DELAY LINE buffer at an offset decided by BLOCK NO.

3. After performing the overlap and add to all the Blocks of Coefficients, Extract first SAMPLES_PER_CHAN number of data from delay line. This will the required output.

4.Shift the delay line left by the SAMPLE_PER_CHAN. Append SAMPLE_PER_CHAN zeros at the end.

5.Repeat from step 1 for next SAMPLES_PER_CHAN number of data points.

Thanks,

Sachin