I am attempting to get the ECU module in the VoLIB to work on TMS320C6A8168 processor.
But it does not seem to work.
I feel like ECU buffer problems.
I want to consult on how to initialize the ECU module(ECU buffer).
Or give me some suggestions to make the ECU work properly.
Here I write some code:
#define siuMakeID(mid,chnum) ((tuint)(mid)<<8|(tuint)(chnum))
#define SIU_MAX_FRAME_LENGTH 80 /* 10ms maximum frame duration */
#define SIU_MAX_ECU_FILTER_LENGTH 1024 /* maximum echo tail in taps */
#define SIU_MAX_ECU_FLTSEG 3 /* maximum number of filter segments */
#define SIU_MAX_ECU_FLTSEG_LENGTH 256 /* maximum taps for all filter segments */
#define SIU_MAX_SYSTEM_DELAY 320 /* maximum extra system delay in samples */
#define SIU_VOICE_HEAP_SIZE 2048
tword siu_voice_heap[SIU_VOICE_HEAP_SIZE];
//void *cheap;
void *vheap;
/* Module ID's */
#define SIU_MID_SIU 0x01 /* SIU module */
#define SIU_MID_VCU 0x02 /* VCU module */
#define SIU_MID_VCA 0x03 /* VCA modules */
#define SIU_MID_PIU 0x04 /* PIU module */
#define SIU_MID_ECU 0x05 /* ECU module */
/* Buffer numbers. Ensure that these coincide with #defines in ecuinit.c */
#define ecu_FG_FLTSEG 1
#define ecu_BG_FLTSEG 2
#define ecu_BG_E_BUF 3
#define ecu_RECEIVE_IN 4
#define ecu_EXPAND_DL_BUF 5
#define ecu_BG_UPDATE_BUF 6
struct ecu_inst_params{
tuint ID;
void *ecu_Inst; /* Signal limiter Instance */
ecomemBuffer_t *ecu_buffers;
ecuConfig_t ecuCfg;
ecuControl_t ecuCtl;
ecuNewConfig_t ecuCfgNew;
tint ecu_rx_buffer[80];
tint ecu_tx_buffer[80];
tint ecu_ec_buffer[80];
};
struct ecu_inst_params ys_ecu_inst[64];
void my_exception(tuint _id, tuint _type, tuint _code, tuint _length, tuint *data)
{
System_printf("id: %x, type: %d, code: %d, len: %d", _id, _type, _code, _length);
}
ecuContext_t ecuContext = {
(vfnptr)my_exception,
NULL, /* Debug streaming function pointer */
NULL,
NULL, /* Search filter swapping function */
NULL,//ecu_send_out, /* Send out function pointer */
NULL,//piuReceiveIn, /* Receive out function pointer */
SIU_MAX_FRAME_LENGTH, /* Maximum number of samples per frame */
SIU_MAX_ECU_FILTER_LENGTH, /* Maximum filter length in taps */
SIU_MAX_ECU_FLTSEG_LENGTH, /* Maximum filter segment buffer length in taps */
SIU_MAX_ECU_FLTSEG, /* Maximum allowed active filter segments */
SIU_MAX_SYSTEM_DELAY + SIU_MAX_FRAME_LENGTH,
/* 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 */
};
typedef struct {
Fract ecu_buf_1[512];
Fract ecu_buf_2[512];
linSample ecu_buf_3[80];
linSample ecu_buf_4[2048];
linSample ecu_buf_5[4096];
Fract ecu_buf_6[2048];
Fract ecu_buf_14[2048];
}ecu_buf_t;
ecu_buf_t ecu_buf[64];
void ecu_set_buffer(const ecomemBuffer_t *bufs, ecomemBuffer_t *ecuBufs, tint ecuNbufs, int inst_num)
{
int i;
for (i = 0; i < ecuNbufs; i++) {
ecuBufs[i] = bufs[i];
if (i == ecu_FG_FLTSEG) { /* FG Filter */
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_1[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_1);
}
else if (i == ecu_BG_FLTSEG) { /* BG Filter */
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_2[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_2);
}
else if (i == ecu_BG_E_BUF) { /* BG Error Buffer IRAM */
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_3[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_3);
}
else if (i == ecu_RECEIVE_IN) { /* ECU's recv-in buffer is aligned! */
ecuBufs[i].volat = FALSE;
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_4[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_4);
}
else if (i == ecu_EXPAND_DL_BUF) { /* ECU's recv-in buffer is aligned! */
ecuBufs[i].volat = TRUE;
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_5[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_5);
}
else if (i == ecu_BG_UPDATE_BUF) { /* BG Work Buffer IRAM */
if (ecuBufs[i].size > 0) {
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_6[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_6);
}
else { /* Float version may not use this buffer */
ecuBufs[i].base = NULL;
ecuBufs[i].size = 0;
}
}
else if (i == ecu_SEARCH_FILTER_BUF) { /* Search filter buffer IRAM */
ecuBufs[i].volat = FALSE;
ecuBufs[i].base = &(ecu_buf[inst_num].ecu_buf_14[0]);;
ecuBufs[i].size = sizeof(ecu_buf[inst_num].ecu_buf_14);
}
else {
if (ecuBufs[i].size > 0) {
ecuBufs[i].volat = FALSE;
ecuBufs[i].base = (mhmAlloc (vheap, bufs[i].size));
}
else { /* no buffer allocated if size zero or less */
ecuBufs[i].base = NULL;
ecuBufs[i].size = 0;
}
}
}
}
int ys_ecu_new(int chan)
{
tint stat, ecuNbufs;
const ecomemBuffer_t *bufs;
stat = ecuGetSizes (&ecuNbufs, &bufs, (void *)NULL);
if (stat != ecu_NOERR) {
Log_print1(Diags_EXIT,"[+X] ecuGetSizes failed >return %d\n",stat);
return stat;
}
ys_ecu_inst[chan].ecu_buffers = (ecomemBuffer_t*)calloc (ecuNbufs,sizeof(ecomemBuffer_t));
if(ys_ecu_inst[chan].ecu_buffers == NULL) {
Log_print0(Diags_EXIT,"[+X] the ecu_buffers allocated failed \n");
return -1;
}
vheap = mhmCreate (siu_voice_heap, SIU_VOICE_HEAP_SIZE,0);
ecu_set_buffer(bufs, ys_ecu_inst[chan].ecu_buffers, ecuNbufs, chan);
ys_ecu_inst[chan].ecuCfgNew.ID = siuMakeID (SIU_MID_ECU, chan);
stat = ecuNew (&(ys_ecu_inst[chan].ecu_Inst), ecuNbufs, ys_ecu_inst[chan].ecu_buffers, &(ys_ecu_inst[chan].ecuCfgNew));
if (stat != ecu_NOERR) {
Log_print2(Diags_EXIT, "[+X] ecuNew %d failed > return %d\n", chan, stat);
return stat;
}
return 0;
}
int ys_ecu_open(int chan)
{
ecuConfigParam_t cfgParam;
ys_ecu_inst[chan].ecuCfg.cfgParam = &cfgParam;
ys_ecu_inst[chan].ecuCfg.y2x_delay = 40; /* One frame default y2x delay */
ys_ecu_inst[chan].ecuCfg.samples_per_frame = 10*8; /* 5ms default frame duration */
ys_ecu_inst[chan].ecuCfg.pcm_zero = 0;//(0x55D5);
ys_ecu_inst[chan].ecuCfg.pcm_expand_tbl = NULL;//&_a2lin[0];
cfgParam.filter_length = SIU_MAX_ECU_FILTER_LENGTH ; /* 128ms default ECU tail */
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 (ys_ecu_inst[chan].ecu_Inst, &(ys_ecu_inst[chan].ecuCfg));
return 0;
}
int ecu_init()
{
int chan;
int res;
memset(ys_ecu_inst, 0, sizeof(struct ecu_inst_params) * 64);
for (chan=0; chan<64; chan++) {
res = ys_ecu_new(chan);
if(res != 0){
Log_print1(Diags_EXIT, "[+X] ys_ecu_new faild> return (0x%x)", res);
return res;
}
ys_ecu_open(chan);
return 0;
}
int ys_ecu_process(int chan, int codec, short* rx, short * tx, short * ec)
{
int i;
for(i = 0; i <80; i ++){
ys_ecu_inst[chan].ecu_rx_buffer[i] = rx[i];
ys_ecu_inst[chan].ecu_tx_buffer[i] = tx[i];
}
ecuSendIn(ys_ecu_inst[chan].ecu_Inst, ys_ecu_inst[chan].ecu_rx_buffer, ys_ecu_inst[chan].ecu_tx_buffer, ys_ecu_inst[chan].ecu_ec_buffer);
for(i = 0; i <80; i ++){
ec[i] =ys_ecu_inst[chan].ecu_ec_buffer[i];
}
return 0;
}