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

📄 demo_dec.c

📁 音频编解码库的具体实现,分析流程清晰,编译测试通过
💻 C
字号:
/*
 Note:
		G722.1 decoder demo file
		Read G722.1 encoded bitstream file, decode it and write in Microsoft Wave File Format.
*/
#include <stdio.h>
#include <time.h>
#include "g722codec.h"
#include "g722interface.h"

// G722.1 Decoder 输出:每帧40ms(与视频一致), 640个采样点(16位)
#define OUT_PACKET_LEN		(FRAMESIZE*2)
// 每次送给G722.1 Decoder的数据的长度(16位), 40ms
#define MAX_IN_BITS_LEN		(BIT_RATE_32000/(25*16))

/* add by cjk */
typedef struct _tagWaveFileHeader{
	unsigned char	ChunkID[4];
	long int 		ChunkSize;
	unsigned char	Format[4];
	unsigned char	Sub1ChunkID[4];
	long int		Sub1ChunkSize;
	short int		AudioFormat;
	short int		NumChannels;
	long int		SampleRate;
	long int		ByteRate;
	short int		BlockAlign;
	short int		BitsPerSample;
	unsigned char	Sub2ChunkID[4];
	long int		Sub2ChunkSize;
}WaveFileHeader;

unsigned int	g_test_time[10];
int   g_nTest[10];
int   g_nFrameNum = 0;

unsigned __int64 g_startcount[10];
unsigned __int64 g_endcount[10];

void ReadTimestampCounter(unsigned __int64 *count)
{ 
#ifdef _WIN64
	*count = 0;
#else 
#ifdef _WIN32
    unsigned __int64 c;
    __asm push eax
    __asm push edx
    __asm _emit 0x0f
    __asm _emit 0x31
    __asm mov dword ptr c,   eax
    __asm mov dword ptr c+4, edx
    __asm pop edx
    __asm pop eax
    *count = c;
#endif
#ifdef LINUX
	*count = 0;
#endif
#endif
}

void StartTimer(int n)
{
	ReadTimestampCounter(&g_startcount[n]);
}

void StopTimer(int n)
{
	ReadTimestampCounter(&g_endcount[n]);
	g_test_time[n] += (int)((g_endcount[n] - g_startcount[n] - 13 - 1)-133);
	g_nTest[n]++;
}



main(int argc,char *argv[])
{
	FILE *f_input, *f_output;
    short int number_of_bits_per_frame, number_of_16bit_words_per_frame;
    int in_words[MAX_IN_BITS_LEN/2];		/* input */
    int output[OUT_PACKET_LEN/2];		/* output */
	int inlen_per_frame;
	/* add wave file header by cjk */
	int filesize=0, framenum=0;
	int bitrate = 16000;
	int packet_len=0;
    WaveFileHeader header={	"RIFF",		/* ChunkID */
    						0,			/* ChunkSize */
    						"WAVE",		/* format */
    						"fmt ",		/* Sub1ChunkID */
    						0x10,		/* Sub1ChunkSize */
    						1,			/* Audio Format */
    						1,			/* NumChannels */
    						0,			/* SampleRate */
    						0,			/* ByteRate */
    						0,			/* BlockAlign */
    						0,			/* BitsPerSample */
    						"data",		/* Sub2ChunkID */
    						0			/* Sub2ChunkSize */
    						};

	G722_CODEC_PARA decPara;
	void * hDec = NULL;
	int outsize = 0;
	int i;

    if (argc !=4 )
    {
        printf("Usage :%s  <bitstream_file>  <outputaudio_file> <bitrate> \n",argv[0]);
		printf("\n");
		printf("<bitstream_file>:\n");
		printf("  Input bitstream file.\n");
		printf("<outputaudio_file>:\n");
		printf("  Output file is written to a microsoft wave format file.\n");
		printf("<bitrate>:\n");
		printf("  bitrate must be 24000, 32000 or 16000.\n");
		printf("\n");
        exit(1);
    }

	if ( (f_input = fopen(argv[1], "rb")) == NULL) {
		printf("Error opening file %s !!\n", argv[1]);
		exit(0);
	}
	printf(" Input audio file    :  %s\n", argv[1]);
	
	if ( (f_output = fopen(argv[2], "wb")) == NULL) {
		printf("Error opening file %s !!\n", argv[2]);
		exit(0);
	}
	printf(" Output bitstream file:  %s\n", argv[2]);

    bitrate = atoi(argv[3]);
	printf(" Bitrate = %d\n", bitrate);

	number_of_bits_per_frame = bitrate/50;	/* 20ms per frame */
	number_of_16bit_words_per_frame = number_of_bits_per_frame/16;	/* 16_bit words */

	fseek(f_input, 0, SEEK_END);
	filesize = ftell(f_input);
	fseek(f_input, 0, SEEK_SET);

	packet_len = number_of_16bit_words_per_frame;		/* number of 16_bit words */

	framenum = filesize/(packet_len*2);

    header.Sub2ChunkSize = framenum * FRAMESIZE * 2;	/* 8KHz, 16bits */
    header.ChunkSize = header.Sub2ChunkSize + 0x24;
    header.BitsPerSample = 0x10;
    header.NumChannels = 1;	
    header.SampleRate = 16000;	/* G722.1 sample rate is 16KHz */
    header.ByteRate = header.SampleRate * header.NumChannels * header.BitsPerSample / 8;
    header.BlockAlign = header.NumChannels * header.BitsPerSample / 8;
    
	fwrite(&header, 1, sizeof(WaveFileHeader), f_output);
    

	inlen_per_frame = bitrate/(25*16);	/* nubmer of 16_bit words per 40ms */
	/* Init G722.1 decoder */
	G722_GetDecoderMemSize(&decPara);
	if((decPara.buffer = malloc(decPara.bufferSize)) == NULL)
	{
		DebugPrint("not enough memory : %d\n", decPara.bufferSize);
		return 0;
	}
	decPara.bitrate = 16000;
	if(argc>3)
		decPara.bitrate = atoi(argv[3]);

	hDec = G722_CreateDecoder(&decPara);
	if(hDec == NULL)
	{
		DebugPrint("create decoder error!\n");
		exit(0);
	}
	g_nFrameNum = 0;
	/* read one frame(40ms) from file */
    while((int)fread(in_words, 2, inlen_per_frame, f_input)==inlen_per_frame) 
    {
		/* Decoder one frame */
		outsize = OUT_PACKET_LEN*2;
		StartTimer(0);
		G722_Decode(hDec, (char*)in_words, inlen_per_frame*2, (short*)output, &outsize);
		StopTimer(0);

        /* Write frame of output samples */
        if(fwrite(output, 1, outsize, f_output)!=(OUT_PACKET_LEN*2))
			printf("write error on frame %d.\n", g_nFrameNum);

        g_nFrameNum++;
/*		printf("g_nFrameNum=%d\n", g_nFrameNum); */
    }
	
	printf("total frame =%d \n", g_nFrameNum);  
	for(i = 0; i < 10; i++)
	{
		if(g_nTest[i] > 0 && g_nFrameNum > 0)
			printf("\nNO.%d: 平均每帧需要%u微妙, 每帧调用%u次,每次%u微妙 %u时钟\n", 
			i,
			(unsigned int)(g_test_time[i]/2800/g_nFrameNum),
			g_nTest[i]/g_nFrameNum, 
			(unsigned int)(g_test_time[i]/g_nTest[i]/2800),
			(unsigned int)(g_test_time[i]/g_nTest[i]));
	}
	printf("共编码%d帧\n", g_nFrameNum);


    fclose(f_input);
    fclose(f_output);

    return 0;        
}

⌨️ 快捷键说明

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