Justin Jiang

iMX53 WINCE700 when play mp3 and do pause/resume, there is "clicking noise" issue

Discussion created by Justin Jiang Employee on Jul 2, 2012

MP3 decoder always output 576 samples (576x2x2= 2304Byte for stereo 16bit) per frame. The data size less than the wav/aac playback case.

Our output DMA size is 48K(This size is set for 5.1 audio data), during suspend/resume, there is DMA underrun issue.

When underrun happen, we will fill 0 data to the buffer by call ClearBuffer. It is in the function of TransferBuffer() as below:

Since wave or aac file has a bigger output sample size, so it will not have this issue.

 

ULONG HardwareContext::TransferBuffer(AUDIO_BUS audioBus, UINT8 NumBuf)

{       

        if(pBufferLast != pBufferEnd)

        {

            // Enable if you need to clear the rest of the DMA buffer

            //

            // Probably want to do something better than clearing out remaining

            // buffer samples. DC output by replicating last sample or

            // some type of fade out would be better.

            StreamContext::ClearBuffer(pBufferLast, pBufferEnd);

   }

 

 

this issue can be fixed by changing the ouput DMA buffer size from 48K to 24K .

the code in “\wince700\platform\imx53_ard\src\drivers\esai\ Bsphwctxt.cpp”, plase change the DMA_BUFFER_REGION_SIZE_NBYTES from “0x1000*12” to “0x1000*6”. 
 
UINT16 BSPAllocOutputDMABuffer(PBYTE *pVirtAddr, PHYSICAL_ADDRESS *pPhysAddr)
{
    // Use dynamically allocated memory for the audio DMA buffer (should be multiple of 6).
    static const DMA_BUFFER_REGION_SIZE_NBYTES = (0x1000*6);
 
    DMA_ADAPTER_OBJECT Adapter;
    memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
    Adapter.InterfaceType = Internal;
    Adapter.ObjectSize    = sizeof(DMA_ADAPTER_OBJECT);
 
    // Allocate DMA buffers from external memory
    *pVirtAddr = (PBYTE)HalAllocateCommonBuffer(
                            &Adapter,
                            DMA_BUFFER_REGION_SIZE_NBYTES,
                            pPhysAddr,
                            FALSE);
   
    return DMA_BUFFER_REGION_SIZE_NBYTES;
}
 
 
VOID BSPDeallocOutputDMABuffer(PBYTE VirtAddr,PHYSICAL_ADDRESS phyAddr)
{
    // Nothing do dealloc since we get output DMA buffer from internal RAM
    static const DMA_BUFFER_REGION_SIZE_NBYTES = (0x1000*6);
    DMA_ADAPTER_OBJECT Adapter;
   
    memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
    Adapter.InterfaceType = Internal;
    Adapter.ObjectSize    = sizeof(DMA_ADAPTER_OBJECT);
 
    HalFreeCommonBuffer(&Adapter, DMA_BUFFER_REGION_SIZE_NBYTES, phyAddr, VirtAddr, FALSE);
    return;
}

Outcomes