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.

TMS320C5535: AEC-AER Library

Part Number: TMS320C5535

Hello,

we want to do echo cancellation on eZdsp5535 with 1 single microphone by using aec-aer library. I coded a framework which does i2s audio data io via dma and uses dsp bios. As example code i used http://processors.wiki.ti.com/index.php/C55x_CSL_Audio_Pre-Processing. Now i want to integrate aer echo cancellation algorithms, but i couldn't find a simple example for that.

I have some questions:

1. It is mentioned that cache must be flushed on every algorithm call on C55, but C55 doesn't have a data cache?!

2. http://processors.wiki.ti.com/index.php/C55x_CSL_Audio_Pre-Processing works with xdais. Is this just a xdais wrapper for the aer algos? Do we need to implement xdais too? 

3. I thought calling the interface functions of the lib (aerCreate(), aerNew(), aerOpen(), aerReceiveIn(), aerSendIn()) should be enough. But the example simulation code in the aer lib package is very huge and I couldn't get which parts are really needed for our application?!

Thanks in advance

Marc

  • Hi Marc,

    I've notified the sw team. they will post their feedback directly here.

    Best Regards,
    Yordan
  • Marc,

    We are looking into your questions and shall get back to you.

    Lali
  • Hello,

    we have connected 2 eZdsp5535 boards via i2s and  synchronized the clocks. The software reads in i2s audio data from adc codec (mic) and transfers it to the other board via i2s. The other board reads in the data via i2s and writes it to the dac codec (speaker). The other way round, we have the same procedure. So at the moment we have 2 intercom units which can talk full duplex in handsfree mode.

    In the software all data transfers are done via dma. We use dsp bios and have an algorithm task. As template we used this example http://processors.wiki.ti.com/index.php/C55x_CSL_Audio_Pre-Processing.

    Now we want to integrate echo cancellation algorithm (aer/aec library). As template we use aertest_c55l project in the aer library folder. Now we have an issue with placing the aer buffers into memory via linker command file. The aertest_c55l project has a linker command file, but since we use dsp bios in our application, we cannot use this file. In our .tcf file SARAM, DARAM and VECT are created. Could you please help us in placing the buffers into memory, so that all requirements mentioned in aer integration guide are met? In the first step, we want to use aer without agc or drc. All buffers should be allocated statically, like in the aertest_c55l project.

    1. How can we define memory sections where data buffers of aer are placed (dsp bios is used!)? How can buffers be placed to different blocks? Requirements of aer integration guide page 15 should be met.

    2. How can we define memory sections where aer code is placed? Assembler code in internal RAM, C code in external RAM.

    We appreciate your help

    Marc

  • Marc,

    Apologies for the long lapse since my last reply. Its difficult to support your AEC use-case since we don't have a working example that's shareable on e2e. Are you working with a local TI sales rep?
    Have you made any progress since your last correspondence?

    Lali
  • Hello,

    thanks for your reply. I am working on other projects at the moment. I still don't know how to place the buffers in a bios application. Perhaps I can post this question in dsp bios forum.

    I coded an audio framework and embedded the aer/aec algos. The application runs and the algos do echo cancellation. I didn't tune the parameters so far. I just wanted to see if everything runs. When algos are active, the sound is scrambled in one direction. Perhaps this is due to buffers not mapped correctly or due to wrong parameters?! In the other direction sound is good. When algos are turned off, sound is good in both directions.

    As parameter set I used the following which are copied from aer demo application.

    Bool aerAlgo_ConfigParams(void * inst)
    {
    aerControl_t aer_ctl;
    tint error_code;

    /* valid bitfield 0 */
    aer_ctl.valid_bitfield_0 = aer_CTL_VALID0_MODES_CTL0
    | aer_CTL_VALID0_MODES_CTL1
    | aer_CTL_VALID0_MODES_CTL2
    | aer_CTL_VALID0_Y2X_DELAY
    | aer_CTL_VALID0_SAMPLING_RATES
    | aer_CTL_VALID0_TAIL_LENGTH
    | aer_CTL_VALID0_TX_AG_CHG_DELAY
    | aer_CTL_VALID0_RX_AG_CHG_DELAY
    | aer_CTL_VALID0_TX_AG_CHG_INTERP
    | aer_CTL_VALID0_PHONE_MODE
    | aer_CTL_VALID0_RX_ANALOG
    | aer_CTL_VALID0_TX_ANALOG
    | aer_CTL_VALID0_RX_DIGITAL
    | aer_CTL_VALID0_TX_DIGITAL
    | aer_CTL_VALID0_RX_EQ_PARAMS
    | aer_CTL_VALID0_TX_EQ_PARAMS;

    /*
    aer_ctl.modes_0.mask = 0xffff;
    aer_ctl.modes_0.value = 0x188f;
    aer_ctl.modes_1.mask = 0xffff;
    aer_ctl.modes_1.value = 0xc1ce;
    aer_ctl.modes_2.mask = 0xffff;
    aer_ctl.modes_2.value = 0x001d;
    */

    aer_ctl.modes_0.mask = 0xffff;
    aer_ctl.modes_0.value = 0x0007;
    aer_ctl.modes_1.mask = 0xffff;
    aer_ctl.modes_1.value = 0x0000;
    aer_ctl.modes_2.mask = 0xffff;
    aer_ctl.modes_2.value = 0x0000;

    aer_ctl.y2x_delay = AER_SIM_PIU_DEL_RX + AER_SIM_PIU_DEL_TX - AER_SIM_SIU_Y2X_DEL_ADJ - 1;
    aer_ctl.srate_bitfield = 7;
    aer_ctl.tail_length = 800; /* 800 = 100msec/125usec */
    aer_ctl.delay_tx_ag_chg = AER_SIM_PIU_DEL_TX + 1;
    aer_ctl.delay_rx_ag_chg = AER_SIM_PIU_DEL_RX + 1;
    aer_ctl.num_samp_interp = 5;
    aer_ctl.phone_mode = aer_PHM_HF;
    aer_ctl.gain_rx_analog = 0; //AER_SIM_HF_MICGAIN_0dB - 16;
    aer_ctl.gain_tx_analog = 0; //AER_SIM_HF_SPKGAIN_0dB - 32;
    aer_ctl.gain_rx_digital = 0; //16;
    aer_ctl.gain_tx_digital = 0; //32;
    aer_ctl.rxeq_params = (aerEqConfig_t *)&sampleEqBqParamsRx;
    aer_ctl.txeq_params = (aerEqConfig_t *)&sampleEqBqParamsTx;

    /* valid bitfield 1 */
    aer_ctl.valid_bitfield_1 = aer_CTL_VALID1_NLP_CLOSS_TARGET
    | aer_CTL_VALID1_NLP_TX_CLIPAGG
    | aer_CTL_VALID1_NLP_LINATTN_MAX_ERLE
    | aer_CTL_VALID1_NLP_CLIPPER_MAX_ERLE
    | aer_CTL_VALID1_NLP_TOTAL_LINATTN_MIN
    | aer_CTL_VALID1_NLP_RX_LINATTN_MIN
    | aer_CTL_VALID1_NLP_RX_LINATTN_MAX
    | aer_CTL_VALID1_NLP_TX_LINATTN_MIN
    | aer_CTL_VALID1_NLP_TX_LINATTN_MAX
    | aer_CTL_VALID1_NLP_TX_IN_TC
    | aer_CTL_VALID1_NLP_TX_OUT_TC
    | aer_CTL_VALID1_NLP_RX_IN_TC
    | aer_CTL_VALID1_NLP_RX_OUT_TC
    | aer_CTL_VALID1_GAIN_SPLIT_TC
    | aer_CTL_VALID1_CNG_RX_LEVEL
    | aer_CTL_VALID1_CNG_TX_LEVEL;
    aer_ctl.nlp_combloss_target = 900;
    aer_ctl.nlp_clip_agg_l2 = 6;
    aer_ctl.nlp_linattn_max_erle = 27;
    aer_ctl.nlp_clipper_max_erle = 27;
    aer_ctl.nlp_total_linattn_min = 2;
    aer_ctl.nlp_rx_linattn_min = 1;
    aer_ctl.nlp_rx_linattn_max = 12;
    aer_ctl.nlp_tx_linattn_min = 1;
    aer_ctl.nlp_tx_linattn_max = 12;
    aer_ctl.nlp_tx_in_tc = 5;
    aer_ctl.nlp_tx_out_tc = 5;
    aer_ctl.nlp_rx_in_tc = 5;
    aer_ctl.nlp_rx_out_tc = 5;
    aer_ctl.gain_split_tc = 5;
    aer_ctl.cng_rx_level = -60;
    aer_ctl.cng_tx_level = -60;


    /* valid bitfield 2 */
    aer_ctl.valid_bitfield_2 = aer_CTL_VALID2_TX_FDNLP_MSEC_DELAY
    | aer_CTL_VALID2_TX_FDNLP_BIN_LO1
    | aer_CTL_VALID2_TX_FDNLP_BIN_LO2
    | aer_CTL_VALID2_TX_FDNLP_BIN_HI1
    | aer_CTL_VALID2_TX_FDNLP_BIN_HI2
    | aer_CTL_VALID2_TX_FDNLP_CNG_MAX
    | aer_CTL_VALID2_NR_FBIN1_LIM
    | aer_CTL_VALID2_NR_FBIN2_LIM
    | aer_CTL_VALID2_NR_FBAND1_MAX_ATTEN
    | aer_CTL_VALID2_NR_FBAND2_MAX_ATTEN
    | aer_CTL_VALID2_NR_FBAND3_MAX_ATTEN
    | aer_CTL_VALID2_NR_SIG_UPD_RATE_MAX
    | aer_CTL_VALID2_NR_SIG_UPD_RATE_MIN
    | aer_CTL_VALID2_NR_NOISE_THRESH
    | aer_CTL_VALID2_NR_NOISE_HANGOVER;

    aer_ctl.txfdnlp_msec_delay = 6;
    aer_ctl.txfdnlp_bin_lo1 = 2;
    aer_ctl.txfdnlp_bin_lo2 = 5;
    aer_ctl.txfdnlp_bin_hi1 = 60;
    aer_ctl.txfdnlp_bin_hi2 = 62;
    aer_ctl.txfdnlp_cng_max = -62;
    aer_ctl.nr_fbin1_lim = 12;
    aer_ctl.nr_fbin2_lim = 40;
    aer_ctl.nr_fband1_max_atten = 12;
    aer_ctl.nr_fband2_max_atten = 12;
    aer_ctl.nr_fband3_max_atten = 12;
    aer_ctl.nr_sig_upd_rate_max = 32000;
    aer_ctl.nr_sig_upd_rate_min = 30000;
    aer_ctl.nr_noise_thresh = -70;
    aer_ctl.nr_noise_hangover = 100;

    /* valid bitfield 3 */
    aer_ctl.valid_bitfield_3 = aer_CTL_VALID3_COH_HANGOVER
    | aer_CTL_VALID3_COH_RATIO_THRESH
    | aer_CTL_VALID3_COH_CNT_THRESH
    | aer_CTL_VALID3_HLC_THRESHOLD
    | aer_CTL_VALID3_HLC_RAMP_OUT_TC
    | aer_CTL_VALID3_HLC_POWER_TC
    | aer_CTL_VALID3_THRESH_RX_NLD
    | aer_CTL_VALID3_THRESH_NOISE_RX
    | aer_CTL_VALID3_THRESH_NOISE_TX
    | aer_CTL_VALID3_HANGOVER_RXTOTX
    | aer_CTL_VALID3_HANGOVER_TXTORX
    | aer_CTL_VALID3_TX_SLIM_MODE
    | aer_CTL_VALID3_RX_SLIM_MODE
    | aer_CTL_VALID3_NG_HANGOVER
    | aer_CTL_VALID3_NG_RAMPIN_PERIOD
    | aer_CTL_VALID3_NG_NOISE_LEVEL;
    aer_ctl.coh_hangover = 500;
    aer_ctl.coh_ratio_thresh = 7000;
    aer_ctl.coh_cnt_thresh = 25;
    aer_ctl.thresh_hlc = -12;
    aer_ctl.ramp_out_tc_hlc = 500;
    aer_ctl.power_tc_hlc = 2;
    aer_ctl.thresh_rx_nld = 32500;
    aer_ctl.thresh_rx_noise = 6000;
    aer_ctl.thresh_tx_noise = 6000;
    aer_ctl.hangover_rx_to_tx = 20;
    aer_ctl.hangover_tx_to_rx = 20;
    aer_ctl.tx_slim_mode = 1;
    aer_ctl.rx_slim_mode = 1;
    aer_ctl.hangover_ng = 500;
    aer_ctl.rampin_period_ng = 700;
    aer_ctl.noise_level_ng = -65;

    /*== AER valid bitfield 4 ==*/
    aer_ctl.valid_bitfield_4 = aer_CTL_VALID4_DT_THRESH
    | aer_CTL_VALID4_CLIP_SCALE
    | aer_CTL_VALID4_DT_HANGOVER;
    aer_ctl.dt_thresh = 80;
    aer_ctl.clip_scale_curve = 0x30405060;
    aer_ctl.dt_hangover = 10;

    error_code = aerControl (inst, &aer_ctl);

    if(error_code != aer_NOERR) {
    printf("AER parameters configuration error in aer_sim_test_api()!\n");
    return FALSE;
    }

    return TRUE;

    } /* aer_sim_test_api */

    In our intercom hardware device, the speaker and mic are mounted in a cube, both looking in the same direction. Do you have a parameter set for this application as a starting point for tuning? There are lots of parameters which must be set and we don't know which values are valid for us. Also we don't know which parameters must be set explicitly via aerControl() and which have internal default values. 

    Thanks and have e nice day

    Marc

  • Hi Marc,

    When you said " the sound is scrambled in one direction.  In the other direction sound is good", which direction is good and which is bad? We refer speaker play out as the receive direction and microphone input as the send direction. 

    Some other information that may help you:

    1. AER_Quick_Tuning_Guide.pdf in the docs folder can guide you for basic tuning

    2. AER_Integration_Guide.pdf in the docs folder can help you with memory placement. Also, there is a simulation test with linker command file packages\ti\mas\aer\test\lnkr\c55l\aertest_c55l.cmd, which can be used as a reference of memory buffer placement. 

    Regards,

    Jianzhong