pmp2dec.c

来自「瑞星微公司RK27XX系列芯片的SDK开发包」· C语言 代码 · 共 568 行 · 第 1/2 页

C
568
字号
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\MP2Dec\
Desc : MP2解码。

Author : FSH , Vincent Hisung
Date : 2007-08-xx
Notes :

$Log :
* FSH               2007/06/01 建立此文件
*
* vincent            2007/08/xx
*
*/
/****************************************************************/

#include "../include/audio_main.h"

#ifdef MP2_INCLUDE
#include "../include/audio_globals.h"
#include "include.h"

#include "MP2DEC_Instance.h"
#include "MP2DEC.h"

#include "../include/file_access.h"
#include "pMP2Dec_lib.h"

extern stID3V2XInfoType ID3V2XInfo;
static long OutLength;

extern unsigned int CheckID3V2Tag(unsigned char *pucBuffer);

F_MP2DEC0 *InitMP2Aud = RKInitMP2Audio;
F_MP2DEC1 *MP2SyncHeader = RKMP2DECSearchForSyncword;
//普通MP2解码
F_MP2DEC2 *MP2DecData = (F_MP2DEC2 *)RKMP2DecodeData;
//DAB的MP2解码
//F_MP2DEC2 *MP2DecData = (F_MP2DEC2 *)RKMP2DecodeData_DAB;

//****************************************************************************
//
// The codec plug-in entry point for the MP2 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:  MP2DecFunction
Desc:  MP2解码器接口函数
Param: ulIoctl 子功能号
    ulParam1 子功能参数1
    ulParam2 子功能参数2
    ulParam3 子功能参数3
    ulParam4 子功能参数4

Return: 0-失败 1-成功
Global: 无
Note: 无
Author: FSH
Log:
******************************************************/
unsigned long
MP2Function(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
            unsigned long ulParam3, unsigned long ulParam4)
{
    // Determine what to do based on the specified IOCTL.
    unsigned int WaitCounter;

    switch (ulSubFn)
    {
            // Return the bitrate at which this file is encoded.
        case SUBFN_CODEC_GETBITRATE:
            {
                unsigned long *pulBitRate;
                tMP2 *pMP2;

                // The first parameter is a pointer to the MP2 persistent data.
                pMP2 = (tMP2 *)ulParam1;

                // The second parameter is a pointer for the bitrate.
                pulBitRate = (unsigned long *)ulParam2;

                // Return the average bitrate of the file.
                *pulBitRate = pMP2->ulBitRate;

                // Success.
                return(1);
            }

            // Return the sample rate at which this file is encoded.
        case SUBFN_CODEC_GETSAMPLERATE:
            {
                unsigned long *pulSampleRate;
                tMP2 *pMP2;

                // The first parameter is a pointer to the MP2 persistent data.
                pMP2 = (tMP2 *)ulParam1;

                // The second parameter is a pointer for the sample rate.
                pulSampleRate = (unsigned long *)ulParam2;

                // Return the sample rate of the file.
                *pulSampleRate = pMP2->usSampleRate;

                // Success.
                return(1);
            }

        case SUBFN_CODEC_GETCAPTUREBUFFER:
            {
                tMP2 *pMP2;
                short **ppsBuffer;
                long *plLength;

                pMP2 = (tMP2 *)ulParam1;

                if (pMP2->ucChannels == 2)
                {
                    *(unsigned long *)ulParam2 = (unsigned long)pMP2->psLeft;
                    *(unsigned long *)ulParam3 = (unsigned long)pMP2->psRight;
                }
                else
                {
                    *(unsigned long *)ulParam2 = (unsigned long)pMP2->psLeft;
                    *(unsigned long *)ulParam3 = (unsigned long)pMP2->psLeft;
                }
                *(unsigned long *)ulParam4 = (unsigned long)OutLength;

                //success
                return(1);
            }

            // Return the number of channels in the file.
        case SUBFN_CODEC_GETCHANNELS:
            {
                unsigned long *pulChannels;
                tMP2 *pMP2;

                // The first parameter is a pointer to the MP2 persistent data.
                pMP2 = (tMP2 *)ulParam1;

                // The second parameter is a pointer for the number of channels.
                pulChannels = (unsigned long *)ulParam2;

                // Return the number of channels in the file.
                *pulChannels = pMP2->ucChannels;

                // Success.
                return(1);
            }

            // Return the length (in milliseconds) of the file.
        case SUBFN_CODEC_GETLENGTH:
            {
                unsigned long *pulLength;
                tMP2 *pMP2;

                // The first parameter is a pointer to the MP2 persistent data.
                pMP2 = (tMP2 *)ulParam1;

                pulLength = (unsigned long *)ulParam2;

                // Return the length of the file.
                *pulLength = pMP2->ulTimeLength;

                // Success.
                return(1);
            }

            // Return the current position (in milliseconds) within the file.
        case SUBFN_CODEC_GETTIME:
            {
                unsigned long *pulTime;
                tMP2 *pMP2;

                // The first parameter is a pointer to the MP2 persistent data.
                pMP2 = (tMP2 *)ulParam1;

                // The second parameter is a pointer for the number of seconds.
                pulTime = (unsigned long *)ulParam2;

                if (pMP2->usSampleRate == 0) return(0);

                // Determine the time based on the sample rate.
                *pulTime = ((pMP2->ulTimePos / pMP2->usSampleRate) * 1000) +
                           (((pMP2->ulTimePos % pMP2->usSampleRate) * 1000) /
                            pMP2->usSampleRate);

                // Success.
                return(1);
            }

            // Prepare the codec to encode or decode a file.
        case SUBFN_CODEC_OPEN_DEC:
            {
                tMP2 *pMP2;
                unsigned short count;

                // The first parameter is a pointer to the MP2 persistent state.
                pMP2 = (tMP2 *)ulParam1;

                // Determine the pointer to the MP2 decoder library's persistent
                // state.  This pointer must be aligned on a 2K byte boundary.
                pMP2->pMPEGInstance = (tMP2Instance *)(((unsigned long)pMP2 +
                                                        sizeof(tMP2) + 4) & 0xfffffffc);

                // Initialize the MP2 library.
                InitMP2Aud(pMP2->pMPEGInstance, (unsigned char *)pENCODED_DATA);
                memset(pMP2->psLeft, 0, (MP2_PCM_BUFFER_SIZE)*2);
                memset(pMP2->psRight, 0, (MP2_PCM_BUFFER_SIZE)*2);

                // Save the position of the beginning of the file.
                pMP2->ulFirstFrame = GetFirstFrame_MP2((unsigned char *)pENCODED_DATA);

                // Get the length of the file.
                pMP2->ulLength = (unsigned long)RKFIO_FLength(pRawFileCache) - pMP2->ulFirstFrame;

                // Decode the ID3 tag if it is present.
                //MP2DecodeID3Tag(pMP2);

                // Initialize the bitstream.
                MP2InitBitstream(pMP2, pMP2->ulFirstFrame);

                // Find the first frame of the file.
                count = 0;

                while (MP2FindNextFrame(pMP2) == 0)
                {
                    count += 1;

                    if (count > 1024) return (0);
                }

                // Get the sample rate of the file.
                pMP2->usSampleRate = usSRMap2[pMP2->sHdr.sample_rate];

                // Get the number of channels in the file.
                pMP2->ucChannels = pMP2->sHdr.numchans;

                // Attempt to decode the VBR header.
                if (MP2DecodeVBRHeader(pMP2) == 0)
                {
                    // There is no VBR header on this file, so get the actual
                    // bitrate from the sync header.
                    pMP2->ulBitRate = usBRMap2[((pMP2->sHdr.packed_info & 0x00080000) >> 15) |
                                               ((pMP2->sHdr.packed_info & 0x0000f000) >> 12)] * 1000;
                    // If no bitrate is specified, then return an error.
                    if (pMP2->ulBitRate == 0)
                    {
                        return(0);
                    }

                    // Indicate that this is not a VBR file.
                    pMP2->ucIsVBR = 0;
                }

                if (pMP2->ulBitRate == 0) return(0);


                // Get the length of the file.
                pMP2->ulTimeLength = (((pMP2->ulLength * 8) / pMP2->ulBitRate) * 1000) +
                                     ((((pMP2->ulLength * 8) % pMP2->ulBitRate) * 1000) /
                                      pMP2->ulBitRate);

                // Re-initialize the bitstream pointer structure.
                MP2InitBitstream(pMP2, pMP2->ulFirstFrame);

                // The position is zero.
                pMP2->ulTimePos = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?