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

📄 audio.c

📁 arm嵌入式常用模块的程序源代码
💻 C
字号:
											//音频编解码主程序
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "decode.h"

void main(int argc, char**argv)
{
	FILE *musicout;
	Bit_stream_struc  bs;
	frame_params fr_ps;
	IIS_side_info_t IIS_side_info;
	IIS_scalefac_t IIS_scalefac;
	unsigned int old_crc;
	layer info;
	int sync, clip;
	int done = FALSE;
	unsigned long frameNum=0;
	unsigned long bitsPerSlot;
	unsigned long sample_frames;

	typedef short PCM[2][SSLIMIT][SBLIMIT];
	PCM *pcm_sample;                                         //PCM采样

	pcm_sample = (PCM *) mem_alloc((long) sizeof(PCM), "PCM Samp");
	if (argc==1) 
	{
		printf("Useage:decode file.mp3 output.pcm\n");
		return;
	}

	fr_ps.header = &info;

	if ((musicout = fopen(argv[2], "w+b")) == NULL) {
		printf ("Could not create \"%s\".\n", argv[2]);
		exit(1);
	}

    open_bit_stream_r(&bs, argv[1], BUFFER_SIZE);

	sample_frames = 0;
	while(!end_bs(&bs)) 
	{
															  //尝试帧同步
		sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LENGTH);
		if (!sync) 
		{
			done = TRUE;
			printf("\nFrame cannot be located\n");
			out_fifo(*pcm_sample, 3, &fr_ps, done, musicout, &sample_frames);
			break;
		}
															//解码帧头
		decode_info(&bs, &fr_ps);
									//将fr_ps.header中的信息解读到fr_ps的相关域中
		hdr_to_frps(&fr_ps);
															//输出相关信息
		if(frameNum == 0)
		   WriteHdr(&fr_ps);
		printf("\r%05lu", frameNum++);
		if (info.error_protection)
			buffer_CRC(&bs, &old_crc);
		switch (info.lay) {
		case 3:
		{
			int nSlots, main_data_end, flush_main;
			int bytes_to_discard, gr, ch, ss, sb;
			static int frame_start = 0;

			bitsPerSlot = 8;
			
															//取Side信息
			IIS_get_side_info(&bs, &IIS_side_info, &fr_ps);
			nSlots = main_data_slots(fr_ps);

															 //读取音频主数据
			for (; nSlots > 0; nSlots--)  			
				hputbuf((unsigned int) getbits(&bs,8), 8);
			main_data_end = hsstell() / 8; 			 /*前一帧数据*/
			if ( flush_main=(hsstell() % bitsPerSlot) ) 
			{
				hgetbits((int)(bitsPerSlot - flush_main));
				main_data_end ++;
			}
			bytes_to_discard = frame_start - main_data_end - IIS_side_info.main_data_begin ;
			if( main_data_end > 4096 ) 
			{   
				frame_start -= 4096;
				rewindNbytes( 4096 );
			}

			frame_start += main_data_slots(fr_ps);
			if (bytes_to_discard < 0) 
			{
				printf("Not enough main data to decode frame %d.  Frame discarded.\n",                  
						frameNum - 1); 
				break;
			}
			for (; bytes_to_discard > 0; bytes_to_discard--) hgetbits(8);

			clip = 0;
			for (gr=0;gr<2;gr++) {
				double lr[2][SBLIMIT][SSLIMIT],ro[2][SBLIMIT][SSLIMIT];
																//主解码
				for (ch=0; ch<fr_ps.stereo; ch++) 
				{
					long int is[SBLIMIT][SSLIMIT];  		 /*保存量化数据*/
					int part2_start;
					part2_start = hsstell();
																//获取比例因子
					IIS_get_scale_factors(&IIS_scalefac,&IIS_side_info, gr, ch, &fr_ps);
																//Huffman解码
					IIS_hufman_decode(is, &IIS_side_info, ch, gr, part2_start, &fr_ps);
																//反量化采样
					IIS_dequantize_sample(is, ro[ch], &IIS_scalefac, &(IIS_side_info.ch[ch].gr[gr]), ch, &fr_ps);
				}
																//立体声处理
				IIS_stereo(ro, lr, &IIS_scalefac, &(IIS_side_info.ch[0].gr[gr]), &fr_ps);
				for (ch=0; ch<fr_ps.stereo; ch++) 
				{
					double re[SBLIMIT][SSLIMIT];
					double hybridIn[SBLIMIT][SSLIMIT];	/* 滤波器输入 */
					double hybridOut[SBLIMIT][SSLIMIT];	/* 滤波器输出 */
					double polyPhaseIn[SBLIMIT];    		/* 多项输入. */

					IIS_reorder(lr[ch], re, &(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
																//抗锯齿处理
					IIS_antialias(re, hybridIn, 
								&(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
																//IMDCT
					for (sb=0; sb<SBLIMIT; sb++) 
					{ 									/* 合成. */
						IIS_hybrid(hybridIn[sb], hybridOut[sb], sb, ch,	&(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
					}
					for (ss=0;ss<18;ss++)					//多相频率倒置
						for (sb=0; sb<SBLIMIT; sb++)
							if ((ss%2) && (sb%2))
								hybridOut[sb][ss] = -hybridOut[sb][ss];
					for (ss=0;ss<18;ss++) { 				//多相合成
						for (sb=0; sb<SBLIMIT; sb++)
							polyPhaseIn[sb] = hybridOut[sb][ss];
																//子带合成
						clip += SubBandSynthesis(polyPhaseIn, ch, &((*pcm_sample)[ch][ss][0]));
					}
				}
																//PCM输出
			out_fifo(*pcm_sample, 18, &fr_ps, done, musicout, &sample_frames);
			}
			if(clip > 0)
				printf("\n%d samples clipped.\n", clip);
		}
			break;
		default:
			printf("\nOnly layer IIS supported!\n");
			exit(1);
			break;
		}
	}
	close_bit_stream_r(&bs);
	fclose(musicout);
	printf("\nDecoding done.\n");
	return;
}

⌨️ 快捷键说明

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