This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Help to run ECU (Echo Canceller) correctly

Dear Charlie and TI support team

I'm using CCS V5.1.1 to run ECU testing (I wrote these codes based on references on TI forum site). 

Some additional information: 

- I'm testing on TI EVM6472 platform. 

- ECU version: 10.92.1.0

Here is my code: 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ti/mas/ecu/ecu.h>
#include <ti/mas/types/types.h>
#include "hyb.h"
#include "mua.h"

// Parameters
#define ECHO_CANCEL_FRAME_SIZE 80 // Frame Length
#define ECU_SEARCH_FILTER_LENGTH 1024 // Filter Length
#define ECU_FILTER_SEGMENT_COUNT 3 // Filter Segment Count
#define ECU_FILTER_SEGMENT_LENGTH 256 // Filter Segment Length
#define Y2X_DELAY 80 // Delay

// ECU Parameters
struct ecu_params{
tuint ID;
void *ecu_Inst; //Signal limiter Instance
ecomemBuffer_t *ecu_buffers;
ecuConfig_t ecuCfg;
ecuControl_t ecuCtl;
ecuNewConfig_t ecuCfgNew;

linSample ecu_rx_buffer[80];
linSample ecu_tx_buffer[80];
linSample ecu_ec_buffer[80];
};

// EcuContext
ecuContext_t ecuContext = {
NULL, // Exception handler
NULL, // Debug streaming function pointer
NULL, // MIPS Agent open/close event handler
NULL, // Search filter swapping function
NULL, // Send out function pointer
NULL, // Receive out function pointer
ECHO_CANCEL_FRAME_SIZE, // Maximum number of samples per frame
ECU_SEARCH_FILTER_LENGTH , // Maximum filter length in taps
ECU_FILTER_SEGMENT_LENGTH, // Maximum filter segment buffer length in taps
ECU_FILTER_SEGMENT_COUNT, // Maximum allowed active filter segments
Y2X_DELAY, // Maximum y2x delay in samples
0L, // Bitfield representing those portions of the delay line already expanded.
NULL, // Pointer to base of the scratch delay line
NULL, // TDM aligned pointer within scratch delay line
NULL, // TDM aligned pointer within packed delay line
};

void main() {

linSample sinBuffer[80];
linSample rinLinear[80];
tint rinCompr[80];
tword rinBuffer[80];
tint i;
tint length = 80;

// List of Buffers
tint *InstanceBuffer;
Fract *fg_fs, *bg_fs, *bg_ub, *dt_xp, *erl_ye, *acom_ee;
Fract *bsdl, *wbs, *sb, *ssb, *sc;
tint *bg_fsdl, *fg_fsdl;
linSample *bg_er_sig, *exp_dl;
linSample *far_end_dl;


struct ecu_params echo;

// Clear data
for(i=0;i<length;i++){
echo.ecu_rx_buffer[i]=0;
echo.ecu_tx_buffer[i]=0;
echo.ecu_ec_buffer[i]=0;
sinBuffer[i] = 0;
rinCompr[i]=0;
}

// Getsize, Provide memory for all buffers
tint ecuNumberOfBuffers;
const ecomemBuffer_t *internalMemoryBuffers = NULL;
tint ecuStatus;

//Get size
ecuStatus = ecuGetSizes (&ecuNumberOfBuffers, &internalMemoryBuffers, (void *)NULL);

// Provide memory for all buffers
echo.ecu_buffers = (ecomemBuffer_t *)calloc(ecuNumberOfBuffers, sizeof(ecomemBuffer_t));

// List of Buffer memory
InstanceBuffer = (tint *) malloc(internalMemoryBuffers[0].size); //Instance Buffer
fg_fs = (Fract *) malloc(internalMemoryBuffers[1].size); //Foreground filter segment (NV)
bg_fs = (Fract *) malloc(internalMemoryBuffers[2].size); //Background filter segment (NV)
bg_er_sig = (linSample *) malloc(internalMemoryBuffers[3].size); //Background error signal (NV)
far_end_dl = (linSample *) malloc(internalMemoryBuffers[4].size); //Far End Delay Line
exp_dl = (linSample *) malloc(internalMemoryBuffers[5].size); //Expanded Delay Line
bg_ub = (Fract *) malloc(internalMemoryBuffers[6].size); //Background Update Buffer
dt_xp = (Fract *) malloc(internalMemoryBuffers[7].size); //Doubletalk x-Power
erl_ye = (Fract *) malloc(internalMemoryBuffers[8].size); //ERL y-Energy
acom_ee = (Fract *) malloc(internalMemoryBuffers[9].size); //ACOM e-Energy
bg_fsdl = (tint *) malloc(internalMemoryBuffers[10].size); //Background Filter Segment Delays/Lengths
fg_fsdl = (tint *) malloc(internalMemoryBuffers[11].size); //Foreground Filter Segment Delays/Lengths
bsdl = (Fract *) malloc(internalMemoryBuffers[12].size); //Band Split Delay Lines
wbs = (Fract *) malloc(internalMemoryBuffers[13].size); //Wide Band Scratch
sb = (Fract *) malloc(internalMemoryBuffers[14].size); //Search Buffer
ssb = (Fract *) malloc(internalMemoryBuffers[15].size); //Search Scratch Buffer
sc = (Fract *) malloc(internalMemoryBuffers[16].size); //Search Counter

echo.ecu_buffers[0] = internalMemoryBuffers[0];
echo.ecu_buffers[0].base = InstanceBuffer;
echo.ecu_buffers[1] = internalMemoryBuffers[1];
echo.ecu_buffers[1].base = fg_fs;
echo.ecu_buffers[2] = internalMemoryBuffers[2];
echo.ecu_buffers[2].base = bg_fs;
echo.ecu_buffers[3] = internalMemoryBuffers[3];
echo.ecu_buffers[3].base = bg_er_sig;
echo.ecu_buffers[4] = internalMemoryBuffers[4];
echo.ecu_buffers[4].base = far_end_dl;
echo.ecu_buffers[5] = internalMemoryBuffers[5];
echo.ecu_buffers[5].base = exp_dl;
echo.ecu_buffers[6] = internalMemoryBuffers[6];
echo.ecu_buffers[6].base = bg_ub;
echo.ecu_buffers[7] = internalMemoryBuffers[7];
echo.ecu_buffers[7].base = dt_xp;
echo.ecu_buffers[8] = internalMemoryBuffers[8];
echo.ecu_buffers[8].base = erl_ye;
echo.ecu_buffers[9] = internalMemoryBuffers[9];
echo.ecu_buffers[9].base = acom_ee;
echo.ecu_buffers[10] = internalMemoryBuffers[10];
echo.ecu_buffers[10].base = bg_fsdl;
echo.ecu_buffers[11] = internalMemoryBuffers[11];
echo.ecu_buffers[11].base = fg_fsdl;
echo.ecu_buffers[12] = internalMemoryBuffers[12];
echo.ecu_buffers[12].base = bsdl;
echo.ecu_buffers[13] = internalMemoryBuffers[13];
echo.ecu_buffers[13].base = wbs;
echo.ecu_buffers[14] = internalMemoryBuffers[14];
echo.ecu_buffers[14].base = sb;
echo.ecu_buffers[15] = internalMemoryBuffers[15];
echo.ecu_buffers[15].base = ssb;
echo.ecu_buffers[16] = internalMemoryBuffers[16];
echo.ecu_buffers[16].base = sc;
echo.ecuCfgNew.ID = 1;

//ecunew
ecuStatus = ecuNew(&(echo.ecu_Inst), ecuNumberOfBuffers, echo.ecu_buffers, &(echo.ecuCfgNew));

// Config & Ecu open
ecuConfigParam_t cfgParam;
cfgParam.filter_length = ECU_SEARCH_FILTER_LENGTH ;
cfgParam.noise_level = 0;
cfgParam.config_bitfield = ecu_ENABLE_ECHO_CANCELLER | // ENABLE ECU, ENABLE NLP, ENABLE UPDATE
ecu_ENABLE_UPDATE |
ecu_ENABLE_NLP |
ecu_ENABLE_AUTO_UPDATE |
ecu_ENABLE_SEARCH |
ecu_ENABLE_CNG_ADAPT |
ecu_ENABLE_OPNLP_DETECT;
cfgParam.config_bitfield1 = ecu_ENABLE_NLP_PHASE_RND;
cfgParam.nlp_aggress = 0; // balance performance
cfgParam.cn_config = 0; // pink noise

echo.ecuCfg.cfgParam = &cfgParam;
echo.ecuCfg.y2x_delay = 80; // One frame default y2x delay
echo.ecuCfg.samples_per_frame = 80; // 10ms default frame duration
echo.ecuCfg.pcm_zero = 0;
echo.ecuCfg.pcm_expand_tbl = NULL;

// ecuopen
ecuOpen (echo.ecu_Inst, &echo.ecuCfg);
ecuStatus = ecuControl(echo.ecu_Inst,&echo.ecuCtl);

// Read file
FILE *pt1,*pt2,*pt3;
int Fnum;

pt1 = fopen("../rin.pcm","rb");
pt2 = fopen("../sin.pcm","rb");
pt3 = fopen("../sout.pcm","wb");

for(Fnum=0;Fnum<1500;Fnum++){

fseek(pt1,Fnum*length,SEEK_SET);
fread(rinLinear,sizeof(linSample),length,pt1);
fseek(pt2,Fnum*length,SEEK_SET);
fread(sinBuffer,sizeof(linSample),length,pt2);

// Data Compression
muaTblUlawCmpr(length, rinLinear, rinCompr);

for (i=0; i<length; i++) {
rinBuffer[i] = rinCompr[i] & 0xFF;
}

// EcuSendin
ecuSendIn(echo.ecu_Inst, sinBuffer, rinBuffer, echo.ecu_ec_buffer);

fseek(pt3,Fnum*length,SEEK_SET);
fwrite(echo.ecu_ec_buffer,2,length,pt3);

printf("\n Frame %d",Fnum);
printf("\n");
for(i=0;i<length;i++){
printf("%d,",sinBuffer[i]);
}

printf("\n");
for(i=0;i<length;i++){
printf("%d,",rinBuffer[i]);
}

printf("\n");
for(i=0;i<length;i++){
printf("%d,",echo.ecu_ec_buffer[i]);
}

}
fclose(pt1);
fclose(pt2);
fclose(pt3);
}

However, the results of "echo.ecu_ec_buffer" is as same as "sinBuffer". I tried many times, but can not solve this problem.  I don't know how to run it to get correct results? Please help me.

Thank you and regards, 

Phong