📄 pwmadec.c
字号:
//From now, WMA header parsing is getting started!
//
// If we are being asked to encode a WMA file, then return a
// failure since we can only decode WMA.
if (ulParam2 & CODEC_OPEN_ENCODE)
{
return(0);
}
// The first parameter is a pointer to the WMA persistent state.
pWMA = (tWMA *)ulParam1;
pStartStruct = (unsigned char *)pWMA;
RKFIO_FSeek(pRawFileCache, 0, 0);
// Clear the internal structure.
memset((void *)&pWMA->sWMAHeader, 0, sizeof(pWMA->sWMAHeader));
// Indicate that there is no file data in the internal read buffer.
pWMA->dwOffset = 0;
pWMA->dwLength = 0;
RK_PB_SetLocking();
//Bug Fix : By Vincent Hisung , Jan 15,2008
//For DRM9, Delay The WMA Format Detection .
//Before : //test = RK_WMAFileIsWMA((tWMAFileHdrState *)&pWMA->sWMAHeader);
/*
test = RK_WMAFileIsWMA((tWMAFileHdrState *)&pWMA->sWMAHeader);
if(WMAGlobal.WMAType && (!(gWMADec_SupportCodec & WMAGlobal.WMAType)))
{
//不是WMA文件
return(0);
}
*/
/*if(test != cWMA_NoErr)
{
return(0);
}*/
// Initialize the WMA decoder.
if (RK_WMAFileDecodeInit(&pWMA->sWMAState) != cWMA_NoErr)
{
return(0);
}
test = (int)RK_WMAFileIsWMA((tWMAFileHdrState *) & pWMA->sWMAHeader);
if (test != cWMA_NoErr)
{
return(0);
}
// Decode the file header.
if (RK_WMAFileDecodeInfo(&pWMA->sWMAState, &pWMA->sWMAHeader) != cWMA_NoErr)
{
return(0);
}
// The initial time position is zero.
pWMA->dwTimePos = 0;
pWMA->dwSampleRate = pWMA->sWMAHeader.sample_rate;
// Initially, there is not any PCM data to be generated.
pWMA->bMorePCMToGenerate = 0;
// There is no output buffer.
pWMA->pOutput = 0;
if (!RK_WMA_DecCheckSpec(&WMAGlobal, &pWMA->sWMAHeader))
{
RK_PB_SetUnlocking();
return(0);
}
// If the file is protected by DRM, then we can not play it (at
// this time).
if (pWMA->sWMAHeader.has_DRM)
{
// If the license is not part of the file, then we can not
// play the file.
if (pWMA->sWMAHeader.LicenseLength == 0)
{
return(0);
}
sDeviceID.pPMID = (unsigned char *)g_pmid;
sDeviceID.cbPMID = 16;
// Provide our device ID to the DRM library and if the license
// is does now allow the file to be played on this device then
// we can not play the file.
if (RK_WMAFileLicenseInit(&pWMA->sWMAState, &sDeviceID,
CHECK_ALL_LICENSE, 0, 0) != cWMA_NoErr)
{
return(0);
}
}
// Get the file content description.
pWMA->sWMADesc.title_len = STRING_SIZE;
pWMA->sWMADesc.author_len = STRING_SIZE;
pWMA->sWMADesc.copyright_len = 0;
pWMA->sWMADesc.description_len = 0;
pWMA->sWMADesc.rating_len = 0;
pWMA->sWMADesc.pTitle = pWMA->pucTitle;
pWMA->sWMADesc.pAuthor = pWMA->pucAuthor;
pWMA->pucTitle[0] = 0x00;
pWMA->pucTitle[1] = 0x00;
pWMA->pucAuthor[0] = 0x00;
pWMA->pucAuthor[1] = 0x00;
if (RK_WMAFileContentDesc(&pWMA->sWMADesc) != cWMA_NoErr)
{
pWMA->sWMADesc.title_len = 0;
pWMA->sWMADesc.author_len = 0;
pWMA->pucTitle[0] = '\0';
pWMA->pucAuthor[0] = '\0';
}
else
{
}
//原SETBUFFER
{
// The second parameter is a pointer to the output buffer.
pWMA->pOutput = (BufferState *) & sPlayBuffer;
// Provide the output buffer with our data buffers.
if (pWMA->sWMAHeader.num_channels == cWMA_C_Stereo)
{
//RK_BufferSetBuffer(pWMA->pOutput, pWMA->psLeft, pWMA->psRight,
//WMA_MAX_PCM_LENGTH);
BufferSetBuffer(pWMA->pOutput, pWMA->psLeft, pWMA->psRight,
WMA_MAX_PCM_LENGTH);
}
else
{
BufferSetBuffer(pWMA->pOutput, pWMA->psLeft, pWMA->psLeft,
WMA_MAX_PCM_LENGTH);
}
}
// Success.
return(1);
}
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
tWMA *pWMA;
short *psLeft, *psRight;
long lSamples;
unsigned int Check_Timer;
tWMAFileStatus WMA_TEST;
OutLength = 2048;
// The first parameter is a pointer to the WMA persistent state
pWMA = (tWMA *)ulParam1;
// The loop will only return in case of an error or when it
// generated an output.
while (1)
{
// See if there is more PCM data to be generated.
if (!pWMA->bMorePCMToGenerate)
{
// There is no more PCM data available, so decode the next
// frame of the WMA file.
WMA_TEST = RK_WMAFileDecodeData(&pWMA->sWMAState);
if (WMA_TEST != cWMA_NoErr)
{
// Either there was a file error or we've reached the
// end of the file.
return(0);
}
// There should be more PCM to be generated.
pWMA->bMorePCMToGenerate = 1;
}
// Wait until there is an adequate amount of space available
// in the output buffer.
Check_Timer = 0;
// Get a pointer to the output buffer
BufferGetWritePointer(pWMA->pOutput, &psLeft, &psRight,
&lSamples, gPlugInSkip);
// Generate PCM data into the output buffer.
lSamples = RK_WMAFileGetPCM(&pWMA->sWMAState,
psLeft, psRight, lSamples);
// See if we actually generated any samples.
if (lSamples > 0)
{
int i;
//del by vincent
//GetEnergyofVolume(psLeft, psRight, lSamples, 1);
// Advance the write pointer of the output buffer by the
// number of samples we produced.
// 更新缓冲区指针
BufferUpdateWritePointer(pWMA->pOutput, lSamples, gPlugInSkip);
// Increment the time position by the number of samples
// we produced.
pWMA->dwTimePos += lSamples;
}
else
{
// There is no more PCM data, so indicate that we must
// decode the next frame.
pWMA->bMorePCMToGenerate = 0;
//输出
//--------------------------------------
{
long tmp = 0;
BufferGetReadPointer(pWMA->pOutput, &psLeft, &psRight, &tmp);
//得到缓冲区内已有数据量
tmp = BufferDataAvailable(pWMA->pOutput);
//OutLength=(-1);
//若数据量足够,可进行输出
if (tmp >= 2048*3)
{
BufferUpdateReadPointer(pWMA->pOutput, 2048);
{
wma_psLeft = psLeft;
wma_psRight = psRight;
OutLength = 2048;
if (WMAfft > 0 && WMAfft < 6)
{
memset(psLeft, 0, 2048*2);
memset(psRight, 0, 2048*2);
WMAfft++;
}
else
WMAfft = 0;
}
// Success
return(1); //解满缓冲区后再返回
}
}
//--------------------------------------
}
}
// We should never get here, but just in case...
break;
}
// Encode a frame of data.
case SUBFN_CODEC_ENCODE:
{
// We don't support encode, so return an error.
return(0);
}
/// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
tWMA *pWMA;
unsigned char *p;
unsigned int Offset = (unsigned int)ulParam2;
// The first parameter is a pointer to the WMA persistent state
pWMA = (tWMA *)ulParam1;
// Seek to the specified position.
ulParam2 = RK_WMAFileSeek(&pWMA->sWMAState, ulParam2, ulParam3);
WMAfft = 1;
if (CurrentCodec == CODEC_WMA)
{
WMAfft = 0;
if ((Offset <= ulParam2))
{
int iOffset;
if (Offset > 1300)
iOffset = Offset - 1300;
else
{
iOffset = 0;
}
ulParam2 = RK_WMAFileSeek(&pWMA->sWMAState, iOffset, ulParam3);
}
}
// Set the time position correctly.
pWMA->dwTimePos = ((ulParam2 / 1000) * pWMA->dwSampleRate) +
(((ulParam2 % 1000) * pWMA->dwSampleRate) /
1000);
// Success.
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
// There's nothing to do, so return success.
cStartDec = 0;
return(1);
}
case SUBFN_CODEC_GETCAPTUREBUFFER:
{
*(unsigned long *)ulParam2 = (unsigned long) wma_psLeft ;
*(unsigned long *)ulParam3 = (unsigned long) wma_psRight;
*(unsigned long *)ulParam4 = (unsigned long) OutLength ;
return(1);
}
// We should never get here, but just in case...
default:
{
// Return a failure.
return(0);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -