i'm using ECU to remove echo, but it seems the echo wasn't removed, the output data is same as input data.
does this version support linear pcm ? or it only support alaw/ulaw compressed pcm ?
volib version : 2_0_0_3
ecu version : 10_92_0_4
my code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "ti/mas/ecu/ecu.h"
#define __TI_DSP__
#include "omap_basetype.h"
#include "module.h"
#define MEM_ALIGN(buf, type, size, align, err)\
{\
int sz=sizeof(type)*(size);\
buf = (type *) C6RUN_MEM_memalign (align, sz);\
if (buf == NULL)\
{\
printf("malloc fail, %s:%d\n", FILE_LINE);\
err;\
}\
else\
{\
memset(buf, 0, sz);\
}\
}
#define SAMPLES_MS (8)
#define MS_2_SAMPLES(ms) ((ms)*SAMPLES_MS)
ecuContext_t ecuContext =
{
NULL, //vfnptr exception; /**< For exception function pointer (typecast internally) */
NULL, //void (*debugStrmWrite) (tuint id, tuint n, tuint chan, void *vptr, tuint type);
NULL, //void (*mipsEcuInstEvt) (void *inst, tint event); /**< MAG ECU event handler */
NULL, //void (*srchPrep) (tuint ID, tint event); /**< search preparation */
NULL, //void (*sendOutFcn) (void *targetInst, void *send_out_ptr); /**< Send out function pointer */
NULL, //void (*receiveOutFcn) (void *targetInst, void *receive_out_ptr); /**< Receive out function pointer */
MS_2_SAMPLES(20), //tint max_samples_per_frame; /**< Maximum number of samples per frame */
MS_2_SAMPLES(128), //tint max_filter_length; /**< Maximum filter length in taps */
MS_2_SAMPLES(32), //tint max_filter_seg_length; /**< Maximum filter segment buffer length in taps */
3, //tint max_filter_seg_count; /**< Maximum allowed active filter segments */
MS_2_SAMPLES(0), //tint max_y2x_delay; /**< Maximum extra system delay in samples */
0L, //tulong expanded_bf; /**< Bitfield representing those portions of the delay line already expanded. */
NULL, //linSample *rxout_buf_base; /**< Pointer to base of the scratch delay line */
NULL, //linSample *expand_ptr; /**< TDM aligned pointer within scratch delay line */
NULL, //tword *pack_ptr; /**< TDM aligned pointer within packed delay line */
};
void *ecuInst=NULL;
tint ecuNbufs;
ecomemBuffer_t *gecuBufs;
int ecu_init()
{
#define ERR return -1
int i;
tint stat;
const ecomemBuffer_t *bufs;
ecuNewConfig_t ecuCfgNew;
ecuConfig_t ecuCfg;
ecuConfigParam_t cfgParam;
stat = ecuGetSizes (&ecuNbufs, &bufs, (void *)NULL);
CHK_COND(stat != ecu_NOERR, ERR);
//print_ecomemBuffer(ecuNbufs, bufs);
MEM_ALIGN(gecuBufs, ecomemBuffer_t, ecuNbufs, 1, ERR);
memset(gecuBufs, 0, ecuNbufs*sizeof(ecomemBuffer_t));
for (i=0;i<ecuNbufs;i++)
{
gecuBufs[i] = bufs[i];
gecuBufs[i].base = NULL;
if (gecuBufs[i].size > 0)
{
gecuBufs[i].volat = FALSE;
MEM_ALIGN(gecuBufs[i].base, tword, gecuBufs[i].size, 1<<gecuBufs[i].log2align, break);
}
}
print_ecomemBuffer(ecuNbufs, gecuBufs);
ecuCfgNew.ID = 0;
stat = ecuNew (&ecuInst, ecuNbufs, gecuBufs, &ecuCfgNew);
CHK_COND(stat != ecu_NOERR, ERR);
ecuCfg.cfgParam = &cfgParam;
ecuCfg.y2x_delay = MS_2_SAMPLES(0);
ecuCfg.samples_per_frame = ecuContext.max_samples_per_frame;
cfgParam.filter_length = ecuContext.max_filter_length;
cfgParam.noise_level = 0; /* Use default (-70) if fixed */
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 */
ecuOpen (ecuInst, &ecuCfg);
return 0;
}
int ecu_close()
{
int i;
/*for (i=0;i<ecuNbufs;i++)
{
FREE_PRV(gecuBufs[i].base);
}*/
//FREE_PRV(gecuBufs);
ecuClose(ecuInst);
ecuDelete(&ecuInst, ecuNbufs, gecuBufs);
return 0;
}
static s8 as8FileCap[] = "/mnt/net/omap/dev0_O_20090415_015931.pcm";
static s8 as8FilePly[] = "/mnt/net/omap/dev0_S_20090415_015931.pcm";
static s8 as8FileOut[] = "/mnt/net/omap/aec.pcm";
int test_aec_dsp()
{
#define ERR return -1
#define FRAME_MS 20
#define ECHO_MS 200
#define MALLOC MALLOC_PRV_3
#define FREE FREE_PRV_3
FILE *ptFileCap, *ptFilePly, *ptFileOut;
s16 *ps16Cap, *ps16Ply, *ps16Out;
s32 s32SampleRate, s32FrmLen, s32Frm, s32FrmEcho;
void *ptAEC;
DECLARE_TICK(tick_s);
DECLARE_TICK(tick_e);
int tick_us=0;
printf("DSP Compile : %s,%s\n", __DATE__, __TIME__);
PRNT_LINE;
s32SampleRate = 8000;
s32FrmLen = s32SampleRate*FRAME_MS/1000;
s32FrmEcho = ECHO_MS / FRAME_MS;
OPEN_FILE(ptFileCap, as8FileCap, "rb", ERR);
OPEN_FILE(ptFilePly, as8FilePly, "rb", ERR);
OPEN_FILE(ptFileOut, as8FileOut, "wb", ERR);
MALLOC(ps16Cap, ps16Ply, ps16Out, s16, s32FrmLen, ERR);
ecu_init();
#if 1
s32Frm = 0;
while(1)
{
RW_FILE(fread, ptFileCap, ps16Cap, s32FrmLen, break);
RW_FILE(fread, ptFilePly, ps16Ply, s32FrmLen, break);
READ_TICK(tick_s);
ecuSendIn(ecuInst, ps16Cap, ps16Ply, ps16Out);
READ_TICK(tick_e);
CALC_TICK(tick_s, tick_e, tick_us);
printf("C %d %d %d %d\n", ps16Cap[0], ps16Cap[1], ps16Cap[2], ps16Cap[3]);
printf("P %d %d %d %d\n", ps16Ply[0], ps16Ply[1], ps16Ply[2], ps16Ply[3]);
printf("O %d %d %d %d\n", ps16Out[0], ps16Out[1], ps16Out[2], ps16Out[3]);
RW_FILE(fwrite, ptFileOut, ps16Out, s32FrmLen, break);
printf("[%5d] %d us, \n", (int)s32Frm, (int)tick_us);
s32Frm++;
//if (s32Frm > 200) { break; }
}
#endif
ecu_close();
CLOSE_FILE_3(ptFileCap, ptFilePly, ptFileOut);
FREE(ps16Cap, ps16Ply, ps16Out);
PRINT_MEM_SHR;
PRNT_LINE;
return 0;
#undef ERR
}