📄 pape_dec.c
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\APEDec
Desc : APE解码。
Author : huangxd , Vincent Hisung
Date : 2007-08-xx
Notes :
$Log :
* huangxd 2007/08/xx 建立此文件
*
* vincent 2007/08/xx 修订完善
*
*/
/****************************************************************/
#include "../include/audio_main.h"
#ifdef APE_DEC_INCLUDE
#include "../include/audio_globals.h"
#include "../include/file_access.h"
#include "pAPE_DEC.h"
static long OutLength;
int ape_TitleIndex;
int ape_ArtistIndex;
int ape_AlbumIndex;
//****************************************************************************
//
// The codec plug-in entry point for the APE decoder.
//
//****************************************************************************
//功能实现情况:
//SUBFN_CODEC_GETNAME : 不支持
//SUBFN_CODEC_GETARTIST: 得到歌手名
//SUBFN_CODEC_GETTITLE : 得到曲目名
//SUBFN_CODEC_GETBITRATE: 得到码率
//SUBFN_CODEC_GETSAMPLERATE: 得到采样率
//SUBFN_CODEC_GETCHANNELS: 得到声道数目
//SUBFN_CODEC_GETLENGTH : 得到时长 [单位:毫秒]
//SUBFN_CODEC_GETTIME : 得到当前播放时间 [单位:毫秒]
//SUBFN_CODEC_OPEN_DEC : 打开解码器(初始化)
//SUBFN_CODEC_DECODE : 解码
//SUBFN_CODEC_ENCODE : 不支持
//SUBFN_CODEC_SEEK : 按时间直接定位 [单位:毫秒]
//SUBFN_CODEC_CLOSE : 关闭解码器
/******************************************************
Name: APEDecFunction
Desc: APE解码器接口函数
Param: ulIoctl 子功能号
ulParam1 子功能参数1
ulParam2 子功能参数2
ulParam3 子功能参数3
ulParam4 子功能参数4
Return: 0-失败 1-成功
Global: 无
Note: 无
Author: HXD
Log:
******************************************************/
unsigned long
APEDecFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
unsigned long ulParam3, unsigned long ulParam4)
{
unsigned int WaitCounter = 0;
switch (ulSubFn)
{
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
OutLength = 1152;
{
// variable declares
tAPE *pAPE;
short *psLeft, *psRight;
long lLength;
ape_int32 nBlocksDecoded = -1;
ape_int16 nBlocksDecRetVal = ERROR_SUCCESS;
pAPE = (tAPE *)ulParam1;
if (Ape_gBlocksLeft <= 0)
return (0);//表示解码结束,没有未解码的数据 added by hxd 20070723
Ape_gDecodeErrorFlag = ERROR_SUCCESS;//非零表示错误发生,零表示正常完成解码; 20070703
{
// decode data
ape_int32 nRetVal ;
Ape_pOutBufferLeft = (ape_uint16*)pAPE->psLeft;
Ape_pOutBufferRight = (ape_uint16*)pAPE->psRight;
nRetVal = Ape_pApeDecompress->GetData(Ape_pApeDecompress, APE_BLOCKS_PER_DECODE, &nBlocksDecoded);
if (nRetVal != ERROR_SUCCESS)
{
return (nBlocksDecRetVal = 0);//exit(ERROR_INVALID_CHECKSUM);ERROR_INVALID_CHECKSUM
}
//该帧解错误码 commented by hxd 20070703
if (Ape_gDecodeErrorFlag != ERROR_SUCCESS)
{
return (nBlocksDecRetVal = 0);//ERROR_DECOMPRESSING_FRAME
}
}
//输出 ---------------------------------
lLength = APE_BLOCKS_PER_DECODE;
OutLength = lLength;
pAPE->ulTimePos += lLength;
Ape_gBlocksLeft -= nBlocksDecoded;//更新未解码blocks数目值 added by hxd 20070723
ApeUnBitArrayFillBitArrayOutside();//remove old bitstream and fill new bitstream added by hxd 20070618
//Success
return(1);
}
}
// Prepare the codec to decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
tAPE* pAPE;
CAPEInfo* pAPEInfo = &Ape_gDecompressInfoCreate;
ape_int32 nStartBlock = -1;
ape_int32 nFinishBlock = -1;
ape_int32 nErrorCode = ERROR_SUCCESS;
WAVEFORMATEX wfeInput;
// The first parameter is a pointer to the MP3 persistent data.
pAPE = (tAPE *)ulParam1;
// create and return
Ape_pApeDecompress = (IAPEDecompress *)ApeDecompressCoreCreate(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode);
// get the input format
Ape_pApeDecompress->GetInfo(APE_INFO_WAVEFORMATEX, (ape_int32) &wfeInput, 0);
//----FOR DEBUG--- 在需要解析ID3或APETAG时可参考如下代码
if (((CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput, 0)))->GetHasAPETag(((CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput, 0)))) == TRUE)
{
//CAPETag* pTmp=(CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput,0));
//CAPETagField* pTmp2;
//ape_int32 i;
//fprintf(stderr, "APE Tag Bytes: %i\n",pTmp->GetTagBytes(pTmp));
//for (i=0;i<7;i++)
//for (i=0;i<pTmp->m_nFields;i++)
//{
//fprintf(stderr, "Has APE Tag: %s\n",pTmp->m_aryFields[i]);
//}
}
else
{
//fprintf(stderr, "No APE Tag.\n");
}
if (((CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput, 0)))->GetHasID3Tag(((CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput, 0)))) == TRUE)
{
//CAPETag* pTmp=(CAPETag*)(Ape_pApeDecompress->GetInfo(APE_INFO_TAG, (ape_int32) &wfeInput,0));
}
else
{
//fprintf(stderr, "No ID3 Tag.\n");
}
//--------------------------------------
pAPE->ulTimePos = 0;
pAPE->usSampleRate = pAPEInfo->m_APEFileInfo.nSampleRate;
pAPE->ucChannels = pAPEInfo->m_APEFileInfo.nChannels;
pAPE->ulBitRate = pAPEInfo->m_APEFileInfo.nAverageBitrate * 1000;
pAPE->ulTimeLength = (unsigned long)pAPEInfo->m_APEFileInfo.nLengthMS;//单位为毫秒,nLengthMS的单位是毫秒
pAPE->usSamplesPerBlock = pAPEInfo->m_APEFileInfo.nBlocksPerFrame;//Ape快进快退的最小单位就是一帧
Ape_gTotalBlocks = Ape_gBlocksLeft = Ape_pApeDecompress->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS, 0, 0);
if (nErrorCode == 0) //mod by vincent
{
return 1;
}
else
{
return 0;
}
}
// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
tAPE *pAPE;
unsigned long ulPos;
// The first parameter is a pointer to the APE persistent data.
pAPE = (tAPE *)ulParam1;
if (ulParam2 > pAPE->ulTimeLength)//ulParam2单位是毫秒,ulTimeLength单位也是毫秒
{
ulParam2 = pAPE->ulTimeLength;
}
// Compute the number of frames that occur before the requested time position.
ulPos = (((ulParam2 / 1000) * pAPE->usSampleRate) / pAPE->usSamplesPerBlock) +
(((ulParam2 % 1000) * pAPE->usSampleRate) / (pAPE->usSamplesPerBlock * 1000));//表示当前时间点对应为第几帧
// Compute the time for the computed frame number.
pAPE->ulTimePos = ulPos * pAPE->usSamplesPerBlock;//当前时间点对应的样本数目
Ape_gStartBlock = pAPE->ulTimePos;//快进、快退至当前帧对应的样本数目
Ape_gCurrentBlock = Ape_gStartBlock;
Ape_gBlocksLeft = Ape_gTotalBlocks;
Ape_gBlocksLeft -= Ape_gStartBlock;
//下列标记设定表示从当前位置开始解码,类似于从第一帧开始解码
Ape_gDecompressorInitial = FALSE;//设置为false表示所有的初始化工作重新开始
Ape_gBeginDecodeFrameFlag = FALSE;//表示重新获取总blocks数目
// Compute the file position based on the actual seek time.
//重新定位文件位置在下一次SUBFN_CODEC_DECODE中完成的,注意这里A-B复读的B点首尾结束可能有问题,需要考虑下,added by hxd 20070724
return(1);
}
// Return the current position (in milliseconds) within the file.
case SUBFN_CODEC_GETTIME:
{
// additional code needed
unsigned long *pulTime;
tAPE *pAPE;
// The first parameter is a pointer to the APE persistent data.
pAPE = (tAPE *)ulParam1;
// The second parameter is a pointer for the number of seconds.
pulTime = (unsigned long *)ulParam2;
if (pAPE->usSampleRate)
{
// Determine the time based on the sample rate.
*pulTime = ((pAPE->ulTimePos / pAPE->usSampleRate) * 1000) +
(((pAPE->ulTimePos % pAPE->usSampleRate) * 1000) /
pAPE->usSampleRate);
}
// Success.
return(1);
}
// Return the sample rate at which this file is encoded.
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
tAPE *pAPE;
// The first parameter is a pointer to the MP3 persistent data.
pAPE = (tAPE *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
// Return the sample rate of the file.
*pulSampleRate = pAPE->usSampleRate;
// Success.
return(1);
}
// Return the number of channels in the file.
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
tAPE *pAPE;
// The first parameter is a pointer to the MP3 persistent data.
pAPE = (tAPE *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulChannels = pAPE->ucChannels;
// Success.
return(1);
}
// Return the bitrate at which this file is encoded.
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
tAPE *pAPE;
// The first parameter is a pointer to the MP3 persistent data.
pAPE = (tAPE *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulBitRate = pAPE->ulBitRate;
// Success.
return(1);
}
// Return the length (in milliseconds) of the file.
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
tAPE *pAPE;
// The first parameter is a pointer to the APE persistent data.
pAPE = (tAPE *)ulParam1;
pulLength = (unsigned long *)ulParam2;
// Return the length of the file.
*pulLength = pAPE->ulTimeLength;//单位为毫秒
// Success.
return(1);
}
case SUBFN_CODEC_GETCAPTUREBUFFER:
{
tAPE *pAPE;
pAPE = (tAPE *)ulParam1;
*(unsigned long *)ulParam2 = (unsigned long) pAPE->psLeft ;
*(unsigned long *)ulParam3 = (unsigned long) pAPE->psRight;
*(unsigned long *)ulParam4 = (unsigned long) OutLength ;
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
tAPE *pAPE;
pAPE = (tAPE *) ulParam1;
pAPE->status = ERROR_SUCCESS;
if (pAPE->status == ERROR_SUCCESS)
{
return(1);
}
else
{
return(0);
}
}
default:
{
// Return a failure.
return(0);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -