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.

Get Acoustic Echo canceling (AEC) working with dm365...

Hi,

I want to integrate the AEC in my project running on the dm365 but I can't get it work... I managed to compile it and integrate it thanks to this post

http://e2e.ti.com/support/embedded/f/356/p/108009/381318.aspx

But I can't get any results applying it. Following the sample app I wrote a wrapper around the library :Here is the initialization

AEC_Params.base.size    = sizeof(AEC_ITTIAM_Params);
    AEC_Status.base.size    = sizeof(AEC_ITTIAM_Status);
    AEC_DynParams.base.size = sizeof(AEC_ITTIAM_DynamicParams);


    /* frame_length parameter is specially used for ARM9E platform to use long buffer
    for efficient filtering operation */
    AEC_Params.samp_freq         = srate;
    AEC_Params.tail_length       = 1024;
    AEC_Params.frame_length      = 128;
    AEC_Params.erle_thresh_level = (char)36;

    /* Instance creation of AEC */
    /* To create AEC from external memory set flag to 1 in name string,
        "aec::flag"
     */
    libcodec_lock_memory_alloc_cached(codecs);

    aech = (AEC_ITTIAM_Handle)COMMON_create(codecs->eh, "aec", (COMMON_Params*)&AEC_Params);
    if (aech == NULL) {
        dbg( "Can't create handle for echo canceller\n");
        goto error_free ;
    }

    dbg("echo canceler  created\n");

    AEC_Status.base.data.buf = NULL;

    AECcmd                 = AEC_ITTIAM_OPERATING_MODE;
    AEC_DynParams.operating_mode = AEC_ITTIAM_FULL_DUPLEX;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                (ICOMMON_DynamicParams*)&AEC_DynParams,
                (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call AEC_ITTIAM_OPERATING_MODE!\n");
        return -1;
    }


    AECcmd               = AEC_ITTIAM_INHIBIT_UPDATES;
    AEC_DynParams.inhibit_conv = 0;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                (ICOMMON_DynamicParams*)&AEC_DynParams,
                (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call AEC_ITTIAM_INHIBIT_UPDATES!\n");
        return -1;
    }

    AECcmd             = AEC_ITTIAM_ENABLE_AEC;
    AEC_DynParams.enable_aec = 1;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                (ICOMMON_DynamicParams*)&AEC_DynParams,
                (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call AEC_ITTIAM_ENABLE_AEC!\n");
        return -1;
    }


    AECcmd             = AEC_ITTIAM_ENABLE_NLP;
    AEC_DynParams.enable_nlp = 1;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                (ICOMMON_DynamicParams*)&AEC_DynParams,
                (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call AEC_ITTIAM_ENABLE_NLP!\n");
        return -1;
    }


    AECcmd             = AEC_ITTIAM_ENABLE_CNG;
    AEC_DynParams.enable_cng = 1;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                (ICOMMON_DynamicParams*)&AEC_DynParams,
                (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call AEC_ITTIAM_ENABLE_CNG!\n");
        return -1;
    }



    AECcmd             = XDM_GETSTATUS;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                            (ICOMMON_DynamicParams*)&AEC_DynParams,
                            (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call XDM_GETSTATUS!\n");
        return -1;
    }
   
    dbg("Sampling frequency : %d\n Tail length %d \n",AEC_Status.samp_freq, AEC_Status.tail_length);
    dbg("Creating AEC with success \n");
    aec->aech = aech;

    XDM_AlgBufInfo bufinfo = AEC_Status.base.bufInfo;
    dbg("BUF INFO %d %d %d %d %d %d\n",bufinfo.minNumInBufs, bufinfo.minNumOutBufs,
                bufinfo.minInBufSize[0], bufinfo.minInBufSize[1],
                bufinfo.minOutBufSize[0], bufinfo.minOutBufSize[1]);

    libcodec_unlock_memory_alloc(codecs);
    return aec;

 

Here is the processing function :

 

int aec_feed(struct aec *aec, void* near_end, void* far_end,
        void* output, int ilen, int olen){


    XDM_BufDesc       inbufs, outbufs;
    AEC_ITTIAM_InArgs AEC_InArgs;
    AEC_ITTIAM_OutArgs AEC_OutArgs;

    XDAS_Int32 ret_val;


    AEC_InArgs.base.size    = sizeof(AEC_ITTIAM_InArgs);
    AEC_OutArgs.base.size   = sizeof(AEC_ITTIAM_OutArgs);


    AEC_ITTIAM_Handle aech;
    AEC_ITTIAM_DynamicParams AEC_DynParams;
    AEC_ITTIAM_Status AEC_Status;
     AEC_ITTIAM_Cmd    AECcmd;

    AEC_Status.base.size    = sizeof(AEC_ITTIAM_Status);
    AEC_DynParams.base.size = sizeof(AEC_ITTIAM_DynamicParams);

    AECcmd             = XDM_GETSTATUS;
    aech = aec->aech;
    ret_val = COMMON_control((COMMON_Handle)aech, AECcmd,
                            (ICOMMON_DynamicParams*)&AEC_DynParams,
                            (ICOMMON_Status*)&AEC_Status);
    if(ret_val != COMMON_EOK)
    {
        dbg("Error with Control call XDM_GETSTATUS!\n");
        return -1;
    }
    XDM_AlgBufInfo bufinfo = AEC_Status.base.bufInfo;

     ret_val = io_buffer_alloc(&inbufs, &outbufs, &AEC_Status.base.bufInfo);

    memcpy(inbufs.bufs[0], far_end, ilen);   
    memcpy(inbufs.bufs[1], near_end, ilen);   
#if 0
    inbufs.numBufs = 2;
    XDAS_Int8* bufs[2] = {far_end, near_end};
    XDAS_Int32 bufSizes[2] = {ilen, ilen};
    inbufs.bufSizes = bufSizes;
    inbufs.bufs = bufs;

    outbufs.numBufs = 2;
    XDAS_Int8* obufs[2] = {output, output};
    XDAS_Int32 obufSizes[2] = {olen, olen};
    outbufs.bufSizes = obufSizes;
    outbufs.bufs = obufs;
#endif


        AEC_InArgs.proc_path = AEC_ITTIAM_RX_PATH;
        ret_val = (XDAS_Int8) COMMON_process(
            (COMMON_Handle) aec->aech, &inbufs, &outbufs,
            (ICOMMON_InArgs*) &AEC_InArgs, (ICOMMON_OutArgs*) &AEC_OutArgs);

        if(ret_val != COMMON_EOK)
        {
            printf("Error with Tx path Process call!\n");
            return -1;
        }

        /* invoke the function to cancel echo */
        /* apply_cng = (XDAS_Int8)AEC_Handle->process(
            AEC_Handle, farEndSignal, nearEndSignal, residueSignal); */


  
        AEC_InArgs.proc_path = AEC_ITTIAM_TX_PATH;
        ret_val = (XDAS_Int8) COMMON_process(
            (COMMON_Handle) aec->aech, &inbufs, &outbufs,
            (ICOMMON_InArgs*) &AEC_InArgs, (ICOMMON_OutArgs*) &AEC_OutArgs);
   

        if(ret_val != COMMON_EOK)
        {
            printf("Error with Tx path Process call!\n");
            return -1;
        }
   
    memcpy(output, outbufs.bufs[0], olen);
     io_buffer_free(&inbufs, &outbufs);
    return 0;

 

The result I get has nothing to do with echo cancellation is either the same signal with noise or nothing...

The samples I supply are synchronized as I tested with speex for comparison and it's working.

Has somebody any idea why it's not working ?

Thanks

 

Charles