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;
}