📄 pogg_dec.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), ¤t_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 + -