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

📄 pamrdec.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 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 + -