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.

Linux/TMS320DM365: What may cause audio capture short in alsa for linux?

Guru 24520 points
Part Number: TMS320DM365

Tool/software: Linux

Hi TI Experts,

My customer face on the short audio capture data issue. I summary the confirmed points as below.
1. It seems that the cause is the "snd_pcm_readi()" function bacause this function was returned before the frame data was filled. i.e. the capture data duration should be 20ms but this function was returned at 5~6ms when this issue occrred.
2. It depends on the sampling rate of audio data.If set the higher rate, it is likely to occur this issue.

Please let me confirm the following question.
[Question.1-1]
If there is no PCM data on buffer, the return value of snd_pcm_readi() shoul be "-32".
Is this understanding correct?
[Question.1-2]
If my understanding is correct,what is the cause that the send_cpm_readi() returns the "320" value even though the data could not get?
[Questin.1-3]
What is the cause that the return value of "-32"(EPIPE) on "send_pcm_readi()" is happen?

Best regards.
Kaka

  • Hi Kaka,

    [Question.1-1] If there is no PCM data on buffer, the return value of snd_pcm_readi() shoul be "-32".
    Is this understanding correct?
       It indicates that the stream has suffered unrecoverable error. It may be because of Buffer overflow or underflow.

    [Questin.1-3]What is the cause that the return value of "-32"(EPIPE) on "send_pcm_readi()" is happen?
       As i have mentioned above it can be because of buffer mis handling.

    To root cause the issue can you provide more details regarding the kernel version, DVSDK version, audio codec, dmesg logs from boot to audio capture.

  • Hello, TI Experts,

     

    We got the details from the customer.

     - DVSDK version: ti-dvsdk_dm365-evm_4_02_00_06

     - kernel version:2.6.32.17-davinci1

     - major parameters of ALSA

        - sampleRate = 16000

        - channels = 1

        - periodSize = 160

        - buffer_time = 500000

        - avail min = 160

        - start_threshold = 1

        - stop_threshold = 8000

     

    And we tried to realize same behavior and get logs with DM365EVM & DVSDK(4_02_00_06) sample code.

    (Please see the attached "teraterm.log" file.)

     - At first, we execute "DMAI_DEBUG=2 ./audio_encode1_dm365.x470MV -n 100" in short time to see the details.

     - Then, we execute "./audio_encode1_dm365.x470MV -n 3000" to capture logs including problem.

     

    Major code modification based on the customers detail information of SDK is as below:

    (Please see the attached three "xxxx.c" files.)

      - dmai_2_20_00_15/packages/ti/sdo/dmai/apps/audio_encode1/appMain.c

         > Sound_Attrs sAttrs = Sound_Attrs_MONO_DEFAULT; // modified from Sound_Attrs_STEREO_DEFAULT;

      - dmai_2_20_00_15/packages/ti/sdo/dmai/linux/Sound.c

         > const Sound_Attrs Sound_Attrs_MONO_DEFAULT = {

         >    16000, // modified from 8000,

         >        1,

         >      127,

         >      127,

         >    Sound_Mode_FULLDUPLEX,

         >    Sound_Input_MIC,

         >    Sound_Std_ALSA,

         >      160, // modified from 2048, };

      - dmai_2_20_00_15/packages/ti/sdo/dmai/linux/Sound_alsa.c

         > avail = snd_pcm_avail_update(hSound->rcIn);  // add

         > printf("\tbefor: numSamples=%ld, avail=%ld\n", numSamples, avail ); // add

         >

         > numSamples = snd_pcm_readi(hSound->rcIn, bufPtr, readSamples);

         >

         > avail = snd_pcm_avail_update(hSound->rcIn); // add

         > printf("\tafter: numSamples=%ld, avail=%ld\n", numSamples, avail ); // add

      

    The problem is seen like below in the log around line 3956:

       - Sometimes snd_pcm_readi() execution period seems to be short.

         (In this case, we found 38ms (=17:49:57.045[ms] -17:49:57.007[ms]) 

       - Usually snd_pcm_readi() execution period is around 130 for reading 2048 samples.

    [Mon Dec 04 17:49:56.876 2017] #        befor: numSamples=0, avail=736

    [Mon Dec 04 17:49:56.975 2017]              after: numSamples=2048, avail=291

    [Mon Dec 04 17:49:57.007 2017] #        befor: numSamples=0, avail=768

    [Mon Dec 04 17:49:57.013 2017]              after: numSamples=2048, avail=6849

    [Mon Dec 04 17:49:57.045 2017] #        befor: numSamples=0, avail=7360

     

    Question:

      - Why does snd_pcm_readi() return sometime in short time?

         - The old sample data sound seems to be heard in this case.

         - So whole sound data update seems no to be completed, when "after: numSamples=2048" message appeared. 

     

    Do you see same experience with our attached code?

     

    We would appreciate if you tell us how to solve this problem.

    We would also appreciate if you check & try to run on DM365EVM with the attached c-sources.

     

    Best regards,

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2010, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <alsa/asoundlib.h>
    
    #include <xdc/std.h>
    #include <ti/sdo/dmai/Dmai.h>
    #include <ti/sdo/dmai/Sound.h>
    #include <ti/sdo/dmai/Buffer.h>
    
    #define MODULE_NAME     "Sound"
    
    #define AUDIO_DEVICE    "plughw:0,0"
    #define AUDIO_MIXER     "hw:0"
    
    #ifdef CONFIG_SND_SOC_TLV320AIC3X
    /* AIC3X specific elements */
    #define RIGHT_LINE_CTRL_ELEM  "Right PGA Mixer Line1R Switch"
    #define LEFT_LINE_CTRL_ELEM   "Left PGA Mixer Line1L Switch"
    
    #define RIGHT_MIC_CTRL_ELEM   "Right PGA Mixer Mic3R Switch"
    #define LEFT_MIC_CTRL_ELEM    "Left PGA Mixer Mic3L Switch"
    #endif
    
    #define PCM_TIMEOUT 40
    
    typedef struct Sound_Object {
        Sound_Std               soundStd;
        snd_pcm_t              *rcIn;
        snd_pcm_t              *rcOut;
        Int32                   sampleRate;
        Int16                   channels;
        Int32                   periodSize;
        Int32                   bufSize;
        snd_pcm_hw_params_t    *hwParamsIn;
        snd_pcm_hw_params_t    *hwParamsOut;
        snd_pcm_sw_params_t    *swParamsIn;
        snd_pcm_sw_params_t    *swParamsOut;
    } Sound_Object;
    
    /******************************************************************************
     *   setMixerInput
     *****************************************************************************/
    #ifdef CONFIG_SND_SOC_TLV320AIC3X
    static Int setMixerControl (const Char *name, Int value)
    {
        Int status;
        snd_hctl_t *hctl;
        snd_ctl_elem_id_t *id;
        snd_hctl_elem_t *elem;
        snd_ctl_elem_value_t *control;
    
        if ((status = snd_hctl_open(&hctl, AUDIO_MIXER, 0)) < 0) {
            Dmai_err2("setMixerControl %s open error: %s\n", AUDIO_MIXER, snd_strerror(status));
            return Dmai_EFAIL;;
        }
    
        if ((status = snd_hctl_load(hctl)) < 0) {
            Dmai_err2("setMixerControl %s load error: %s\n", AUDIO_MIXER, snd_strerror(status));
            return Dmai_EFAIL;;
        }
    
        snd_ctl_elem_id_alloca(&id);
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
        snd_ctl_elem_id_set_name(id, name);
        elem = snd_hctl_find_elem(hctl, id);
        if (!elem) {
            Dmai_err1("setMixerControl %s find element error\n", 
                AUDIO_MIXER);
            snd_hctl_close(hctl);
            return Dmai_EFAIL;
        }
    
        snd_ctl_elem_value_alloca(&control);
        snd_ctl_elem_value_set_id(control, id);
        snd_ctl_elem_value_set_integer(control, 0, value);
        snd_hctl_elem_write(elem, control);
    
        snd_hctl_close(hctl);
    
        return Dmai_EOK;
    }
    #endif
    
    /******************************************************************************
     *   setMixerVolume
     *****************************************************************************/
    static Int setMixerVolume (Sound_Attrs *attrs)
    {
        Int status;
        snd_mixer_t *rcMixer;
        snd_mixer_elem_t    *elem;
        snd_mixer_selem_id_t    *sid;
    
        snd_mixer_selem_id_malloc (&sid);
    
        /* Open the mixer device */
        status = snd_mixer_open (&rcMixer, 0);
    
        if ( status<0 ) {
            Dmai_err2 ("Failed to open mixer on %s (%s)\n",
                       AUDIO_MIXER, snd_strerror (status));
            return Dmai_EFAIL;
        }
    
        /* Attach mixer with sound card */
        status = snd_mixer_attach (rcMixer,AUDIO_MIXER);
    
        if (status <0) {
            Dmai_err2 ("Failed to attach mixer on %s (%s)\n",
                       AUDIO_MIXER, snd_strerror (status));
            return Dmai_EFAIL;
        }
    
        /* Register mixer with selected elements */
        status = snd_mixer_selem_register (rcMixer, NULL, NULL);
    
        if (status <0) {
            Dmai_err2 ("Failed to register mixer on %s (%s)\n",
                       AUDIO_MIXER, snd_strerror (status));
            return Dmai_EFAIL;
        }
        /* Load mixer */
        status = snd_mixer_load (rcMixer);
    
        if (status <0) {
            Dmai_err2 ("Failed to load mixer on %s (%s)\n",
                       AUDIO_MIXER, snd_strerror (status));
            return Dmai_EFAIL;
        }
    
        for (elem = snd_mixer_first_elem (rcMixer); elem; 
                elem=snd_mixer_elem_next(elem)) {
    
            snd_mixer_selem_get_id(elem,sid);
            if (!snd_mixer_selem_is_active(elem))
                continue;
    
            if (attrs->mode == Sound_Mode_OUTPUT || 
                 attrs->mode == Sound_Mode_FULLDUPLEX) {
                if (snd_mixer_selem_has_playback_channel(elem, 
                     SND_MIXER_SCHN_FRONT_LEFT))
                    snd_mixer_selem_set_playback_volume (elem, 
                    SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
                if (snd_mixer_selem_has_playback_channel(elem, 
                              SND_MIXER_SCHN_FRONT_RIGHT))
                    snd_mixer_selem_set_playback_volume (elem, 
                              SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
            }
    
            if (attrs->mode == Sound_Mode_INPUT || 
                        attrs->mode == Sound_Mode_FULLDUPLEX) {
                if (snd_mixer_selem_has_capture_channel(elem,
                        SND_MIXER_SCHN_FRONT_LEFT))
                    snd_mixer_selem_set_capture_volume (elem, 
                               SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
                if (snd_mixer_selem_has_capture_channel(elem, 
                        SND_MIXER_SCHN_FRONT_RIGHT))
                    snd_mixer_selem_set_capture_volume (elem, 
                               SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
            }
        }
    
        snd_mixer_selem_id_free (sid);
        snd_mixer_close (rcMixer);
    
        return Dmai_EOK;
    }
    
    /******************************************************************************
     * initHwParams
     ******************************************************************************/
    static Int initHwParams(snd_pcm_t *rc, snd_pcm_hw_params_t *hwParams,
                            Sound_Attrs *attrs, Sound_Handle hSound)
    {
        Int status;
        snd_pcm_uframes_t periodSize, bufSize;
        Uns buffer_time = 0;
    
        /* Fill the params with the defaults */
        status = snd_pcm_hw_params_any(rc, hwParams);
    
        if (status < 0) {
            Dmai_err2("Failed to init ALSA hardware param structure on %s (%s)\n",
                      AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the access type to interleaved */
        status = snd_pcm_hw_params_set_access(rc, hwParams,
                                              SND_PCM_ACCESS_RW_INTERLEAVED);
    
        if (status < 0) {
            Dmai_err2("Failed to set ALSA access type on %s (%s)\n",
                      AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the format to 16 bit little endian */
        status = snd_pcm_hw_params_set_format(rc, hwParams, SND_PCM_FORMAT_S16_LE);
    
        if (status < 0) {
            Dmai_err2("Failed to set sample format on %s (%s)\n",
                      AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the sample rate */
        status = snd_pcm_hw_params_set_rate_near(rc, hwParams,
                                                 (Uns *) &attrs->sampleRate, 0);
    
        if (status < 0) {
            Dmai_err3("Failed to set sample rate to %d on %s (%s)\n",
                      attrs->sampleRate, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the number of channels to 2 */
        status = snd_pcm_hw_params_set_channels(rc, hwParams, attrs->channels);
    
        if (status < 0) {
            Dmai_err3("Failed to set channel count to %d on %s (%s)\n",
                      attrs->channels, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set period size equal to input buffer size */    
        periodSize = hSound->periodSize;
        status = snd_pcm_hw_params_set_period_size_near (rc, hwParams,
                                                          &periodSize, 0);
        
        if (status < 0) {
            Dmai_err3("Failed to set the period size to %d on %s (%s)\n",
                      periodSize, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        if (periodSize != hSound->periodSize) {
            Dmai_dbg4("Failed to set buffer size (%d) , got (%d) on %s (%s)\n",
                        hSound->periodSize, periodSize, AUDIO_DEVICE,
                        snd_strerror(status));
            hSound->periodSize = periodSize;
        }
    
        /* Set the maximum buffer time */    
        status = snd_pcm_hw_params_get_buffer_time_max(hwParams, &buffer_time, 0);
    
        if (status < 0) {
            Dmai_err2("Failed to get maximum buffer time on %s (%s)\n",
                       AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        if (buffer_time > 500000) {
            buffer_time = 500000;
        }
    
        status = snd_pcm_hw_params_set_buffer_time_near(rc, hwParams, 
                    &buffer_time, 0);
    
        if (status < 0) {
            Dmai_err2("Failed to set maximum buffer time on %s (%s)\n",
                       AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Prepare the PCM interface with the choosen parameters */
        status = snd_pcm_hw_params(rc, hwParams);
    
        if (status < 0) {
            Dmai_err2("Failed to set ALSA parameters on %s (%s)\n",
                      AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Do sanity check */
        snd_pcm_hw_params_get_period_size(hwParams, &periodSize, 0);
        snd_pcm_hw_params_get_buffer_size(hwParams, &bufSize);
        
        if (periodSize == bufSize) {
            Dmai_err2("Can't use period size equal to buf size (%d == %d)\n",
                        periodSize, bufSize);
            return Dmai_EFAIL;
        }
    
        hSound->periodSize = periodSize;
        hSound->bufSize = bufSize;
        
    // get param 
       unsigned int get_val;
       snd_pcm_uframes_t get_frm;
    
       snd_pcm_hw_params_get_channels(hwParams, &get_val );
       printf("snd_pcm_hw_params_get_channels= %u\n", get_val );
       snd_pcm_hw_params_get_channels_min(hwParams, &get_val );
       printf("snd_pcm_hw_params_get_channels_min= %u\n", get_val );
       snd_pcm_hw_params_get_channels_max(hwParams, &get_val );
       printf("snd_pcm_hw_params_get_channels_max= %u\n", get_val );
    
       snd_pcm_hw_params_get_rate(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_rate= %u\n", get_val );
       snd_pcm_hw_params_get_rate_min(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_rate_min= %u\n", get_val );
       snd_pcm_hw_params_get_rate_max(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_rate_max= %u\n", get_val );
    //   snd_pcm_hw_params_get_rate_resample(hwParams, &get_val, 0 );
    //   printf("snd_pcm_hw_params_get_rate_resample= %u\n", get_val );
    
       snd_pcm_hw_params_get_period_time(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_period_time=%u\n", get_val );
       snd_pcm_hw_params_get_period_time_min(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_period_time_min=%u\n", get_val );
       snd_pcm_hw_params_get_period_time_max(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_period_time_max=%u\n", get_val );
    
       snd_pcm_hw_params_get_period_size(hwParams, &get_frm, 0 );
       printf("snd_pcm_hw_params_get_period_size=%lu\n", get_frm );
       snd_pcm_hw_params_get_period_size_min(hwParams, &get_frm, 0 );
       printf("snd_pcm_hw_params_get_period_size_min=%lu\n", get_frm );
       snd_pcm_hw_params_get_period_size_max(hwParams, &get_frm, 0 );
       printf("snd_pcm_hw_params_get_period_size_max=%lu\n", get_frm );
    
       snd_pcm_hw_params_get_periods(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_periods=%u\n", get_val );
       snd_pcm_hw_params_get_periods_min(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_periods_min=%u\n", get_val );
       snd_pcm_hw_params_get_periods_max(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_periods_max=%u\n", get_val );
    
       snd_pcm_hw_params_get_buffer_time(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_buffer_time=%u\n", get_val );
       snd_pcm_hw_params_get_buffer_time_min(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_buffer_time_min=%u\n", get_val );
       snd_pcm_hw_params_get_buffer_time_max(hwParams, &get_val, 0 );
       printf("snd_pcm_hw_params_get_buffer_time_max=%u\n", get_val );
    
       snd_pcm_hw_params_get_buffer_size(hwParams, &get_frm );
       printf("snd_pcm_hw_params_get_buffer_size=%lu\n", get_frm );
       snd_pcm_hw_params_get_buffer_size_min(hwParams, &get_frm );
       printf("snd_pcm_hw_params_get_buffer_size_min=%lu\n", get_frm );
       snd_pcm_hw_params_get_buffer_size_max(hwParams, &get_frm );
       printf("snd_pcm_hw_params_get_buffer_size_max=%lu\n", get_frm );
    
    //   snd_pcm_hw_params_get_tick_time(hwParams, &get_val, 0 );
    //   printf("snd_pcm_hw_params_get_tick_time=%u\n", get_val );
    
        return Dmai_EOK;
    }
    
    /******************************************************************************
     * initSwParams 
     * ***************************************************************************/
    static Int initSwParams(snd_pcm_t *rc, snd_pcm_sw_params_t *swParams,
                            Sound_Handle hSound, Int delay)
    {
        Int status;
        snd_pcm_uframes_t start_threshold, stop_threshold;
    
        /* Get the current sw params */
        status = snd_pcm_sw_params_current (rc, swParams);
        
        if (status < 0) {
            Dmai_err2 ("Failed to read the current swparams on %s (%s)\n",
                       AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the available min */
        status = snd_pcm_sw_params_set_avail_min(rc, swParams, hSound->periodSize);
        
        if (status < 0) {
            Dmai_err3 ("Failed to set avail min to (%d) on %s (%s)\n",
                       hSound->periodSize, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the start threshold */
        if (delay) {
            start_threshold = 1;
        }
        else {
            start_threshold = hSound->bufSize;
        }
    
        status = snd_pcm_sw_params_set_start_threshold(rc, swParams, 
                    start_threshold);
    
        if (status < 0) {
            Dmai_err3 ("Failed to set start threashold to (%d) on %s (%s)\n",
                        start_threshold, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Set the stop threshold */
        stop_threshold = hSound->bufSize;
    
        status = snd_pcm_sw_params_set_stop_threshold(rc, swParams, 
                    stop_threshold);
    
        if (status < 0) {
            Dmai_err3 ("Failed to set start threashold to (%d) on %s (%s)\n",
                         stop_threshold, AUDIO_DEVICE, snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        /* Write the swparams */
        status = snd_pcm_sw_params(rc, swParams);
    
        if (status < 0) {
            Dmai_err2 ("Failed to set swparams on %s (%s)\n", AUDIO_DEVICE,
                       snd_strerror(status));
            return Dmai_EFAIL;
        }
    
        return Dmai_EOK;
        
    }
    
    /******************************************************************************
     * Sound_alsa_delete
     ******************************************************************************/
    Int Sound_alsa_delete(Sound_Handle hSound)
    {
        if (hSound) {
            if (hSound->rcIn) {
                snd_pcm_close(hSound->rcIn);
            }
    
            if (hSound->rcOut) {
                snd_pcm_close(hSound->rcOut);
            }
    
            if (hSound->hwParamsIn) {
                /* Free the H/W param structure */
                snd_pcm_hw_params_free(hSound->hwParamsIn);
            }
    
            if (hSound->swParamsIn) {
                /* Free the S/W param structure */
                snd_pcm_sw_params_free(hSound->swParamsIn);
            }
    
            if (hSound->hwParamsOut) {
                /* Free the H/W param structure */
                snd_pcm_hw_params_free(hSound->hwParamsOut);
            }
    
            if (hSound->swParamsOut) {
                /* Free the S/W param structure */
                snd_pcm_sw_params_free(hSound->swParamsOut);
            }
    
            free(hSound);
    
            snd_config_update_free_global();
    
        }
    
        return Dmai_EOK;
    }
    
    /******************************************************************************
     * Sound_alsa_create
     ******************************************************************************/
    Sound_Handle Sound_alsa_create(Sound_Attrs *attrs)
    {
        Sound_Handle hSound;
        Int status;
        snd_output_t    *log;
    
        assert(attrs);
    
        snd_output_stdio_attach(&log, stdout, 0);
    
        hSound = calloc(1, sizeof(Sound_Object));
    
        if (hSound == NULL) {
            Dmai_err0("Failed to allocate space for Sound Object\n");
            return NULL;
        }
    
        hSound->soundStd = attrs->soundStd;
        hSound->sampleRate = attrs->sampleRate;
        hSound->channels = attrs->channels;
        hSound->periodSize  = attrs->bufSize;
    
        if (attrs->mode == Sound_Mode_INPUT ||
            attrs->mode == Sound_Mode_FULLDUPLEX) {
    
            status = snd_pcm_open(&hSound->rcIn, AUDIO_DEVICE,
                                  SND_PCM_STREAM_CAPTURE, 0);
    
            if (status < 0) {
                Dmai_err2("Failed to open ALSA sound device for input %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            /* Allocate a PCM SW and HW Param structure */
            status = snd_pcm_hw_params_malloc(&hSound->hwParamsIn);
    
            if (status < 0) {
                Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            status = snd_pcm_sw_params_malloc(&hSound->swParamsIn);
    
            if (status < 0) {
                Dmai_err2("Failed to alloc software param structure on %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            if (initHwParams(hSound->rcIn,hSound->hwParamsIn,attrs,hSound) < 0) {
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            if (initSwParams(hSound->rcIn,hSound->swParamsIn,hSound,1) < 0) {
                Sound_alsa_delete(hSound);
                return NULL;
            }
           
            Dmai_dbg1("", snd_pcm_dump(hSound->rcIn, log)); 
        }
    
        if (attrs->mode == Sound_Mode_OUTPUT ||
            attrs->mode == Sound_Mode_FULLDUPLEX) {
    
            status = snd_pcm_open(&hSound->rcOut, AUDIO_DEVICE,
                                  SND_PCM_STREAM_PLAYBACK, 0);
    
            if (status < 0) {
                Dmai_err2("Failed to open ALSA sound device for output %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            /* Allocate a PCM SW and HW Param structure */
            status = snd_pcm_hw_params_malloc(&hSound->hwParamsOut);
    
            if (status < 0) {
                Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            status = snd_pcm_sw_params_malloc(&hSound->swParamsOut);
    
            if (status < 0) {
                Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n",
                          AUDIO_DEVICE, snd_strerror(status));
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            if (initHwParams(hSound->rcOut,hSound->hwParamsOut,attrs,hSound) < 0) {
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            if (initSwParams(hSound->rcOut,hSound->swParamsOut,hSound,0) < 0) {
                Sound_alsa_delete(hSound);
                return NULL;
            }
    
            if (setMixerVolume (attrs) <0) {
                Dmai_err0("Failed to configure sound mixer device\n");
            }
    
            Dmai_dbg1("", snd_pcm_dump(hSound->rcOut, log)); 
        }
    
    #ifdef CONFIG_SND_SOC_TLV320AIC3X
        if (attrs->mode != Sound_Mode_OUTPUT) {
            if (attrs->soundInput == Sound_Input_MIC) {
                if(setMixerControl(RIGHT_LINE_CTRL_ELEM, 0) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Right_PGA_Mixer_Line1R_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(LEFT_LINE_CTRL_ELEM, 0) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Left_PGA_Mixer_Line1L_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(RIGHT_MIC_CTRL_ELEM, 1) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Right_PGA_Mixer_Mic3R_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(LEFT_MIC_CTRL_ELEM, 1) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Left_PGA_Mixer_Mic3L_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
            } else if (attrs->soundInput == Sound_Input_LINE) {
                if(setMixerControl(RIGHT_LINE_CTRL_ELEM, 1) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Right_PGA_Mixer_Line1R_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(LEFT_LINE_CTRL_ELEM, 1) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Left_PGA_Mixer_Line1L_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(RIGHT_MIC_CTRL_ELEM, 0) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Right_PGA_Mixer_Mic3R_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
                if(setMixerControl(LEFT_MIC_CTRL_ELEM, 0) != Dmai_EOK) {
                    Dmai_err0("Failed to configure Left_PGA_Mixer_Mic3L_Switch\n");
                    Sound_alsa_delete(hSound);
                    return NULL;
                }
            }
        }
    #endif
        snd_output_close(log);
        return hSound;
    }
    
    /******************************************************************************
     * xrunRecovery
     * ***************************************************************************/
    static Int xrunRecovery(snd_pcm_t *rc, Int err)
    {
        Dmai_dbg0("Recovering from underrun\n");
    
        if (err == -EPIPE) {
            if (snd_pcm_prepare(rc) < 0) {
                Dmai_err1("Failed to recover from over or underrun on %s\n",
                          AUDIO_DEVICE);
                return Dmai_EFAIL;
            }
        }
        else if (err == -ESTRPIPE) {
            while ((err = snd_pcm_resume(rc)) == -EAGAIN) {
                sleep (1);  /* wait until the suspend flag is released */
            }
    
            if (snd_pcm_prepare(rc) < 0) {
                Dmai_err1("Failed to recover from over or underrun on %s\n",
                          AUDIO_DEVICE);
                return Dmai_EFAIL;
            }
        }
        else {
            return Dmai_EFAIL;
        }
    
        return Dmai_EOK;
    } 
    
    /******************************************************************************
     * Sound_alsa_read
     ******************************************************************************/
    Int Sound_alsa_read(Sound_Handle hSound, Buffer_Handle hBuf)
    {
        Int32 numSamples, readSamples;
        Int8 *bufPtr;
        snd_pcm_sframes_t avail; // modify
    //    struct timeval startTime, endTime; // modify
    
        assert(hSound);
        assert(hBuf);
        
        readSamples = Buffer_getSize(hBuf) / (2 * hSound->channels);
    
        bufPtr = Buffer_getUserPtr(hBuf);
    
        while (readSamples > 0) {
    
            avail = snd_pcm_avail_update(hSound->rcIn);  // modify
    //        printf("\tbefor: numSamples=%ld, avail=%ld\n", numSamples, avail ); // modify
    //        gettimeofday(&startTime, NULL);
    //        printf("%04ld[s].%06ld[us] : numSamples=%ld, avail=%ld\n",        
    //                startTime.tv_sec,           
    //                startTime.tv_usec, 
    //                numSamples,           
    //                avail
    //                );
            printf("\tbefor: numSamples=%ld, avail=%ld\n", numSamples, avail ); // avail
    
            numSamples = snd_pcm_readi(hSound->rcIn, bufPtr, readSamples);
    
    //        gettimeofday(&endTime, NULL);
            avail = snd_pcm_avail_update(hSound->rcIn); // modify
            printf("\tafter: numSamples=%ld, avail=%ld\n", numSamples, avail ); // modify
    //        printf("\tafter: numSamples=%ld, avail=%ld, snd_pcm_readi takes: %09ld[us]\n", numSamples, avail, (endTime.tv_usec - startTime.tv_usec) ); // modify
    
            if (numSamples == -EAGAIN) 
                continue;
    
            if (numSamples < 0) {
                if (xrunRecovery(hSound->rcIn,numSamples) < 0) {
                    Dmai_err2 ("Failed to read from %s (%s)\n", 
                                AUDIO_DEVICE, strerror(numSamples));
                    return Dmai_EFAIL;
                }
            }
            else {
                bufPtr += numSamples * 2 * hSound->channels;
                readSamples -= numSamples;
            }
        }
    
        Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf));
    
        return Dmai_EOK;
    }
    
    /******************************************************************************
     * Sound_alsa_write
     ******************************************************************************/
    Int Sound_alsa_write(Sound_Handle hSound, Buffer_Handle hBuf)
    {
        Int32 numSamples, writeSamples;
        Int8 *bufPtr;
    
        assert(hSound);
        assert(hBuf);
    
        writeSamples = Buffer_getNumBytesUsed(hBuf) / (2 * hSound->channels);
        bufPtr = Buffer_getUserPtr(hBuf);
    
        while (writeSamples > 0) {
    #if defined(Dmai_Device_dm365) || defined(Dmai_Device_dm368)
            /* start by doing a blocking wait for free space. */
            snd_pcm_wait (hSound->rcOut, PCM_TIMEOUT);
    #endif
    
            numSamples = snd_pcm_writei(hSound->rcOut, bufPtr, writeSamples);
    
            if (numSamples == -EAGAIN) 
                continue;
    
            if (numSamples < 0) {
                if (xrunRecovery(hSound->rcOut,numSamples) < 0) {
                    Dmai_err2 ("Failed to write to %s (%s)\n",
                                AUDIO_DEVICE, strerror(numSamples));
                    return Dmai_EFAIL;
                }
            }
            else {
                bufPtr += numSamples * 2 * hSound->channels;
                writeSamples -= numSamples;
            }
        }
    
        Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf));
    
        return Dmai_EOK;
    }
    

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2010, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    
    #include <xdc/std.h>
    #include <ti/sdo/dmai/Dmai.h>
    #include <ti/sdo/dmai/Sound.h>
    
    #define MODULE_NAME     "Sound"
    
    const Sound_Attrs Sound_Attrs_STEREO_DEFAULT = {
        44100,
        2,
        127,
        127,
        Sound_Mode_FULLDUPLEX,
        Sound_Input_MIC,
        Sound_Std_ALSA,
        2048,
    };
    
    const Sound_Attrs Sound_Attrs_MONO_DEFAULT = {
        16000, // 8000, // modify
        1,
        127,
        127,
        Sound_Mode_FULLDUPLEX,
        Sound_Input_MIC,
        Sound_Std_ALSA,
        160, // 2048,  // modify
    };
    
    typedef struct Sound_Object {
        Sound_Std         soundStd;
    } Sound_Object;
    
    /* OSS API prototypes */
    extern Sound_Handle Sound_oss_create(Sound_Attrs *attrs);
    extern Int Sound_oss_delete(Sound_Handle hSound);
    extern Int Sound_oss_read(Sound_Handle hSound, Buffer_Handle hBuf);
    extern Int Sound_oss_write(Sound_Handle hSound, Buffer_Handle hBuf);
    
    /* ALSA API prototypes */
    extern Sound_Handle Sound_alsa_create(Sound_Attrs *attrs);
    extern Int Sound_alsa_delete(Sound_Handle hSound);
    extern Int Sound_alsa_read(Sound_Handle hSound, Buffer_Handle hBuf);
    extern Int Sound_alsa_write(Sound_Handle hSound, Buffer_Handle hBuf);
    
    /* Function tables for run time lookup */
    static Sound_Handle (*createFxns[Sound_Std_COUNT])(Sound_Attrs *attrs) = {
        Sound_oss_create,
        Sound_alsa_create,
    };
    
    static Int (*deleteFxns[Sound_Std_COUNT])(Sound_Handle hSound) = {
        Sound_oss_delete,
        Sound_alsa_delete,
    };
    
    static Int (*readFxns[Sound_Std_COUNT])(Sound_Handle hSound,
                                            Buffer_Handle hBuf) = {
        Sound_oss_read,
        Sound_alsa_read,
    };
    
    static Int (*writeFxns[Sound_Std_COUNT])(Sound_Handle hSound,
                                             Buffer_Handle hBuf) = {
        Sound_oss_write,
        Sound_alsa_write,
    };
    
    
    /******************************************************************************
     * Sound_create
     ******************************************************************************/
    Sound_Handle Sound_create(Sound_Attrs *attrs)
    {
        return createFxns[attrs->soundStd](attrs);
    }
    
    /******************************************************************************
     * Sound_delete
     ******************************************************************************/
    Int Sound_delete(Sound_Handle hSound)
    {
        return deleteFxns[hSound->soundStd](hSound);
    }
    
    /******************************************************************************
     * Sound_read
     ******************************************************************************/
    Int Sound_read(Sound_Handle hSound, Buffer_Handle hBuf)
    {
        return readFxns[hSound->soundStd](hSound, hBuf);
    }
    
    /******************************************************************************
     * Sound_write
     ******************************************************************************/
    Int Sound_write(Sound_Handle hSound, Buffer_Handle hBuf)
    {
        return writeFxns[hSound->soundStd](hSound, hBuf);
    }
    

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2010, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*
     * This applications encodes from a sound device driver using a specified
     * XDM audio codec to an elementary stream.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <xdc/std.h>
    
    #include <ti/sdo/ce/Engine.h>
    #include <ti/sdo/ce/CERuntime.h>
    
    #include <ti/sdo/dmai/Dmai.h>
    #include <ti/sdo/dmai/Cpu.h>
    #include <ti/sdo/dmai/Sound.h>
    #include <ti/sdo/dmai/ce/Aenc1.h>
    
    #include "appMain.h"
    
    /* Align buffers to this cache line size (in bytes)*/
    #define BUFSIZEALIGN            128
    
    /******************************************************************************
     * main
     ******************************************************************************/
    Int appMain(Args * args)
    {
        Sound_Attrs             sAttrs      = Sound_Attrs_MONO_DEFAULT; // Sound_Attrs_STEREO_DEFAULT; // modify
        Buffer_Attrs            bAttrs      = Buffer_Attrs_DEFAULT;
        AUDENC1_Params          params      = Aenc1_Params_DEFAULT;
        AUDENC1_DynamicParams   dynParams   = Aenc1_DynamicParams_DEFAULT;
        Aenc1_Handle            hAe1        = NULL;
        Engine_Handle           hEngine     = NULL;
        Buffer_Handle           hOutBuf     = NULL;
        Buffer_Handle           hInBuf      = NULL;
        Sound_Handle            hSound      = NULL;
        FILE                   *outFile     = NULL;
        Int                     numFrame    = 0;
        Cpu_Device              device;
        Int                     ret         = Dmai_EOK;
    
        /* Initialize the codec engine run time */
        CERuntime_init();
    
        /* Initialize DMAI */
        Dmai_init();
    
        if (Cpu_getDevice(NULL, &device) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to determine target board\n");
            goto cleanup;
        }
    
        /* Open the output file */
        outFile = fopen(args->outFile, "wb");
    
        if (outFile == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create output file %s\n", args->outFile);
            goto cleanup;
        }
    
        /* Create device driver instance */
        sAttrs.sampleRate = args->maxSampleRate;
        sAttrs.mode = Sound_Mode_INPUT;
        if (device == Cpu_Device_OMAPL137) {
            sAttrs.soundStd = Sound_Std_ALSA;
        }
    
        sAttrs.soundInput = args->soundInput;
        hSound = Sound_create(&sAttrs);
    
        if (hSound == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create audio device\n");
            goto cleanup;
        }
    
        /* Open the codec engine */
        hEngine = Engine_open(args->engineName, NULL, NULL);
    
        if (hEngine == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to open codec engine %s\n", args->engineName);
            goto cleanup;
        }
    
        params.sampleRate = dynParams.sampleRate = args->maxSampleRate;
        params.bitRate = dynParams.bitRate = args->maxBitrate;
    
        /* Create the AUDENC1 based audio encoder */
        hAe1 = Aenc1_create(hEngine, args->codecName, &params, &dynParams);
    
        if (hAe1 == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create audio encoder\n");
            goto cleanup;
        }
    
        /* Align buffers to cache line boundary */    
        bAttrs.memParams.align = BUFSIZEALIGN; 
        
        /* Use cached buffers if requested */    
        if (args->cache) {
            bAttrs.memParams.flags = Memory_CACHED;
        } 
        
        /* Create an output buffer for encoded data */
        hOutBuf = Buffer_create(
            Dmai_roundUp(Aenc1_getOutBufSize(hAe1), BUFSIZEALIGN), &bAttrs);
    
        if (hOutBuf == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create contiguous buffer\n");
            goto cleanup;
        }
    
        /* Create an input buffer for pcm data */
        hInBuf = Buffer_create(Dmai_roundUp(Aenc1_getInBufSize(hAe1), BUFSIZEALIGN),
            &bAttrs);
    
        if (hInBuf == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create contiguous buffer\n");
            goto cleanup;
        }
    
        while (numFrame++ < args->numFrames) {
            /* Read samples from the Sound device */
            if (Sound_read(hSound, hInBuf) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to write audio buffer\n");
                goto cleanup;
            }
    
            if (args->cache) {
                /*
                 *  To meet xDAIS DMA Rule 7, when input buffers are cached, we
                 *  must writeback the cache into physical memory.  Also, per DMA
                 *  Rule 7, we must invalidate the output buffer from
                 *  cache before providing it to any xDAIS algorithm.
                 */
                Memory_cacheWbInv(Buffer_getUserPtr(hInBuf),
                                  Buffer_getSize(hInBuf));
    
                /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
                Memory_cacheInv(Buffer_getUserPtr(hOutBuf),
                                Buffer_getSize(hOutBuf));
            }
    
            /* Encode the audio buffer */
            if (Aenc1_process(hAe1, hInBuf, hOutBuf) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to encode audio buffer\n");
                goto cleanup;
            }
    
            if (args->cache) {
                /* Writeback the outBuf. */
                Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf));
            }
    
            /* Write the encoded frame to the file system */
            if (Buffer_getNumBytesUsed(hOutBuf)) {
                if (numFrame >= args->startFrame) {
                    if (fwrite(Buffer_getUserPtr(hOutBuf),
                               Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) {
                        ret = Dmai_EFAIL;
                        fprintf(stderr,"Failed to write encoded video data to file\n");
                        goto cleanup;
                    }
    
                    printf("#");
                }
                else {
                    printf("-");
                }
            }
            else {
                printf("%%");
            }
    
            fflush(stdout);
        }
    
        printf("\n%d frames encoded, exiting\n", numFrame - 1);
    
    cleanup:
        /* Clean up the application */
        if (hAe1) {
            Aenc1_delete(hAe1);
        }
    
        if (hInBuf) {
            Buffer_delete(hInBuf);
        }
    
        if (hOutBuf) {
            Buffer_delete(hOutBuf);
        }
    
        if (hEngine) {
            Engine_close(hEngine);
        }
    
        if (hSound) {
            Sound_delete(hSound);
        }
    
        if (outFile) {
            fclose(outFile);
        }
    
        printf("End of application.\n");
    
        if (ret == Dmai_EFAIL)
            return 1;
        else
            return 0;
    }
    

    6404.teraterm.log

  • Hi,

    Do you have any update?
    Now, our customer is waiting for the answer too long.

    We would appreciate if you tell us about the progress on this.

    Best regards,

  • Hi ,

       Are you able to play/record the audio using aplay/arecord command or gstreamer?

    Please find attached link which might give some idea on usage.

    e2e.ti.com/.../406165

    Unfortunately i dont have the hardware to test your modifications.

  • Hello,

    I am capturing 6 stereo channels at 48kHz ( FPGA -> TDM protocol -> MCASP2 DM8168)

    I met the similar issue :
    - sometimes,old sample data sound seems to be heard
    -----> In this case : "snd_pcm_readi" function execution time is only 0 or 1 ms instead of 13ms in good conditions.

    I goes beyond this problem by rejecting returned samples of "snd_pcm_readi" function, as long as the execution time is lower than a threshold (13/2) defined after somes trials.

    But after some searches I found this post :
    e2e.ti.com/.../1709745

    My problem seems to be resolved by fixing the function "edma_write_slot" located in arch/arm/common/edma.c from this post :

    e2e.ti.com/.../277294

    I hope it could be helpfull for you !
  • Hello,

     

    Thank you very much for your kindness.

    I really appreciate to provide us the clue to solve our problem.

     

    From your information, your problem seems to be resolved by fixing below functions.

     1: davinci_pcm_pointer

     2: edma_get_position

     3: edma_write_slot

     4: edma_read_slot is needed to fix?

     

    Is my understanding correct?

    If there are any missing, please tell me.

     

    I'd like to know how to fix those functions.

    Please tell me detail.

     For davinci_pcm_pointer

      I can find the detail with 7658.davinci-pcm.c from 

      http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/277294

     

     For edma_get_position

      I can find the detail with edma-get-position-race.txt from

      http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/277294

     

     But I cannot find how to fix edma_write_slot from E2E thread which you tell me.

     

    I would appreciate if you provide me files which you fixed like below;

       - davinci-pcm.c

       - arch/arm/common/edma.c

     

    I'd like to try to fix my files and run application from your advice.

     

    Best regards,

  • Hello,

    Sorry I have done a mistake into my post. I didn't modify the "edma_write_slot " function".

    I only modified the "edma_get_position" function, located at "arch/arm/common/edma.c", from the file edma-get-position-race.txt.

    Best regards

  • Hello,
     
    Thank you very much for your kindness.
    I really appreciate your help.

    I understood "your problem seems to be resolved by fixing the "edma_get_position" function only".

    I'd like to try to fix my file.

    Best regards,
    --