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

📄 pogg_dec.c

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

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

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

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

#ifdef OGG_DEC_INCLUDE

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

char *alloca_buff = NULL;

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

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

OggVorbis_File vf;
int eof = 0;
int current_section;
char pcmout[4096]; /* take 4k out of the data segment, not the stack */
//__align(8) char pcmO[4096*2*4];
char *pcmO = NULL;
static long OggLength = 2048;
static long nDataInBuf = 0;

unsigned long
OggDecFunction(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:
            {
                long ret;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;
                while (1)
                {
                    ret = ov_read(&vf, pcmout, sizeof(pcmout), &current_section);
                    if (ret == 0)
                    {
                        /* EOF */  //正常结束
                        eof = 1;
                        return 0;
                    }
                    else if (ret < 0)
                    {
                        /* error in the stream.  Not a problem, just reporting it in
                        case we (the app) cares.  In this case, we don't. */
                        return 0;//非正常结束
                    }
                    else
                    {
                        memcpy(&pcmO[nDataInBuf] , pcmout, ret);
                        nDataInBuf += ret;
                        pOgg->ulTimePos += (ret / 2 / pOgg->ucChannels);

                        if (nDataInBuf >= 2048*2*2)
                        {
                            int i;
                            //输出(向左右声道BUF复制值)
                            //...
                            if (pOgg->ucChannels == 1)
                            {
                                for (i = 0; i < 2048*2 ;i++)
                                {
                                    pOgg->OGGleft[i] = *((short*)pcmO + i);
                                    pOgg->OGGright[i] = *((short*)pcmO + i);
                                }
                                OggLength = 2048 * 2;
                            }
                            else
                            {
                                for (i = 0; i < 2048 ;i++)
                                {
                                    pOgg->OGGleft[i] = *((short*)pcmO + i * 2);
                                    pOgg->OGGright[i] = *((short*)pcmO + i * 2 + 1);
                                }
                                OggLength = 2048;
                            }
                            //倒腾...
                            nDataInBuf -= 2048 * 2 * 2;
                            memcpy(&pcmO[0], &pcmO[2048*2*2], nDataInBuf);

                            return 1;
                        }
                    }
                }

                return 1;


            }

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

                tOGG *pOgg;

                alloca_buff = malloc(20480);
                if (alloca_buff == NULL)
                    return 0;

                if (pcmO == NULL)
                {
                    pcmO = malloc(4096 * 2 * 4);
                    if (pcmO == NULL)
                        return 0;
                }

                pOgg = (tOGG *)ulParam1;

                pOgg->ulLength = (unsigned long)RKFIO_FLength(pRawFileCache);

                nDataInBuf = 0;

                if (ov_open(pRawFileCache, &vf, NULL, 0) < 0)
                {
                    // "Input does not appear to be an Ogg bitstream."
                    return 0;
                }


                /* Throw the comments plus a few lines about the bitstream we're decoding */
                {
                    char **ptr = ov_comment(&vf, -1)->user_comments;
                    vorbis_info *vi = ov_info(&vf, -1);

                    pOgg->ulTimePos = 0;
                    pOgg->ulBitRate = vi->bitrate_nominal;
                    pOgg->usSampleRate = vi->rate;
                    pOgg->ucChannels = vi->channels;

                }


                //Bug Fix : Ogg Time Length , By Vincent Hisung , Jan 06 , 2008
                if (pOgg->usSampleRate != 0)
                    pOgg->ulTimeLength = (long long)ov_pcm_total(&vf, -1) * 1000 / pOgg->usSampleRate;
                else
                    pOgg->ulTimeLength = 0;

                if (pOgg->ulTimeLength == 0)
                {
                    pOgg->ulTimeLength = ((((unsigned long long)pOgg->ulLength * 8) / pOgg->ulBitRate) * 1000) +
                                         (((((unsigned long long)pOgg->ulLength * 8) % pOgg->ulBitRate) * 1000) /
                                          pOgg->ulBitRate);
                }



                return 1;
            }

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

                if (ov_time_seek(&vf, ulParam2))
                {
                    return 0;
                }
                else
                {
                    pOgg->ulTimePos = (long long)ulParam2 * pOgg->usSampleRate / 1000;
                }

                return(1);
            }

            // Return the current position (in milliseconds) within the file.
        case SUBFN_CODEC_GETTIME:
            {
                unsigned long *pulTime;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

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

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

                // Success.
                return(1);
            }

            // Return the sample rate at which this file is encoded.
        case SUBFN_CODEC_GETSAMPLERATE:
            {
                unsigned long *pulSampleRate;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

                pulSampleRate = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

            // Return the number of channels in the file.
        case SUBFN_CODEC_GETCHANNELS:
            {
                unsigned long *pulChannels;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

                pulChannels = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

            // Return the bitrate at which this file is encoded.
        case SUBFN_CODEC_GETBITRATE:
            {
                unsigned long *pulBitRate;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

                pulBitRate = (unsigned long *)ulParam2;

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

            // Return the length (in milliseconds) of the file.
        case SUBFN_CODEC_GETLENGTH:
            {
                unsigned long *pulLength;
                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

                pulLength = (unsigned long *)ulParam2;

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

                // Success.
                return(1);
            }

        case SUBFN_CODEC_GETCAPTUREBUFFER:
            {

                tOGG *pOgg;
                pOgg = (tOGG *)ulParam1;

                *(unsigned long *)ulParam2 = (unsigned long) pOgg->OGGleft ;
                *(unsigned long *)ulParam3 = (unsigned long) pOgg->OGGright;
                *(unsigned long *)ulParam4 = (unsigned long) OggLength ;

                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:
            {

                /* cleanup */
                ov_clear(&vf);

                if (pcmO != NULL)
                {
                    free(pcmO);
                    pcmO = NULL;
                }

                if (alloca_buff)
                {
                    free(alloca_buff);
                    alloca_buff = NULL;
                }
                return 1;
            }

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

#endif

⌨️ 快捷键说明

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