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.

TMS320C5517: How to tune AER to pas an adequate level of DTMF when FE send dial tone

Part Number: TMS320C5517

Hello,

We are using aer_c55l_cpuv3_3 17_0_0_0 the latest version algorithms with the TMS320C5517 DSP for echo cancellation in our voip system. handsfree mode.  It can cancel echo very well, but the only issue is that when AER in the near end (NE)  turning on , and far end (FE) sending dial tone(450Hz), the FE  cann't receive  DTMF signal from NE.  only when FE stop sending dial tone, it can recive the DTMF signal from NE.

There seem half-duplex, not the full duplex when double talk. We follow the AER_Quick_Tuning_Guide and adjust the two main NLP parameters:

increasing nlp_combloss_target  to 32767  and decreasing nlp_clip_agg_l2 to -10, There seem no effect and only half duplex performance.

Our NE AER parameter mainly refer from aertest_c55I_C55L_COFF in hand free mode, use DRC and AGC:

    /*== AER valid bitfield 0 ==*/
    aer_ctl.valid_bitfield_0 =  aer_CTL_VALID0_MODES_CTL0
                              | aer_CTL_VALID0_MODES_CTL1
                              | aer_CTL_VALID0_RX_EQ_PARAMS
                              | aer_CTL_VALID0_TX_EQ_PARAMS;
    /* Set AER operation modes: siu_setup->aer_ctl_bitfield_0 and
       siu_setup->aer_ctl_bitfield_1 are set through simulation configuration
       file: aersimcfg.txt.
     * The mask is set to 0xffff to set all bits, either to 0 or to 1.     */
    aer_ctl.modes_0.mask  = 0xffff;
    aer_ctl.modes_0.value = 0x1887;
    aer_ctl.modes_1.mask  = 0xffff;
    aer_ctl.modes_1.value = 0x01c6;
                            
    /* Load equalizer coefficients (unity tap) in both tx and rx directions */
    aer_ctl.rxeq_params = (aerEqConfig_t *)&sampleEqBqParamsRx;
    aer_ctl.txeq_params = (aerEqConfig_t *)&sampleEqBqParamsTx;

    /*== AER valid bitfield 1 ==*/
    /* configure NLP */
    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_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  = 8192;
    aer_ctl.nlp_clip_agg_l2      = -8;
    aer_ctl.nlp_linattn_max_erle = 30;
    aer_ctl.nlp_clipper_max_erle = 30;
    aer_ctl.nlp_tx_in_tc         = 4;
    aer_ctl.nlp_tx_out_tc        = 1;
    aer_ctl.nlp_rx_in_tc         = 4;
    aer_ctl.nlp_rx_out_tc        = 1;
    aer_ctl.gain_split_tc        = 3;
    aer_ctl.cng_rx_level         = -70;
    aer_ctl.cng_tx_level         = -70;

    /*== AER valid bitfield 2 ==*/
    aer_ctl.valid_bitfield_2 =  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_NOISE_THRESH;
    aer_ctl.txfdnlp_cng_max = -40;
    aer_ctl.nr_noise_thresh = -65;
    aer_ctl.nr_fbin1_lim    = 5;
    aer_ctl.nr_fbin2_lim    = 32;
    aer_ctl.nr_fband1_max_atten = 9;
    aer_ctl.nr_fband2_max_atten = 9;
    aer_ctl.nr_fband3_max_atten = 9;
    
    /*== AER valid bitfield 3 ==*/
    aer_ctl.valid_bitfield_3 =  aer_CTL_VALID3_HLC_THRESHOLD
                              | aer_CTL_VALID3_HLC_RAMP_OUT_TC
                              | aer_CTL_VALID3_HLC_POWER_TC                              
                              | aer_CTL_VALID3_COH_HANGOVER     
                              | aer_CTL_VALID3_COH_RATIO_THRESH  
                              | aer_CTL_VALID3_COH_CNT_THRESH;
    aer_ctl.thresh_hlc      = -20;
    aer_ctl.ramp_out_tc_hlc = 700;
    aer_ctl.power_tc_hlc    = 1;
    aer_ctl.coh_hangover    = 600;
    aer_ctl.coh_ratio_thresh= 6000;
    aer_ctl.coh_cnt_thresh  = 30;

    /*== 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 = 64;
    aer_ctl.clip_scale_curve = 0x3c404050;
    aer_ctl.dt_hangover = 1;

    error_code = aerControl (aer_inst,(aerControl_t *)&aer_ctl);

    if(error_code != aer_NOERR) {
      printf("AER parameters configuration error!\n");
      exit(0);
    }
    
    /*== AGC configuration  ==*/
    agcCtl.valid_bitfield =  agc_CTL_VALID_MODES
                           | agc_CTL_VALID_SAT_THRESHOLD
                           | agc_CTL_VALID_SAT_HANGOVER
                           | agc_CTL_VALID_MIC_GAIN_MAX
                           | agc_CTL_VALID_MIC_GAIN_MIN
                           | agc_CTL_VALID_MICGAIN_SWING_MAX;  
    
    /* Set AGC operation modes: siu_setup->agc_ctl_bitfield is set through
       simulation config file: aersimcfg.txt.
     * The mask is set to 0xffff to set all bits, either to 0 or to 1.
     */
    agcCtl.modes.mask  = 0xffff;
    agcCtl.modes.value = 3;
    agcCtl.sat_threshold = AER_SIM_AGC_SAT_THRESHOLD;
    agcCtl.sat_hangover  = AER_SIM_AGC_SAT_HANGOVER;
    agcCtl.max_micgain   = AER_SIM_AGC_MICGAIN_MAX;
    agcCtl.min_micgain   = AER_SIM_AGC_MICGAIN_MIN;
    agcCtl.max_micgain_swing = AER_SIM_AGC_GAINSWING_MAX;
    
    error_code = agcControl (inst->agcHFInst,(agcControl_t *)&agcCtl);

    if(error_code != agc_NOERR) {
      printf("AGC parameters configuration error!\n");
      exit(0);
    }    

I want to know which parameters can be adjusted to achieve the full duplex or something we need to pay attention to.

Best Regards,

Dudechao
    

  • Thanks for your question, we will check and reply soon

  • Hi Arnon,

    thanks for your response.

    following is the additional information:

    in aerOpen:

    aerConfig_t aerCfg;
    tint err_code;
    aerInst_t *inst;
    GainCtl_t *g_inst = &GainCtl[chnum-1];

    inst = &aerInst[chnum-1];
    aerCfg.y2x_delay = 80;
    aerCfg.srate_bitfield = aer_SRATE_RXIN_8K|aer_SRATE_TXOUT_8K|aer_SRATE_RXOUT_TXIN_8K;
    aerCfg.delay_tx_ag_chg = 80;
    aerCfg.delay_rx_ag_chg = 80;
    aerCfg.num_samp_interp = 2;
    aerCfg.reset_bitfield = aer_RESET_FULL;
    aerCfg.valid_bitfield = aer_CFG_VALID_BITS_ALL_1;
    /* Open hands free instances */
    aerCfg.tail_length = 1600;
    aerCfg.phone_mode = aer_PHM_HF;
    err_code = aerOpen (inst->aerHFInst, &aerCfg);
    if (err_code != aer_NOERR) {
    exit(1);
    }

        aer_ctl.gain_rx_analog = 0;                                 

        aer_ctl.gain_tx_analog = 0;                                 
        aer_ctl.gain_rx_digital = 0;                                
        aer_ctl.gain_tx_digital = 0;                

    Best Regards,

    Dudechao

  • Hi Arnon,

    thanks for your response.

    following is the additional information:

    in aerOpen:

    aerConfig_t aerCfg;
    tint err_code;
    aerInst_t *inst;
    GainCtl_t *g_inst = &GainCtl[chnum-1];

    inst = &aerInst[chnum-1];
    aerCfg.y2x_delay = 80;
    aerCfg.srate_bitfield = aer_SRATE_RXIN_8K|aer_SRATE_TXOUT_8K|aer_SRATE_RXOUT_TXIN_8K;
    aerCfg.delay_tx_ag_chg = 80;
    aerCfg.delay_rx_ag_chg = 80;
    aerCfg.num_samp_interp = 2;
    aerCfg.reset_bitfield = aer_RESET_FULL;
    aerCfg.valid_bitfield = aer_CFG_VALID_BITS_ALL_1;
    /* Open hands free instances */
    aerCfg.tail_length = 1600;
    aerCfg.phone_mode = aer_PHM_HF;
    err_code = aerOpen (inst->aerHFInst, &aerCfg);
    if (err_code != aer_NOERR) {
    exit(1);
    }

        aer_ctl.gain_rx_analog = 0;                                 

        aer_ctl.gain_tx_analog = 0;                                 
        aer_ctl.gain_rx_digital = 0;                                
        aer_ctl.gain_tx_digital = 0;                

    /*== AGC configuration ==*/
    agcCtl.valid_bitfield = agc_CTL_VALID_MODES
    | agc_CTL_VALID_SAT_THRESHOLD
    | agc_CTL_VALID_SAT_HANGOVER
    | agc_CTL_VALID_MIC_GAIN_MAX
    | agc_CTL_VALID_MIC_GAIN_MIN
    | agc_CTL_VALID_MICGAIN_SWING_MAX;

    /* Set AGC operation modes: siu_setup->agc_ctl_bitfield is set through
    simulation config file: aersimcfg.txt.
    * The mask is set to 0xffff to set all bits, either to 0 or to 1.
    */
    agcCtl.modes.mask = 0xffff;
    agcCtl.modes.value = agc_CTL_MODES_ENABLE_AGC | agc_CTL_MODES_ENABLE_ADAPT;//(siu_setup->agc_ctl_bitfield;
    agcCtl.sat_threshold = 32500;//AER_SIM_AGC_SAT_THRESHOLD;
    agcCtl.sat_hangover = 20;//200msec AER_SIM_AGC_SAT_HANGOVER;
    agcCtl.max_micgain = 384;//24dB in S11.4 AER_SIM_AGC_MICGAIN_MAX;
    agcCtl.min_micgain = -384;//-24dB in S11.4 AER_SIM_AGC_MICGAIN_MIN;
    agcCtl.max_micgain_swing = 480;//30dB AER_SIM_AGC_GAINSWING_MAX;

    error_code = agcControl (inst->agcHFInst,(agcControl_t *)&agcCtl);

    Best Regards,

    Dudechao

  • Hi Dudechao,

    It can cancel echo very well, but the only issue is that when AER in the near end (NE)  turning on , and far end (FE) sending dial tone(450Hz), the FE  cann't receive  DTMF signal from NE.

    When this problem happens, do you know if AER has already converged? If not, then half duplex is possible during that period. I would recommend you to do some measurements:

    1. keep NE silent, disable AER and capture near end output when dial tone is being received. This is the pure echo.

    2. enable AER and disable NLP and capture near end output when dial tone is being received. This is the residual echo after the adaptive filter.

    3. measure the difference in power between these two captures. See how much echo reduction there is without using NLP.

    A rule of thumb is that echo reduction without using NLP should be above 20dB. If that's not the case, you'll need to investigate your system why convergence is low. If echo reduction is good (>20dB), then we can discuss about tuning the parameters.

    Another question is, how is DTMF signal generated. Is it generated by pressing the key pad? 

    Thanks and regards,

    Jianzhong

  • Hi Jianzhong,

    Thanks for your response.

    We do the measurements as your guide:

    1.keep NE silent, and set  aer_ctl.modes_0.value to 0x82 to disable AER. when dial tone is being received, the NE output level is -27dbm0.

    2. set ctl.modes_0 to 0x83 to enable AER and disable NLP. when dial tone is being received, the NE output level is almost the same: -27dbm0.

    3. set ctl.modes_0 to 0x87 to enable AER and NLP, when dial tone is being received, the NE output level is -41dbm0.

    It seem the adaptive filter is not converged.

    I check and adjust following parameter:

    1. According to  "AER_Quick_Tuning_Guard" 5.2 Trouble Shooting,1) I check the aerSendIn and make sure recv_out_sync is always lead send_in in time . 2)there is no buffer overflow or underflow.

    2. I also adjust y2x_delay from 1 to 80,  this parameter have no effect on convergence.

    3. All the FE and NE send and recive gain is 0(analog and digital) now , I adjust these gain, there is also no effect.

    4. I 'm not sure if the AER 21 buffers  positions are right. According to "AER Integration_Gude" Data Memory Placement Guidelines, I assign these buffers as following:

    MEMORY
    {
        MMR      : origin = 0000000h length = 00c0h /* MMRs */

        DATA0  : origin = 00000c0h length = 0ff40h
       SDATA0 : origin = 0x10000, length = 0x2c000
      SDATA1 : origin = 0x3c000, length = 0x14000
    }


    SECTIONS
    {

       vectors > SDATA0
      vector :> SDATA0 ALIGN = 256
     .stack    > DATA0
      .sysstack > DATA0
      .text     > SDATA0
      .cinit    > SDATA0
      .switch   > SDATA0
      .bss      > DATA0
      .const    > SDATA0
      .data     > SDATA0
      .cio      > DATA0
      .sysmem   > SDATA0
      .far      > DATA0
      .heap        > DATA0

      /*----- Data Memory Allocation -----*/
      .aer_buff0   > SDATA1
      .aer_buff1   > DATA0
      .aer_buff2   > SDATA0
      .aer_buff3   > SDATA1
      .aer_buff4   > DATA0
      .aer_buff5      > DATA0  
      .aer_buff6      > DATA0  
      .aer_buff7      > DATA0
      .aer_buff8      > DATA0  
      .aer_buff9      > DATA0  
      .aer_buff10     > SDATA0  
      .aer_buff11     > SDATA0
      .aer_buff12     > DATA0  
      .aer_buff13     > SDATA0   
      .aer_buff14     > SDATA0  
      .aer_buff15     > DATA0  
      .aer_buff16     > DATA0
      .aer_buff17     > DATA0
      .aer_buff18     > DATA0     
      .aer_buff19     > DATA0  
      .aer_buff20     > DATA0  
     
      .agc_buff0_hf   > DATA0  
      .drc_state_buff  > SDATA0                                           

      AERSEC_SPATBL1 > SDATA0
      AERSEC_SPATBL2 > SDATA0
    }

     that make buffer 3 is not the same  SARAM block as buffer 1. 

    our product is a VOIP getway, the NE is a telephone. 

    which parameters should I check and adjust to make the filter convergence?

    Best Regards!

    Dudechao

  • Hi Dudechao,

    You'll need to achieve good convergence according to chapter 5 of the tuning guide. 

    I 'm not sure if the AER 21 buffers  positions are right.

    Please follow the memory placement guidelines and pay special attention to the restrictions listed in Table 2: AER Module Data Buffers – Properties and Placement Rules for C55x. 

    • Buffer 3 should NOT be placed in the same SARAM block as buffer 1.
    • Buffer 9 should NOT be placed in the same DARAM block as buffer 3.
    • Buffer 12 and buffer 15 should NOT be placed in the same DARAM block as the .const section in object file aerbsfil.o55L.

    You can look at packages\ti\mas\aer\test\lnkr\c55l\aertest_c55l.cmd for reference.

    Regards,

    Jianzhong

  • Hi JianZhong,

    I assigned AER 21 buffers almost the same with aertest_c55l.cmd now. The adjust parameters in our system seem only  y2x_delay and RX TX anlog and digit gains. We  try y2x_delay from 0~80 and gain from 0~10db, the ERLE is always  equal to 0.

    I get aerDebugStat from function aerGetPerformance(), and one debug statistics is shown as:

    dbgstat    struct aerDebugStat_s    {...}    
        control_bitfield0    unsigned int    0x0083 (Hex)        
        control_bitfield1    unsigned int    0    
        coherence_state    int    1    
        path_select_state    int    0    
        nguard_state    int    0    
        flag_bitfield0    unsigned int    45056    
        flag_bitfield1    unsigned int    5    
        tail_length    int    1600    
        state_bitfield    unsigned int    16707    
        max_canc_l2    int    0        
        curr_canc_l2    int    0    
        curr_echo_loss_l2    int    -1        
        maxabs_error    int    20992    
        maxabs_pred_echo    int    63        
        gain_tx_digital    int    0    
        gain_rx_digital    int    0        
        gain_tx_analog    int    0    
        gain_rx_analog    int    0        
        nlp_linear_atten    int    32736    
        nlp_max_closs_target    int    3276        
        nlp_clip_agg_l2    int    0    
        clip_level    int    0        
        hangover_rx2tx    int    0        
        hangover_tx2rx    int    10        
        nguard_atten    int    0        
        hlc_gain    int    0        
        dt_thresh    long    58048   

    I  know the ERLE (=max_can_l2) = 0  from the debug statistics.

    I want to know if you can find what is wrong  in our system from above debug information.

    We can do anything to get information you need to check our system.

    Best Regards,

    Dudechao

  • Hi Dudechao,

    I suspect that the input signals to aerSendIn() may not be correct:

    tint aerSendIn (void *aerInst, void *send_in, void *send_out, 
                    void *sout_8kHz, void *recv_out_sync, void *sout_pnlp_8kHz,
                    void *trace_buf);
    

    Is it possible for you to trace out "send_in" and "recv_out_sync" to make sure the "send_in" is the echo of "recv_out_sync"? You can play a tone from far end while keeping the near end silent. 

    Thanks,

    Jianzhong

  • Hi Jianzhoug,

    When play a tone from FE mic while keeping the NE silent, We can hear the the play tone from FE speaker.

    Following is our input and output signal in aerReceiveIn and aerSendIn:

    void Aer_Proc( void *aer_inst, linSample *recv_in, linSample *recv_out,linSample *send_in, linSample *send_out )
    {
      aerReceiveIn (aer_inst, recv_in, recv_out, NULL);
       aerSendIn(aer_inst, send_in, send_out, NULL, recv_out, NULL, NULL);
    }

    the  send_out is the data sent to FE. send_in is data sampled from NE mic. recv_in is data from FE mic, recv_out is the data to NE speaker.

    I get a debug data:

    dbgstat    struct aerDebugStat_s    {...}    
        control_bitfield0    unsigned int    0x0083 (Hex)    
        control_bitfield1    unsigned int    0        
        coherence_state    int    1        
        path_select_state    int    5    
        nguard_state    int    512        
        flag_bitfield0    unsigned int    45058        
        flag_bitfield1    unsigned int    6        
        tail_length    int    800      
        state_bitfield    unsigned int    1921    
        max_canc_l2    int    0    
        curr_canc_l2    int    6        
        curr_echo_loss_l2    int    5    
        maxabs_error    int    135    
        maxabs_pred_echo    int    229    
        gain_tx_digital    int    0    
        gain_rx_digital    int    0    
        gain_tx_analog    int    -192    
        gain_rx_analog    int    -96    
        nlp_linear_atten    int    27274    
        nlp_max_closs_target    int    3276    
        nlp_clip_agg_l2    int    0    
        clip_level    int    135    
        hangover_rx2tx    int    0    
        hangover_tx2rx    int    0    
        nguard_atten    int    0    
        hlc_gain    int    0    
        dt_thresh    long    58048    
        rx_sig_pwr    long    1680662    
        rx_noise_pwr    long    674400    
        tx_pNLP_total_pwr    long    344412    
        tx_pNLP_sig_pwr    long    16614    
        tx_pNLP_noise_pwr    long    2138        

    I just don't konw max_canc_l2   =   0 while the  curr_canc_l2  = 6 . 

    Best Regards,

    Dudechao

  • Can you dump send_in and recv_out signals to memory and save to files? I would look at the signals and make sure they look correct, i.e. send_in is a delayed and distorted/attenuated version of recv_out. 

  • Let me be a little more clear. The first thing you need to do when tuning AER is to verify it can achieve convergence, as described in chapter 5 of tuning guide - convergence verification. If you have done that and achieved good convergence similar to Figure 5 (example of convergence testing), then we can focus on debugging the dial tone issue.

    Otherwise, dumping out send_in and recv_out signals is very necessary to help understand your system. If you want to dump out these signals, make sure you have a few seconds of silence before sending the tone, so that you can clearly know the starting point of the tone when comparing send_in and recv_out and possibly estimate the delay between these two signals.

  • Hi jianzhongxu,

    I dump the send_in and recv_out signals and attach here.  both are raw data 16 bits binary file with size of 8K samples (about 1 second ).

    Recv_Out_and_Send_In.rar

    Best Regards,

    Dudechao

  • Hi jianzhongxu,

    I adjust the memeory and dump a larger file here. I record the data from the begining of FE sending tone.

    5314.Recv_Out_and_Send_In.rar

    Best Regards,

    Dudechao

  • Hi jianzhongxu,

    I dump the two signals with a few milliseconds  silence before sending tone and attach the file here.

    Recv_out1_and_Send_In1.rar

    Best Regards

    Dudechao

  • Hi Dudechao,

    Sorry, but I haven't had time to look at the signals you captured. Would you be able to analyze the signals using an audio editing tool such as Audition? Having the ability to analyze the signals is very necessary for debugging your system. You'll need that to verify AER convergence as shown in Figure 5.

    With that said, I may be able to squeeze some time to look at your captures, but I won't be able to do it soon. 

    Regards,

    Jianzhong

  • Hi jianzhongxu,

    I have only 'Cool Edit Pro'  at hand and It can play the tone and display the wave. I look at the signals and cannot find what is wrong,    they look correct: send_in is a delayed and distorted/attenuated version of recv_out.

    I have the  time  waiting for your help in your free time. Thank you.

    Best Regards

    Dudechao

  • What's the delay between recv_out and send_in?

    What did your convergence testing result look like, using CSS or white/pink noise? Does it look like Figure 5?

  • Hi jianzhongxu,

    The delay between recv_out and send_in about 32ms from above file Recv_out1 and Send_In1.

    Here I capture the Send_Out, Send_In and Recv_Out, From the Send_Out, it look like some convergence. but  the ERLE is 0.

    Send_In2-Recv_Out2-Send_Out2.rar

    Best Regards,

    Dudechao

  • Hi Dudechao,

    The 32ms delay is quite large. Would it be possible for you to examine your system design to shorten it within 20ms?

    Meanwhile, can you try to set y2x_delay to a value closer to 32ms, e.g. 20ms or 28 ms, and see if convergence gets better? Your current setting is 80 which is 10ms. So can you try a few values between 160 and 224?

    Thank you.

    Jianzhong

  • Hi Jianzhong,

    the y2x_delay is not 32ms, I make a mistake. I compare the two signal carefully and sure the y2x_delay is about 1ms.

    I set y2x_delay to 8 and get filter's coef.  when ERLE > 3:

    dbgstat    struct aerDebugStat_s    {...}    
        control_bitfield0    unsigned int    0x0083 (Hex)        
        control_bitfield1    unsigned int    0        
        coherence_state    int    1        
        path_select_state    int    2    
        nguard_state    int    0        
        flag_bitfield0    unsigned int    45058        
        flag_bitfield1    unsigned int    38    
        tail_length    int    800    
        state_bitfield    unsigned int    2305    
        max_canc_l2    int    6        
        curr_canc_l2    int    6    
        curr_echo_loss_l2    int    7    
        maxabs_error    int    15    
        maxabs_pred_echo    int    97    
        gain_tx_digital    int    0    
        gain_rx_digital    int    0    
        gain_tx_analog    int    -192    
        gain_rx_analog    int    -96    
        nlp_linear_atten    int    5953    
        nlp_max_closs_target    int    3276    
        nlp_clip_agg_l2    int    0    
        clip_level    int    11    
        hangover_rx2tx    int    -8        
        hangover_tx2rx    int    0        
        nguard_atten    int    0    
        hlc_gain    int    0    
        dt_thresh    long    58048        
        rx_sig_pwr    long    374208        
        rx_noise_pwr    long    33848        
        tx_pNLP_total_pwr    long    344412    
        tx_pNLP_sig_pwr    long    5380        
        tx_pNLP_noise_pwr    long    42    
        event_stats    struct aerEventStats_s    {...}    
        piqua_stats    struct aerPiquaStats_s    {...}        
        clip_scale    long    675299456        
        dt_ratio    long    67227        
        dt_hangover    int    1        
        nlp_linear_atten_tx    int    32767        
        nlp_linear_atten_rx    int    32767       

    According to 7.1, I get the adaptive filter coefficients through aerGetFilter(), Run find_opt_delay.exe, I get the optimum y2x_delay is 40.

    I find following questions:

    our terminal (NE with AER) may talk with different FE. to different FE, the ERLE is different:

    1. for some FE, the  ERLE >= 6, while some other FE, the ERLE may always remain 0.

    2.for some FE with ERLE remain 0, if FE change to good ERLE's FE, then return to these FE, the ERLE also have a good ERLE. It seem that if AER is converged, it is can converge in the originally not convergenced FE.       

    So the problem is how can ARE is always convergence with different FE.

    Best Regards,

    Dudechao

  • Hi, 

    I dump the two signals with a few milliseconds  silence before sending tone and attach the file here.

    Recv_out1_and_Send_In1.rar

    I briefly looked at your captures and it seems to me your recv_out (first one below) is actually behind send_in (second below). If this is the case, your system is not causal and won't converge. If the delay is 1ms, you should set y2x_delay to 0 to avoid making your system non-causal.

    To estimate the delay, you can have a few seconds of silence, followed by a tone, and then followed by silence, so that you can clearly see the beginning and ending of the tone in both recv_out and send_in. 

    To run convergence testing, you should use CSS or pink/white noise instead of tone. Tone can lead to false convergence, and if AER detects tone before it converges, AER could reset itself. In general usage, AER should be able to converge within a second when FE is speech. After that, it will preserve the adaptive filter coefficients and can handle any kind of FE signal. You can even preserve coefficients between power cycles.

    I think your first goal is still to make sure your system is causal and AER can converge reliably. You may want to double check the data path to minimize the buffering delay between your recv_out that comes out of aerReceiveIn() and recv_out_sync that goes into aerSendIn().

    tint aerReceiveIn (void *aerInst, void *recv_in, void *recv_out, void *trace_buf);

    tint aerSendIn (void *aerInst, void *send_in, void *send_out, void *sout_8kHz, void *recv_out_sync, void *sout_pnlp_8kHz, void *trace_buf);

    Regards,

    Jianzhong

  • Hi Jianzhong,

    For the buffer limited, I get  recv_out and send_in signal with few milliseconds silence when sending tone this time.

    I can see the begining and ending of the tone and estimate the delay is <10ms.

    I also capture the Send_Out signal( AER result ) in the file. It seem converges first but fail in the end.

    As for the recv_out  is  behind send_in as you show, this is the send_in buffer is not cleared in the AER begining.

    Rec_Out&Send_In&Send_Out.rar

    Best Regards,

    Dudechao

  • Hi Jianzhong,

    I change y2x_delay = 40 to  y2x_delay= 8, do the same test and  capture all the three signals,

    It seem convergenced from the signal Send_Out.

    Is it right?

    0702.Recv_out1_and_Send_In1.rar

    Best Regards,

    Dudechao

  • Hi Jianzhong,

    I do the test for many times, the result is almost the same as the attachment file shown with y2x_delay = 8, it is not convernenced .

    Rec_Out&Send_In&Send_Out3.rar

    does the y2x_delay need to be modified, or something elase I  pay attention to?

    Best Regards,

    Dudechao

  • Hi Dudechao,

    In your latest capture, your recv_out and send_in both have the tone starting at 0:00:020. There is no delay between recv_out and send_in.

    Let me try to explain.

    • The recv_out from aerReceiveIn() processing goes to your speaker.
    • Then the sound travels through your enclosure and the air and arrives at the mic, and becomes send_in signal. This is the echo.
    • At the same time, you provide recv_out to aerSendIn() as the reference signal, which is referred as recv_out_sync. You probably have some buffering delay between recv_out and recv_out_sync. 
    • There should be delay between recv_out_sync and send_in, i.e. reference signal should arrive before echo. Otherwise, your system is not causal and it will never converge.
    • Assuming there is no buffering delay between recv_out and recv_out_sync, send_in should always be a delayed and distorted version of recv_out_sync, because echo cannot come earlier than the original signal.
    • Parameter y2x_delay is used by the adaptive filter to insert delay to recv_out_sync to optimize convergence in case the echo path has long delay.

    So in your case, you should set y2x_delay to 0. More importantly, you need to examine your system and figure out why there is no delay between your send_in and recv_out_sync. Just to confirm, you dumped out the two signals that are provided to aerSendIn(), right?

    Thanks and regards,

    Jianzhong

  • Hi Jianzhong,

    I capture these signals from softswitch system. Before AER beging, the dial tone(450Hz) is reciving out, then the test tone( also 450HZ but with a few silence) is receiving out.  so there is no delay between recv_out and send_in at the AER begining.  the delay can be see from the silence end and the tone appear again.  

    I removed the dial tone before AER begining now and capture these signals in the attachment file. There are delay about 10ms between recv_out and send_in.

    I set the y2x_delay = 80 for the delay about 10ms.  but AER is still not convergenced. 

    Best Regards,

    Dudechao

  • Hi Jianzhong,

    I do many tests with the same FE, NE and  test tone, setting y2x_delay = 80, capturing the three signal: Recv_Out, Send_In, Send_Out. I can find from Send_Out signal that the convergence is different, I labeled it as good, mid, bad according to Send_Out convergence. most cases it was mid.

    Converge_bad.rar

    Converge_mid.rar

    Converge_good.rar

    By the way, the three Signal is direct from  aerSendIn() and  aerReceiveIn():

    aerReceiveIn (inst->aerHFInst, recv_in, recv_out, NULL);
    aerSendIn(inst->aerHFInst, send_in, send_out, NULL, recv_out, NULL, NULL);

    Best Regards,

    Dudechao

  • Hi Jianzhong,

    The convergence  I said above is only from shape of Send_Out signal , in all the cases,  ERLE = 0;

    I should use   CSS or pink/white noise instead of tone for convergence verification. 

    If dial tone cann't make ARE  convergenced,  the ARE will be in half-duplex state, then the  NE can not send DTMF signal. Our main purpose  is the DTMF signal can be sent when FE sending tone.

    I am sure our system is causal, the recv_out signal appear  no delay or even behind  send_in is that the dial tone is sending before ARE on and I capture the signal from ARE on.  There is no this case when  not sending dial tone, only sending test tone when ARE on.

    The ARE may be convergenced(max_canc_l2 > 3 ) when talking between FE and NE, but It has no regularity.

    It seems  some paremeters is not set correctly.

    Best Regards,

    Dudechao

  • Please help me understand a little more about your system if that's possible. I don't understand how there can be no delay between send_in and recv_out.

    1. do you have DAC and a speaker in the receive path?

    2. do you have mic and ADC in the send path?

    Another thought I have is, is it possible to mix in DTMF signal after aerSendIn? Because DTMF signal is generated when pressing key pad, it doesn't have to go through AER. If that's possible, DTMF signal from NE can always go through even if AER is half duplex. 

    Regards,

    Jianzhong

  • Hi jianzhongxu,

    1. We have DAC and speaker in the NE receive path, the Recv_Out signal is to the DAC;

    2. We have mic and ADC in the NE send path, and get the Send_In from the ADC;

    The DTMF signal is generated by pressing key, If  NE know when the FE begin talking, the DTMF can be sent before talking(when talking, AER is On), but often the NE don't know how many DTMF should be sent before talking, it must keep the AER on when dialing DTMF code, this is what we need to resolved.

    I do many tests that when I  open a new aer, when begining a test, the captured signal almost the same.   from the shape of  Send_Out signal , it seem  convergenced though  ERLE = 0.  Is it convergenced?

    IsItConvergenced.rar

    Best Regards,

    Dudechao

  • Hi jianzhougxu,

    There is no way to  mix  DTMF signal after aerSendIn for only  one ADC for DTMF and MIC, our NE is a normal phone.

    when Send_Out signal seem convergenced, the aerDebugSta is:

    dbgstat    struct aerDebugStat_s    {...}    
        control_bitfield0    unsigned int    0x0083 (Hex)    
        control_bitfield1    unsigned int    64    
        coherence_state    int    1    
        path_select_state    int    2        
        nguard_state    int    512        
        flag_bitfield0    unsigned int    45058    
        flag_bitfield1    unsigned int    38    
        tail_length    int    800    0x002227@DATA    
        state_bitfield    unsigned int    16835    
        max_canc_l2    int    0        
        curr_canc_l2    int    4    
        curr_echo_loss_l2    int    4    
        maxabs_error    int    832    
        maxabs_pred_echo    int    2986    
        gain_tx_digital    int    0    
        gain_rx_digital    int    0        
        gain_tx_analog    int    0    
        gain_rx_analog    int    0        
        nlp_linear_atten    int    23969    
        nlp_max_closs_target    int    1500    
        nlp_clip_agg_l2    int    3        
        clip_level    int    832        
        hangover_rx2tx    int    30    
        hangover_tx2rx    int    0        
        nguard_atten    int    0    
        hlc_gain    int    0        
        dt_thresh    long    58048    
        rx_sig_pwr    long    210864259        
        rx_noise_pwr    long    5380    
        tx_pNLP_total_pwr    long    6847232        
        tx_pNLP_sig_pwr    long    448044    
        tx_pNLP_noise_pwr    long    106988       

    The cur_canc_l2 is 4 but the max_canc_l2 is 0?.

    I set control_bitfield0 = 0x87  and tune nlp_combloss_target and nlp_clip_agg_l2 in this case, the send_out remain 0.

    When the NE sending DTMF, the DTMF in send_out is attenuated and distorted.

    DTMF_send.rar

    Best Regards,

    Dudechao

  • Hi jianzhongxu,

    If the FE stop sending the dial tone when sendind DTMF, the DTMF signal can be sent out.

    It seem that the aer is in half-duplex state.

    In our application, only FE received the DTMF, it can stop sending dial tone.

    StopToneWhenSendDTMF.rar

    Best Regards,

    Dudechao

  • I do many tests that when I  open a new aer, when begining a test, the captured signal almost the same.   from the shape of  Send_Out signal , it seem  convergenced though  ERLE = 0.  Is it convergenced?

    I looked at your captures: IsItConvergenced.rar. There is about 1.2 msec delay between send_in and recv_out. The send_out signal shows some kind of convergence. That is encouraging. The reason why max_canc_l2 is 0 could be that AER detects tone and resets itself. AER has tone detection which works as the following:

    1. if AER has already converged and detects tone from FE, AER will slow down adaptive filter update to preserve the coefficients. When tone disappears, AER will go back to normal filter update.

    2. if AER has not yet converged and detects tone from FE, AER will reset itself when tone disappears. 

    Can you perform same test but sending CSS or pink noise from FE before sending the dial tone? I hope to see convergence similar to Figure 5 of the tuning guide. You can set y2x_delay to 0.

    Regards,

    Jianzhong

  • Hi Jianzhong,

    I set y2x_delay to 0.  I do the same test with PC playing the "css_16k_-18dBFS.pcm" file and  FE mic sampling the signal.

    1)When the NE AER on, I switch the dial tone to the signal and capture these signals in file ccs_ERLE8.rar.

    the ERLE = 8 in this case.

    2)No dial tone sending when AER on, I capture theses signals in file nodialtone.rar. I alse get the aerDebugSta here:

    dbgstat    struct aerDebugStat_s    {...}        
        control_bitfield0    unsigned int    0x0083 (Hex)    
        control_bitfield1    unsigned int    64    
        coherence_state    int    0    
        path_select_state    int    2    
        nguard_state    int    0    
        flag_bitfield0    unsigned int    45058    
        flag_bitfield1    unsigned int    38        
        tail_length    int    800      
        state_bitfield    unsigned int    11147        
        max_canc_l2    int    8    
        curr_canc_l2    int    7    
        curr_echo_loss_l2    int    8    
        maxabs_error    int    98        
        maxabs_pred_echo    int    1345    
        gain_tx_digital    int    0    
        gain_rx_digital    int    0    
        gain_tx_analog    int    0    
        gain_rx_analog    int    0        
        nlp_linear_atten    int    32736        
        nlp_max_closs_target    int    3276        
        nlp_clip_agg_l2    int    0        
        clip_level    int    98        
        hangover_rx2tx    int    30    
        hangover_tx2rx    int    0    
        nguard_atten    int    0        
        hlc_gain    int    0        
        dt_thresh    long    58048    
        rx_sig_pwr    long    75917717        
        rx_noise_pwr    long    5380    
        tx_pNLP_total_pwr    long    344412    
        tx_pNLP_sig_pwr    long    5380    
        tx_pNLP_noise_pwr    long    2138   

    css_ERLE8.rar   

    nodialtone.rar

    Best Regards,

    Dudechao

  • Hi Dudechao,

    Thanks for sharing the captures. They look pretty good, especially nodialtone.rar. Have you tried re-enabling NLP and testing your phone by talking on both sides? Is the duplex performance acceptable?

    If you send dial tone from FE and DTMF from NE after AER is converged, DTMF should go through, but it will be distorted by the NLP. The amount of distortion depends on the quality of your phone enclosure and the NLP configuration. 

    Regards,

    Jianzhong

  • Hi Jianzhong,

    The AER can not be coverged by FE sending dialtone, so the DTMF signal is not yet been sending out.

    In practical use,  when NE send DTMF, the FE sending dial tone, at that time the ARE is opened and not converged yet.  If the dial tone can make the AER converged, it is solved. From the Send_Out signal, the dial tone can make the AER converged,  but " if AER has not yet converged and detects tone from FE, AER will reset itself when tone disappears.".

    We cann't sending  CCS or something else from FE to make ARE converged before sending dial tone.

    If the ARE is not converged, it is in half-duplex state. Is there a way to let NE pass through signal in this state?

    Best Regards,

    Dudechao

  • Hi Dudechao,

    I understand the problem you're faced with. Usually, this kind of problem is solved in system level. For example, a standalone tone detection unit can be used to detect the dial tone and call progress so that echo canceller is not started until the call is established. TI has a voice lib software package that has a tone detection unit. You can take a look at here.

    If your system doesn't have that capability, you may be able to work around by pre-converging AER when the phone is powered up. For example, if you play a short sentence of speech (e.g. "thanks for choosing xyz company's solution") after the user powers up the phone, AER can get converged.

    AER has APIs to allow the adaptive filter coefficients to be preserved from call to call. When AER is opened for a new call, it can get converged coefficients from previous call, so any dial tone from FE won't cause AER to reset. 

    Regards,

    Jianzhong

  • Hi Jianzhong,

    AER has APIs to allow the adaptive filter coefficients to be preserved from call to call. When AER is opened for a new call, it can get converged coefficients from previous call, so any dial tone from FE won't cause AER to reset.

    1). If I  get filter coefficients(aerGetFilter() ) from AER when it is convergence, and  put these coefficients( aerPutFilter() ) to AER when it opened, the AER is convergenced then?

    2). The convergenced filter coefficients got from a NE can be used to other NE, and make the other NE convergence?

    3). If  1)  2) is true, we can take the convergenced filter coefficients as constant in program and initialize ARE when it opened and make the  pre-converging AER?

    Thanks and Regards,

    Dudechao

  • If I  get filter coefficients(aerGetFilter() ) from AER when it is convergence, and  put these coefficients( aerPutFilter() ) to AER when it opened, the AER is convergenced then?

    Yes, that's correct. AER test code aer\test\aersim\aersim.c has examples how this can be done.

    The convergenced filter coefficients got from a NE can be used to other NE, and make the other NE convergence?

    That's a good question. The echo path that the adaptive filter models consists of phone enclosure and the room surroundings. Usually phone enclosure dominates room characteristics. I assume the phone enclosure does not vary much from phone to phone. So if you just save the first 20msec of the coefficients, you may be able to apply the coefficients to other phones used in different rooms. But you have to test and measure the convergence. You can try 1, 2, or 3 for NUM_H_VEC_PUT in aersim.c and see which one gives you the best performance. NUM_H_VEC_PUT=1 means 20 msec, 2 means 40 msec, and so on.

    If  1)  2) is true, we can take the convergenced filter coefficients as constant in program and initialize ARE when it opened and make the  pre-converging AER?

    Yes, but you have to use aerPutFilter()  to load the coefficients. First step should work for the same phone and you can start from there. However, second step depends on phone enclosure variances and room differences and needs to be evaluated.

  • Hi jianzhongxu,

    I make the pre-converging AER the same as described above, with the same phone, the DTMF signal can be received by FE. I 'll try it on different phone next.

    Thank you very much for your help!

    Best Regards,

    Dudechao

  • Hi Dudechao,

    Thanks for the update. Very glad for your progress. Glad that I could help.

    Best regards,

    Jianzhong