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.

ECU echo cancellation does not work

Other Parts Discussed in Thread: OMAPL138

Dear All,

Platform - OMAPL138.

I am using ECU component in my code for canceling echo generating at TDM side to IP side.

As my work scenario is to call from IP side to TDM side and we are getting echo voice at IP side.

Here are my settings for open ECU:

    ecuConfigParam_t cfgParam;

    ys_ecu_inst[chan].ecuCfg.y2x_delay = 20;                /* 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 = (0x0);            /* A-Law (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 |
                                ecu_CLEAR_FG |
                                ecu_CLEAR_BG |
                                ecu_CLEAR_SEARCH;

    cfgParam.config_bitfield1 = ecu_ENABLE_NLP_PHASE_RND;
    cfgParam.nlp_aggress = 0;    /* balance performance */
    cfgParam.cn_config = 0;        /* pink noise */

    ys_ecu_inst[chan].ecuCfg.cfgParam = &cfgParam;

    ecuOpen(ys_ecu_inst[chan].ecu_Inst,&(ys_ecu_inst[chan].ecuCfg));

1) How to configure ecuCfg.pcm_zero for linear samples as I get payload in linear 8-bit format and I dont want to use Alaw or Ulaw any of it.

2) Please tell me how to configure ECU properly?

3) Using test example of volib_2_0_0_3 it is programmed using simulator and I dont want to use that as I am not using CCS?

Regards

Rishabh Jain

  • Hi Rishabh,

    It seems we really should highlight PCM format configuration in user guide. You are not the first one to ask for linear sample configuration, see http://e2e.ti.com/support/embedded/bios/f/355/p/246619/869530.aspx#869530 or http://e2e.ti.com/support/embedded/bios/f/355/t/193193.aspx?pi239031349=1, as noted in those threads, “The ECU offered in VoLIB has been compiled with delay line compression enabled, it expects packed PCM for input to the delay line, hence the pcm_format must be compressed mu-law or a-law format in the current VoLIB 2.0.0.3 release.”

    To properly configure ECU, you may start with the default configuration as shown in the test example, and then dig into ecu.h to adjust the ECU control parameters based on your echo path to try to get satisfied performance.

    I am not quite sure if I understand your 3rd question correctly, the volib is independent to CCS, the test example is basically to demo how to initialize and run ECU, and certainly you can use TI C6000 compiler (along with other modules) without CCS to build your own project.

    Hope above helps.

    Regards,

    Garrett

  • Hi Garrett,

    I am also working on the same scenario as that of Rishabh. I followed the thread you mentioned, but still i didn't find any success in echo cancellation.

    I am using the following configuration for ecu.

    ecuConfig_t      ecuCfg;
    ecuConfigParam_t cfgParam;

    ecuCfg.cfgParam              = &cfgParam;
    ecuCfg.y2x_delay             = 120;
    ecuCfg.samples_per_frame     = 40;

    ecuCfg.pcm_expand_tbl = &muaTblUlaw[0];
    ecuCfg.pcm_zero       = SIU_ULAW_ZERO;

    cfgParam.filter_length       = 1024;
    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 */

    /*calling ecuopen*/
    ecuOpen (inst->ecuInst, &ecuCfg);

    After doing the above configuration i carry out the following procedure :

    #define ECUSAMPLESZ 40
    linSample sin_buf [ECUSAMPLESZ];
    linSample sout_buf[ECUSAMPLESZ];

    linSample rinLinear[ECUSAMPLESZ];
    tint      rinCompr[ECUSAMPLESZ];
    tword     rinBuffer[ECUSAMPLESZ];
    tint i,eculen = ECUSAMPLESZ;

    muaTblUlawCmpr (eculen, rinLinear, rinCompr);

    /* Pack samples for delay line compression */
    for (i=0; i<eculen; i++)
    {
           rinBuffer[i] = rinCompr[i] & 0xFF;        
    }

    ecuSendIn (inst->ecuInst, sin_buf,rinBuffer, sout_buf);

    Am i doing something wrong??? Could you please guide me through this as this echo cancellation is quite crucial for the project that we are working on.

    Thanks & regards

    Pankaj Bamola.

  • Hi Pankaj,

    Do you mean echo is not cancelled at all or there is residual echo in sout signal when you said ‘didn't find any success in echo cancellation?’

    Were you able to run test example project in the VOLIB release?

    Regarding the configuration you listed:

    1. How do you measure the system delay and determine decuCfg.y2x_delay = 120;
    2. Rishabh meantioned linear 8-bit format payload, was that a typo?
    3. I don’t see how you initialize sin_buf prior to calling ecuSendIn();
    4. If you can upload your rin/sin/sout sample files, that would be helpful.

    Regards,
    Garrett

  • Hi Garett,

    Sorry for the delayed response.

    Let me make the picture a bit more clear to you.

    We establish a call between an IP phone and an analog phone. IP packets are transferred to the analog phone via a custom board(take it as an exchange) hosting OMAPL138. It is on this call that we encounter echo on the IP side. I have implemented the ECU on the DSP on this same board, which after doing the codec conversion, directs the voice packets (received from IP side) to TDM.

    Now, when I changed y2x_delay to 0, and cleared the Filter coefficients by setting the cfgParam.config_bitfield

                                = ecu_ENABLE_ECHO_CANCELLER  |
                                   ecu_ENABLE_UPDATE          |
                                   ecu_ENABLE_NLP             |
                                   ecu_ENABLE_AUTO_UPDATE     |
                                   ecu_ENABLE_SEARCH          |
                                   ecu_ENABLE_CNG_ADAPT       |
                                   ecu_ENABLE_OPNLP_DETECT    |
                                   ecu_CLEAR_FG               |
                                   ecu_CLEAR_BG               |
                                   ecu_CLEAR_SEARCH;

    and again set the ECU by calling ecuControl with this slight modification, ECU seems to work. All rest of the configuration is same as before.

    However, i am still unable to completely remove the echo. I think it is the residual echo that you had mentioned, as i can here a noisy echo sound.

    Regarding your questions;

    1. How do you measure the system delay and determined ecuCfg.y2x_delay = 120;

    As i am working on real time data, and as i am sending the far end data received from IP side in rinLinear, so i am assuming y2x_delay now to be 0, earlier i was not aware of how exactly we have to use it. Could you please throw a bit light on this parameter. what does it actually mean and how is one supposed to measure it or system delay?.

    2. Rishabh mentioned linear 8-bit format payload, was that a typo?

    Yes, you are right, it was a typo. it must be 16 bits actually.

    3. I don’t see how you initialize sin_buf prior to calling ecuSendIn()

    sin_buf is initialized by the linear samples received from TDM side each time before calling ecuSendIn.

    4. If you can upload your rin/sin/sout sample files, that would be helpful.

    As I have told you that i am working on real time data(voice over IP-Analog call), I can not upload any sample files.

    Hope to get some suggestions from you.

    Thanks & Regards

    Pankaj

  • Pankaj,

    Y2x_delay is the extra system delay (in samples) from receive-in to send-in that can be excluded from echo path. It will help create proper receive-in buffer size inside ECU and align receive-out and send-in samples. Typically The y2x_delay is set to the frame size that TDM side PCM driver send/receives and ECU processes, e.g. 40 samples (5ms).

    You really should add PCM sample capture in your application or have the interface for sample capture externally, that would help identify and solve echo problems, for example, the residual echo you are observing. You can try to adjust nlp_aggress parameter or Tx/Rx signal gain to see if the residual echo can be minimized, but again, without the rin/sin/rout/sout samples, it's difficult to analyze the root cause.

    Regards,

    Garrett

  • Sorry Garrett for delayed response.

    We are trying to remove echo from our real time voice means during running the VoIP call.

    There is no particular voice sample we are talking about in here.

    Can you tell us particularly the setting we should make in the following scenario:-

    We have a VoIP based system in which we are trying to run call between IP-phones to TDM side phones.

    Problem we are facing is we receive echo at IP side?

    what are the settings to be done and in which parameters as we have already mentioned in the above posts? so please tell where we have to make changes?

    Regards

    Rishabh Jain

  • Rishabh,

    Is this a new VoIP system just deployed in field? Do you have echo issue during testing in lab?

    Does the echo happen only in the beginning call or in the entire call? Does the echo occur only during double-talk?

    Be aware that if rin or sin buffer is accidentally corrupted in application driver, it may cause echo issue as well. Are you certain this is an ECU issue?

    All the ECU control code is in ecu.h and users can try to apply each control code based on the call scenarios (echo paths).

    Without the real time samples, it’s really not much I can help.

    Regards,

    Garrett

  • Hi Garrett,

    >> Is this a new VoIP system just deployed in field? Do you have echo issue during testing in lab?

    Yes it is being prepared for deployment in field as an VoIP gateway. Yes we have faced this echo issue while testing in Lab.

    >> Does the echo happen only in the beginning call or in the entire call? Does the echo occur only during double-talk?

    It happens for the entire call. No it does not occur during double-talk state.

    >> Be aware2843.wireshark_payload_g711A_echo_wo_ecu.zip that if rin or sin buffer is accidentally corrupted in application driver, it may cause echo issue as well. Are you certain this is an ECU issue?

    No rin or sin buffer getting corrupt as voice travel smoothly but along with echo.

    And as per your suggestion for real time sample I am attaching the wireshark capture for further details.

    Scenario - Two omapl138 based systems are their and we are trying to make call between them through IP and at the back-end there are analog phones. You can also listen to the voice in the wireshark capture as it is based over G711A codec.

    So please tell me, will this be of any help or you want anything more for it.

    Rishabh Jain

  • Rishabh,

    I extracted the samples from the RTP packet payload. From packets directed to IP 192.168.4.60, it appears echo canceller was not activated and NLP was not engaged, you may take a look if you have the correct ECU library linked into your project, you probably have checked http://e2e.ti.com/support/embedded/bios/f/355/p/199331/716381.aspx#716381.

    From the code you listed above, it looks like rinBuffer is properly set up with compressed mu-law samples, to ensure the receive-in samples are filled into rinBuffer and synchronized with send-in samples, you may try to dump both the sin_buf and rinBuffer prior to calling ecuSendIn. Since the issue is reproduced in lab, you should be able to capture the rin/sin samples and feed into to your test project (or simulation program provided in the VoLIB release), which might give you more clues.

    Regards, Garrett

  • Hi Garrett,

    I am attaching the zip file for your help, in that we are using the way for initializing ecu and compressing packet format.

    >> Since the issue is reproduced in lab, you should be able to capture the rin/sin samples and feed into to your test project (or simulation program provided in the VoLIB release), which might give you more clues.

    For the above question we are not using CCS for our code building so we not using simulation program.

    As for the forum link mentioned in your last post we are linking only two libraries ecu_a,ecu_c and please correct us if are doing anything wrong in our code.6646.ecu_conf.zip

    Regards

    Rishabh Jain

  • Rishabh,

    The file you attached is inconsistent with Pankaj’s posting, e.g. samples_per_frame, buffer size (length), delay line compress format (alaw, ulaw), pcm_zero etc. where he observed ‘ECU seems to work... However, i am still unable to completely remove the echo’. Was previous wireshark trace captured with the configuration in the ecu_init.c (which commented delay line compression) you attached? You may refer to Pankaj’s configuration and re-capture the packet trace, so we can conclude it’s an echo canceller performance issue (that we need further investigate) rather than integration problem.

    Regards,
    Garrett

  • Hi Garrett,

    The wireshark captured I have attached was normal file without using "Echo cancellation Unit (ECU)".

    The code file I have send you is the configuration which I am using for ECU, do you find any thing wrong in that or there is some standard configuration which I should be following for ECU.

    Currently I am focusing over ECU example and trying to work with that, so as soon I will be done with that I will be informing you with the result of that.

    Till then if there is something you want us to follow while working with ECU, please suggest.

    Regards,

    Rishabh Jain

  • Hi Garrett,

    I have tested my wireshark capture with solved example of ECU.

    And we are not getting any success.

    So please guide us in the direction as it is getting critical or suggest any other way round.

    Regards

    Rishabh Jain

  • Rishabh,

    Are you able to capture all the samples (Rin/Sin/Rout/Sout) in your new ECU testing code? The point is that we can only have a wild guess without these samples.

    The previous wireshark capture without ECU enabled does not help understand problem. We first need to know if ECU is not activated or activated but residual echo is not suppressed.

    How does the new wireshark payload (Sout) look like? Do you see residual echo or same signal as Sin? You may post your new wireshark capture (WITH ECU enabled) here.


    Regards,

    Garrett

     

     

  • Hi Garrett,

    Yes I am able to capture all Rin/Sin/Rout/Sout samples file.

    Let me explain you how we are doing the procedure to do achieve it :-

    1) We are working over ECU solved example provided in Volib ECU component.

    2) When we try to run the ECU simulator on CCS it needs two file as input those are Rin & Sin, so we have replaced those file with our wireshark capture for both direction with the existing files.

    3) After then load & run the ECU test binary on CCS to convert it to Rout & Sout files.

    4) After the conversion we get two raw files which are ECU compressed and as the payload is A-law compressed, so we have convert it to wav file format to listen it, so here we are not passing this output over wireshark, here we are directly converting it wave file and listening to it.

    So we observe that we do not get any success while doing ECU compression.

    Here I am attaching all the files so you too can observe the data and you can convert it to wav file format and play that file.

    Regards

    Rishabh Jain

    8625.Ecu_sample_files.zip

  • Rishabh ,

    The Rin/Sin sample in your zip file should be fed into ECU as Sin/Rin sample. Either from signal level or delay, it shows these two files rin.pcm/sin.pcm should be Sin/Rin for ECU.

    Also it would be helpful to check vsend_in & vrecv_in of ecuSendIn( ) to make sure the vsend_in fills with linear samples and vrecv_in is packed compressed samples. You can send silence samples into ECU and see how it looks like in vsend_in and vrecv_in buffers from CCS memory browser. 

    Regards,

    Garrett

  • Hi Garrett,

    Sorry for so delayed response.

    But the thing is I am still not able to get success with what you have suggested me above.

    Now I am telling you my observation regarding ecu is that :-

    1) When I use ecuSendIn function - ecuSendIn(ecu_inst->ecu_Inst,sndinBuffer,rinBuffer,soutCompr);

    a) whatever I pass in the place of rinBuffer it does not affect the soutCompr i.e. data in both sndinBuffer & soutCompr are same.

    b) ecuSendIn(ecu_inst->ecu_Inst,sndinBuffer,sndinBuffer,soutCompr);

    If I re-place rinBuffer with sndinBuffer then also the data in both sndinBuffer & soutCompr are same.

    Can you tell me where to see that this data is not processed properly by ECU?

    Is ECU is working or not?

    If you wany my code I can provide you with that also.

    Regards

    Rishabh Jain

  • Hi Garrett,

    I am just telling you more on what I have observed regarding echo cancellation.

    I have printed all the value after calling function

    ecuGetPerformance(ecu_inst->ecu_Inst,&stat,&ecuVersion,&ecuPerform,&ecuUpdateStat,
                            &noise_x,&noise_y,&rerl,&tail_len,rustat);

    DEBUG    - ecu Version[10]rev[92]patch[0]build[4]feature[33221]
    DEBUG    - ecu Perform Px[212799]Py[142239811]Pe[142239811]erlest[0]acomest[0]
    DEBUG    - ecu Update update[0]search[0]erle_bypass[0]xtone_bypass[0]other_bypass[0]
    DEBUG    - ecu Update xidle[30370]double_talk[31838]dt_cps[0]dt_cpt[31746]nlp[0]
    DEBUG    - ecu Update divergence[0]srch_divergence[0]fg_switch[0]bg_switch[0]openloop_found[0]
    DEBUG    - ecu Update numseg_change[0]segment_change[0]converge_exit[0]txbssat_events[0]rxbssat_events[0]
    DEBUG    - ecu noise_x[699]noise_x[1]rerl[127]tail_len[1024]

    DEBUG    - ecu Version[10]rev[92]patch[0]build[4]feature[33221]
    DEBUG    - ecu Perform Px[35788]Py[143259846]Pe[143259846]erlest[0]acomest[0]
    DEBUG    - ecu Update update[0]search[0]erle_bypass[0]xtone_bypass[0]other_bypass[0]
    DEBUG    - ecu Update xidle[0]double_talk[2]dt_cps[0]dt_cpt[2]nlp[0]
    DEBUG    - ecu Update divergence[0]srch_divergence[0]fg_switch[0]bg_switch[0]openloop_found[0]
    DEBUG    - ecu Update numseg_change[0]segment_change[0]converge_exit[0]txbssat_events[0]rxbssat_events[0]
    DEBUG    - ecu noise_x[699]noise_x[1]rerl[127]tail_len[1024]

    In the above debug mentioned can you tell us why the values in 3rd bold line is not changing.

    Can you give us any clue now that where we are doing wrong?

    Please ask for any queries.

    Regards

    Rishabh Jain

  • Hi Rishabh,

    It really has been a long while. Some questions I probably have asked but still would like to confirm:


    1. if you follow the steps in ECU simulation user manual (volib_C66_2_0_0_3/docs/doxygen/html/ecu_test_html/index.html), are you able to get the unit test pass in your environment?

    2. based on the unit test case, if you replace the default test vectors in volib_C64P_2_0_0_3\packages\ti\mas\ecu\test\vectors\inp with your captured traces from real system, or vice versa, if you feed the test vectors from VoLIB into your real system, how would the Sout look like?

    3. how do you verify the Sin buffer is filled in linear 16-bit PCM samples and Rin buffer is filled 2 8-bit packed samples?

    Regards,
    Garrett

  • Hi Garrett,

    1. if you follow the steps in ECU simulation user manual (volib_C66_2_0_0_3/docs/doxygen/html/ecu_test_html/index.html), are you able to get the unit test pass in your environment?

    Ans- Yes we are able to pass the unit test pass in your environment.

    2. based on the unit test case, if you replace the default test vectors in volib_C64P_2_0_0_3\packages\ti\mas\ecu\test\vectors\inp with your captured traces from real system, or vice versa, if you feed the test vectors from VoLIB into your real system, how would the Sout look like?

    Ans- Yes we have replaced rin.pcm and sin.pcm and we no changes happened.Can you please ellaborate how would the Sout look like? I get the out files for both.

    3. how do you verify the Sin buffer is filled in linear 16-bit PCM samples and Rin buffer is filled 2 8-bit packed samples?

    Both Rin & Sin are 8-bit packed samples. As the ecu library works with delay line, so we passed both a-law compressed data & we get output as such.

    Regards

    Rishabh Jain

  • Rishabh,

    If you are able to pass ECU unit test example, you should see CSS signal from Rin is cancalled in Sout. If you observe echo with your captured trace, please post your Rin/Sin/Sout trace so we can look at if Rin/Sin signals are misaligned.

    Rin/Sin samples are a-law or u-law compressed samples in your system, but you need to uncompress your Sin samples before feeding into your sndinBuffer, and also pack two compressed Rin samples into your rinBuffer (delay line buffer) in little endian format, for details, please review the thread: http://e2e.ti.com/support/embedded/bios/f/355/t/193193.aspx?pi239031349=1.

    Regards,
    Garrett