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

📄 pac3_dec.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\Ac3Dec
Desc : ac3解码。

Author : FANGSAIHONG
Date : 2007-12-17
Notes :

$Log :
* FANGSAIHONG    2007/12/17 建立此文件
*
*
*
*
*
*/
/****************************************************************/

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

#ifdef AC3_DEC_INCLUDE

#include "../include/audio_globals.h"
#include "../include/file_access.h"
#include "pAC3_DEC.h"


#define BUFFER_SIZE 4096

#define A52_SAMPLESPERFRAME (6*256)

a52_state_t *state;
unsigned long samplesdone;
unsigned long frequency;

unsigned char in_buf[BUFFER_SIZE];
int flags, sample_rate, bit_rate, n;
int Ac3Length;
short *leftpcm, *rightpcm;
int  BuffLeftPcmData;

void output_audio(sample_t *samples)
{

#if 1
    int i = 0;
    short tmp;
    for (i = 0 ; i < 256; i++)
    {
        /*
        fwrite(&samples[i],sizeof(sample_t),1,file_out);
        fwrite(&samples[i],sizeof(sample_t),1,file_out);
        */
        tmp = (samples[i] >> 16) & 0xffff;
        *leftpcm++ = tmp;
        tmp = (samples[i+256] >> 16) & 0xffff;
        *rightpcm++ = tmp;
        //fwrite(&tmp,1,2,file_out);
    }
    BuffLeftPcmData += 256;
#endif
}

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

Return: 0-失败 1-成功
Global: 无
Note: 无
Author: HXD
Log:
******************************************************/

/*
short Ac3Left[0x5000];
short Ac3Right[0x5000];
*/
short *Ac3Left = NULL;
short *Ac3Right = NULL;

unsigned long
AC3DecFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
               unsigned long ulParam3, unsigned long ulParam4)
{

    switch (ulSubFn)
    {

            // Decode a frame of data.
        case SUBFN_CODEC_DECODE:
            {
                tAC3 *pAC3;
                pAC3 = (tAC3 *)ulParam1;
                while (BuffLeftPcmData < 0x1800)
                {

                    a52_decode_data(in_buf, in_buf + n);

                    //printf ("samplesdone %i\n",samplesdone);

                    n = RKFIO_FRead(pRawFileCache, in_buf,   BUFFER_SIZE);

                    if (n == 0) /* End of Stream */
                        return 0;
                }



                BuffLeftPcmData -= 0x1800;
                leftpcm = &Ac3Left[BuffLeftPcmData];
                rightpcm = &Ac3Right[BuffLeftPcmData];
                memcpy(pAC3->AC3left, Ac3Left, 0x1800*2);
                memcpy(pAC3->AC3right, Ac3Right, 0x1800*2);
                memcpy(&Ac3Left[0], &Ac3Left[0x1800], BuffLeftPcmData*2);
                memcpy(&Ac3Right[0], &Ac3Right[0x1800], BuffLeftPcmData*2);

                pAC3->ulTimePos += 0x1800;
                return 1;


            }

            // Prepare the codec to decode a file.
        case SUBFN_CODEC_OPEN_DEC:
            {

                tAC3 *pAC3;
                pAC3 = (tAC3 *)ulParam1;

                if (Ac3Left == NULL)
                {
                    Ac3Left = malloc(0x5000 * sizeof(short));
                    if (Ac3Left == NULL)
                        return 0;
                }
                if (Ac3Right == NULL)
                {
                    Ac3Right = malloc(0x5000 * sizeof(short));
                    if (Ac3Right == NULL)
                        return 0;
                }

                pAC3->ulLength = (unsigned long)RKFIO_FLength(pRawFileCache);
                BuffLeftPcmData = 0;
                n = 0;
                state = a52_init(0);
                if (state == NULL)
                {
                    // fprintf (stderr, "A52 init failed\n");
                    return 0;
                }

                samplesdone = 0;
                {
                    int pos = 0;
                    int flag = 1;
                    while (flag)
                    {
                        int i ;
                        pos += n;
                        if (pos > 20 * 1024)
                            return 0;
                        n = RKFIO_FRead(pRawFileCache, in_buf,   BUFFER_SIZE);

                        if (n < BUFFER_SIZE) /* End of Stream */
                            return 0;

                        for (i = 0; i < BUFFER_SIZE - 1 ; i ++)
                        {
                            if (in_buf[i] == 0x0b)
                            {
                                if (in_buf[i+1] == 0x77)
                                {
                                    if (a52_syncinfo(&in_buf[i], &flags, &sample_rate, &bit_rate) > 0)
                                    {
                                        flag = 0;
                                        pos += i;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    RKFIO_FSeek(pRawFileCache, pos, SEEK_SET);
                    pAC3->ulLength -= pos;
                }

                n = RKFIO_FRead(pRawFileCache, in_buf,   BUFFER_SIZE);

                if (n == 0) /* End of Stream */
                    return 0;

                if (0 == a52_syncinfo(in_buf, &flags, &sample_rate, &bit_rate))
                {
                    return 0;
                }
                //printf("sr: %i , br: %i \n",sample_rate,bit_rate);
                pAC3->ulTimePos = 0;
                pAC3->ulBitRate = bit_rate;
                pAC3->usSampleRate = sample_rate;
                pAC3->ucChannels = 2;

                leftpcm = Ac3Left;
                rightpcm = Ac3Right;

                // a52_decode_data(in_buf, in_buf + n);

                // n = RKFIO_FRead(pRawFileCache, in_buf,   BUFFER_SIZE);

                Ac3Length = 0x1800;

                pAC3->ulTimeLength = ((((unsigned long long)pAC3->ulLength * 8) / pAC3->ulBitRate) * 1000) +
                                     (((((unsigned long long)pAC3->ulLength * 8) % pAC3->ulBitRate) * 1000) /
                                      pAC3->ulBitRate);


                return 1;
            }

            // Seek to the specified time position.
        case SUBFN_CODEC_SEEK:
            {
                unsigned long ulPos, ulFrameSize;
                tAC3 *pAC3;
                pAC3 = (tAC3 *)ulParam1;

                ulFrameSize = 4608;

                // Compute the number of frames that occur before the requested
                // time position.
                ulPos = (((ulParam2 / 1000) * pAC3->usSampleRate) /
                         ulFrameSize) +
                        (((ulParam2 % 1000) * pAC3->usSampleRate) /
                         (ulFrameSize * 1000));

                // Compute the time for the computed frame number.
                pAC3->ulTimePos = ulPos = ulPos * ulFrameSize;
                samplesdone = pAC3->ulTimePos;
                // Compute the file position based on the actual seek time.
                if (pAC3->usSampleRate)
                {
                    ulPos = ((ulPos / pAC3->usSampleRate) *
                             (pAC3->ulBitRate / 8)) +
                            (((ulPos % pAC3->usSampleRate) *
                              (pAC3->ulBitRate / 8)) / pAC3->usSampleRate);
                }


                // Seek to the specified position.
                RKFIO_FSeek(pRawFileCache, ulPos, SEEK_SET);

                return(1);
            }

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

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

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

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

                // Success.
                return(1);
            }

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

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

                pulSampleRate = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

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

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

                pulChannels = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

            // Return the bitrate at which this file is encoded.
        case SUBFN_CODEC_GETBITRATE:
            {
                unsigned long *pulBitRate;
                tAC3 *pAC3;

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

                pulBitRate = (unsigned long *)ulParam2;

                // Return the number of channels in the file.
                *pulBitRate = pAC3->ulBitRate;
                // Success.
                return(1);
            }

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

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

                pulLength = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

        case SUBFN_CODEC_GETCAPTUREBUFFER:
            {

                tAC3 *pAC3;

                // The first parameter is a pointer to the MP3 persistent data.
                pAC3 = (tAC3 *)ulParam1;

                *(unsigned long *)ulParam2 = (unsigned long) pAC3->AC3left ;
                *(unsigned long *)ulParam3 = (unsigned long) pAC3->AC3right;
                *(unsigned long *)ulParam4 = (unsigned long) Ac3Length ;

                return(1);
            }
            // Return the name of the artist.
        case SUBFN_CODEC_GETARTIST:
            {


                // Success.
                return(1);
            }

            // Return the name of the song
        case SUBFN_CODEC_GETTITLE:
            {

                // Success.
                return(1);
            }


            // Cleanup after the codec.
        case SUBFN_CODEC_CLOSE:
            {
                if (Ac3Left != NULL)
                {
                    free(Ac3Left);
                    Ac3Left = NULL;
                }
                if (Ac3Right != NULL)
                {
                    free(Ac3Right);
                    Ac3Right = NULL;
                }

                a52_free(state);

            }

        default:
            {
                // Return a failure.
                return(0);
            }
    }
}

#endif

⌨️ 快捷键说明

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