I am attempting to get the ECU module in the VoLIB to work on TMS320DM6446 processor. ecuNew function call returns: ecu_NOMEMORY
Any pointers or tips would be greatly appreciated.
For reference, here is the 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 *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
#define ecu_SEARCH_FILTER_BUF 7
#define ECU_CHAN_COUNT 1
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 tst_ecu_inst[ECU_CHAN_COUNT];
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 */
0, //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[ECU_CHAN_COUNT];
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 tst_ecu_new(int chan) {
tint stat, ecuNbufs;
const ecomemBuffer_t *bufs;
tst_ecu_inst[chan].ecu_Inst = NULL;
stat = ecuGetSizes(&ecuNbufs, &bufs, (void *) NULL);
if (stat != ecu_NOERR) {
return stat;
}
tst_ecu_inst[chan].ecu_buffers = (ecomemBuffer_t*) calloc(ecuNbufs, sizeof(ecomemBuffer_t));
vheap = mhmCreate(siu_voice_heap, SIU_VOICE_HEAP_SIZE, 0);
ecu_set_buffer(bufs, tst_ecu_inst[chan].ecu_buffers, ecuNbufs, chan);
tst_ecu_inst[chan].ecuCfgNew.ID = siuMakeID (SIU_MID_ECU, chan);
stat = ecuNew(&(tst_ecu_inst[chan].ecu_Inst), ecuNbufs,
tst_ecu_inst[chan].ecu_buffers, &(tst_ecu_inst[chan].ecuCfgNew));
if (stat != ecu_NOERR) {
ecu_init_result = stat;
return stat;
}
return 0;
}
int tst_ecu_open(int chan) {
ecuConfigParam_t cfgParam;
tst_ecu_inst[chan].ecuCfg.cfgParam = &cfgParam;
tst_ecu_inst[chan].ecuCfg.y2x_delay = 40; /* One frame default y2x delay */
tst_ecu_inst[chan].ecuCfg.samples_per_frame = 10 * 8; /* 5ms default frame duration */
tst_ecu_inst[chan].ecuCfg.pcm_zero = 0; //(0x55D5);
tst_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(tst_ecu_inst[chan].ecu_Inst, &(tst_ecu_inst[chan].ecuCfg));
return 0;
}
int ecu_init() {
int chan;
int res;
ecu_init_result = 0;
memset(tst_ecu_inst, 0, sizeof(struct ecu_inst_params) * ECU_CHAN_COUNT);
for (chan = 0; chan < ECU_CHAN_COUNT; chan++) {
res = tst_ecu_new(chan);
tst_ecu_open(chan);
return 0;
}
}