⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pape_dec.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 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 + -