📄 pamrdec.c
字号:
//
//
//
#include "../include/audio_main.h"
#include "../include/audio_globals.h"
#include "../include/file_access.h"
#ifdef AMR_INCLUDE
#include "pAMRDec.h"
#define AMR_MAGIC_NUMBER "#!AMR\n" // AMR-NB
#define AMR_WB_MAGIC_NUMBER "#!AMR-WB\n" // AMR-WB
extern MY_FILE *pRawFileCache;
extern short VideoPlaying;
static short LeftOutBuf[160];
static short RightOutBuf[160];
/*
* AMR File IO
*/
int AMR_FRead(void *fp, unsigned char *buf, int size)
{
return RKFIO_FRead((MY_FILE *)fp, buf, size);
}
int AMR_FSeek(void *fp, int where, int how)
{
RKFIO_FSeek((MY_FILE *)fp, where, how);
}
int AMR_FLength(void *fp)
{
return RKFIO_FLength((MY_FILE *)fp);
}
/*
函数: check_amr
描述: 检查是否为合法的AMR文件
参数: IN [fp] -- amr文件指针
OUT[info] -- amr文件基本信息
返回: 0 -- AMR-NB
1 -- AMR-WB
other -- 不是amr文件
*/
int check_amr(void *fp, sAMRFileInfo *info)
{
char magic[12];
int cbHeaderNB = strlen(AMR_MAGIC_NUMBER);
int cbHeaderWB = strlen(AMR_WB_MAGIC_NUMBER);
if(RKFIO_FRead(fp, magic, 12) != 12)
return -1;
if (strncmp((const char *)magic, AMR_MAGIC_NUMBER, cbHeaderNB) == 0)
{ // AMR-NB
info->AMRHeaderSize = cbHeaderNB;
RKFIO_FSeek(fp, info->AMRHeaderSize, 0);
return 0;
}
else if (strncmp((const char *)magic, AMR_WB_MAGIC_NUMBER, cbHeaderWB) == 0)
{ // AMR-WB
info->AMRHeaderSize = cbHeaderWB;
RKFIO_FSeek(fp, info->AMRHeaderSize, 0);
return 1;
}
return -1;
}
//****************************************************************************
//
// The codec plug-in entry point for the AMR 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_SETBUFFER: 不支持
//SUBFN_CODEC_DECODE : 解码
//SUBFN_CODEC_ENCODE : 不支持
//SUBFN_CODEC_SEEK : 按时间直接定位 [单位:毫秒]
//SUBFN_CODEC_CLOSE : 关闭解码器
unsigned long
AMRFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
unsigned long ulParam3, unsigned long ulParam4)
{
switch(ulSubFn)
{
// Return the name for this codec.
case SUBFN_CODEC_GETNAME:
{
char **ppcName;
ppcName = (char **)ulParam2;
*ppcName = "AMR";
// Success.
return(1);
}
// Return the name of the artist.
case SUBFN_CODEC_GETARTIST:
{
char **ppcName;
*ppcName = "";
// Success.
return(1);
}
// Return the name of the song
case SUBFN_CODEC_GETTITLE:
{
char **ppcName;
*ppcName = "";
// Success.
return(1);
}
// Return the bitrate at which this file is encoded.
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
*pulBitRate = pAMR->BitRate;
// Success.
return(1);
}
// Return the sample rate at which this file is encoded.
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
*pulSampleRate = pAMR->SampleRate;
// Success.
return(1);
}
// Return the number of channels in the file.
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
*pulChannels = pAMR->NumOfChannel;
// Success.
return(1);
}
// Return the length (in milliseconds) of the file.
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
pulLength = (unsigned long *)ulParam2;
// Return the length of the file.
*pulLength = pAMR->DurationTime;
// Success.
return(1);
}
// Return the current position (in milliseconds) within the file.
case SUBFN_CODEC_GETTIME:
{
unsigned long *pulTime;
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
pulTime = (unsigned long *)ulParam2;
*pulTime = (( pAMR->DecodedSamples/pAMR->SampleRate)*1000) +
(((pAMR->DecodedSamples%pAMR->SampleRate)*1000) / pAMR->SampleRate);
// Success.
return(1);
}
// Prepare the codec to encode or decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
if(!VideoPlaying)
{
if(check_amr((void *)pRawFileCache, pAMR) != 0)
return 0;
}
if(amr_docoder_init((void *)pRawFileCache, pAMR) != 0)
return 0;
// Success.
return(1);
}
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
sAMRFileInfo *pAMR;
pAMR = (sAMRFileInfo *)ulParam1;
if(amr_docoder_dec((void *)pRawFileCache, pAMR, LeftOutBuf) != 0)
return(0);
// AMR解码输出的pcm数据固定为单声道,长度为160
memcpy(RightOutBuf, LeftOutBuf, sizeof(short)*160);
// Success.
return(1);
}
/// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
if(amr_decoder_seek((void *)pRawFileCache, (sAMRFileInfo *)ulParam1, (int)ulParam2) != 0)
return(0);
// Success.
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
amr_docoder_close();
// Success.
return(1);
}
//
case SUBFN_CODEC_GETCAPTUREBUFFER:
{
*(unsigned long *)ulParam2 =(unsigned long) LeftOutBuf ;
*(unsigned long *)ulParam3 =(unsigned long) RightOutBuf;
*(unsigned long *)ulParam4 =(unsigned long) 160 ;
// Success.
return(1);
}
// We should never get here, but just in case...
default:
{
// Return a failure.
return(0);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -