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

📄 amr_dec.c

📁 这是一个平台无关的标准C的AMR解码库
💻 C
字号:
#include "amr_dec.h"
#include "sp_dec.h"
#include "cnst.h"
#include "frame.h"
#include "d_homing.h"

#define AMR_MAGIC_NUMBER "#!AMR\n"
#define MAX_PACKED_SIZE (MAX_SERIAL_SIZE / 8 + 2)
#define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5)

typedef struct {
	Speech_Decode_FrameState *speech_decoder_state;
	Word16 serial[SERIAL_FRAMESIZE];   /* coded bits                    */
	Word16 synth[L_FRAME];             /* Synthesis                     */
	Word32 synIndex;
	Word32 synLen;
	Word8* data;
	Word32 dataIndex;
	Word32 len;
//	Word32 frame;
	enum Mode mode;
	enum RXFrameType rx_type;
	enum TXFrameType tx_type;
	Word16 reset_flag;
	Word16 reset_flag_old;
}Amr_Dec_Handle;

void* AMR_dec_Init(		  /* return decoder handle			*/
   char*	data,	      /* i   : amr file	data			*/
   int		len,	      /* i   : data length				*/
   int*		erro	      /* o   : erro code if return NULL	*/
)
{
	Amr_Dec_Handle* p = 0;

	/* check magic number */
	if (strncmp(data, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER))) {
		*erro = AMR_DEC_BAD_DATA;
		return 0;
	}

	p = (Amr_Dec_Handle*)malloc(sizeof(Amr_Dec_Handle));
	memset((void*)p,0,sizeof(Amr_Dec_Handle));

  /* Initialization of decoder */
	if (Speech_Decode_Frame_init(&(p->speech_decoder_state), "Decoder")){
		*erro = AMR_DEC_BAD;
		free(p);
		p = 0;
	}
	else{
		p->data = data;
		p->len = len;
	}

	p->dataIndex += strlen(AMR_MAGIC_NUMBER);
	p->reset_flag_old = 1;
	return (void*)p;
}

int AMR_dec_Decode(		  /* return decoded data length(frame)				*/
   void*	decoder,	  /* i   : initialized decoder handle				*/
   int		len,		  /* i   : want decode data length(frame)			*/
   short*	buf		      /* o   : decoded data buffer(8K 16bits samples)	*/
)
{
	Amr_Dec_Handle* p = (Amr_Dec_Handle*)decoder;
	Word32 i_Copied = 0;
	Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
	
	if (p->synLen>0) {
		if (p->synLen>=len) {
			memcpy((void*)buf,(void*)(p->synth+p->synIndex),len*2);
			p->synIndex += len*2;
			p->synLen -= len;
			return len;
		}
		else{
			memcpy((void*)buf,(void*)(p->synth+p->synIndex),p->synLen*2);
			i_Copied += p->synLen;
			len -= i_Copied;
			buf += i_Copied;
		}
	}

	while (p->dataIndex<(p->len-1)) {
		UWord8 toc, q, ft;
		UWord8 *packed_bits = 0;

		toc = *((UWord8*)(p->data+p->dataIndex));
		p->dataIndex++;
		q  = (toc >> 2) & 0x01;
		ft = (toc >> 3) & 0x0F;
		packed_bits = (UWord8*)(p->data+p->dataIndex);
		//fread (packed_bits, sizeof(UWord8), packed_size[ft], file_serial);
		p->dataIndex += packed_size[ft];

		p->rx_type = UnpackBits(q, ft, packed_bits, &(p->mode), &p->serial[1]);

		if (p->rx_type == RX_NO_DATA) {
		p->mode = p->speech_decoder_state->prev_mode;
		}
		else {
		p->speech_decoder_state->prev_mode = p->mode;
		}

		/* if homed: check if this frame is another homing frame */
		if (p->reset_flag_old == 1)
		{
		 /* only check until end of first subframe */
		 p->reset_flag = decoder_homing_frame_test_first(&p->serial[1], p->mode);
		}
		/* produce encoder homing frame if homed & input=decoder homing frame */
		if ((p->reset_flag != 0) && (p->reset_flag_old != 0))
		{
		 Word16 i;
		 for (i = 0; i < L_FRAME; i++)
		 {
			 p->synth[i] = EHF_MASK;
		 }
		}
		else
		{     
		 /* decode frame */
		 Speech_Decode_Frame(p->speech_decoder_state, p->mode, &p->serial[1],
							 p->rx_type, p->synth);
		}

		/* write synthesized speech to file 
		if (fwrite (synth, sizeof (Word16), L_FRAME, file_syn) != L_FRAME) {
		 fprintf(stderr, "\nerror writing output file: %s\n",
				 strerror(errno));
		};
		fflush(file_syn);*/

		/* if not homed: check whether current frame is a homing frame */
		if (p->reset_flag_old == 0)
		{
		 /* check whole frame */
		 p->reset_flag = decoder_homing_frame_test(&p->serial[1], p->mode);
		}
		/* reset decoder if current frame is a homing frame */
		if (p->reset_flag != 0)
		{
		 Speech_Decode_Frame_reset(p->speech_decoder_state);
		}
		p->reset_flag_old = p->reset_flag;
		if (len<=L_FRAME) {
			memcpy((void*)buf,(void*)(p->synth),len*2);
			p->synIndex += len;
			p->synLen = L_FRAME-len;
			i_Copied += len;
			return i_Copied;
		}
		else{
			memcpy((void*)buf,(void*)(p->synth),L_FRAME*2);
			buf += L_FRAME;
			i_Copied += L_FRAME;
			len -= L_FRAME;
		}

	}
	return i_Copied;
}

void AMR_dec_Close(
   void*	decoder		  /* i   : decoder handle	*/
   )
{
	Amr_Dec_Handle* p = (Amr_Dec_Handle*)decoder;
	if (p) {
		Speech_Decode_Frame_exit(&p->speech_decoder_state);
		if (p->data) {
			free(p->data);
		}
		free(p);
	}
	return;
}

⌨️ 快捷键说明

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