提供一种找MP3帧头的方式

关于MP3相关的知识,我这边看的是作者:“crifan" 整理的一个文档,会上传这个pdf。

MPEG的帧头格式:

MPEG帧头(Frame Header):
MPEG帧头:共32bit=4字节

[0~10]:		1111 1111 111	同步帧
[11~12]:	11				MPEG音频的版本ID (00)MPEG2.5 (01)保留 (10)MPEG2 (11)MPEG1
[13~14]:	01				Layer版本 (00)保留 (01)LayerIII (10)LayerII (11)LayerI
[15]:		1				保护位 (0)-用16位的CRC保护下面的帧头 (1)-无CRC
[16~19]:	1001			比特率索引 (1001)对于MPEG1的LayerIII是128kbit/s->128k位每秒
[20~21]:	11				采样率索引 (11)对于MPEG1是44100Hz
[22]:		0				填充位,如果设置了此位,就会对每帧数据填充一个slot
[23]:		1				私有位
[24~25]		01				声道 (00)立体声 (01)混合立体声 (10)双声道 (11)一个声道(单声道)
[26~27]		00				模式扩展(仅用于联合立体声)
[28]:		0				Copyright: (0) audio not copyrighted (1) Audio is copyrighted	版权,音频是是否受版权保护
[29]:		0				Original: (0) Copy of Original media (1) Original media 原始媒体副本 还是原始媒体
[30~31]:	00				Emphasis (00) None (01)-50/15 ms (10) reserved (11) CCIT J.17
  • 定义帧结构体:
typedef struct MPEG_HEAD{
	unsigned int sync 		: 11;
	unsigned int version	: 2;
	unsigned int layer		: 2;
	unsigned int crc		: 1;
	unsigned int bitrate	: 4;
	unsigned int samplerate : 2;
	unsigned int padding	: 1;
	unsigned int private	: 1;
	unsigned int channel    : 2;
	unsigned int extension  : 2;
	unsigned int copyright	: 1;
	unsigned int original	: 1;
	unsigned int emphasis	: 2;
}MPEG_Head_t;
  • 计算帧头:
void vMH_SwitchHeader(MPEG_Head_t *header)
{
	UINT8 data[4];
	memcpy(data,(UINT8*)header,4);
	//printf("%02x %02x %02x %02x\r\n",data[0],data[1],data[2],data[3]);
	memset((UINT8*)header,0,4);
	header->sync = data[0]|((data[1]>>5)<<8);
	header->version = ((data[1]>>3)&0x3);
	header->layer = ((data[1]>>1)&0x3);
	header->crc = (data[1]&0x01);
	header->bitrate = (data[2]>>4);
	header->samplerate = (data[2]>>2)&0x3;
	header->padding = (data[2]>>1)&0x1;
	header->padding = (data[2])&0x1;
	header->channel = (data[3]<<6)&0x3;
	header->extension = (data[3]<<4)&0x3;
	header->copyright = (data[3]<<3)&0x1;
	header->original = (data[3]<<2)&0x1;
	header->emphasis = (data[3]&0x3);


}
  • 输出MP3格式信息:
void vMH_GetSamplerateNum(MPEG_Head_t *header,UINT32 *Sampleratenum)
{
	UINT32 psampleratenum = 0;
	switch(header->version)
	{
		case MPEG1:
		{
			switch(header->layer)
			{
			case LAYERI:
				psampleratenum = 384;
				break;
			case LAYERII:
				psampleratenum = 1152;
				break;
			case LAYERIII:
				psampleratenum = 1152;
				break;
			}
			break;
		}
		case MPEG2_5:
		case MPEG2:
		{
			switch(header->layer)
			{
			case LAYERI:
				psampleratenum = 384;
				break;
			case LAYERII:
				psampleratenum = 1152;
				break;
			case LAYERIII:
				psampleratenum = 576;
				break;
			}
			break;
		}
	}
	printf("psampleratenum = %d\r\n",psampleratenum);
	*Sampleratenum = psampleratenum;
}

void vMH_GetMp3HeaderInfo(MPEG_Head_t *header)
{
	UINT32 bitrate = 0;
	UINT32 samplerate = 0;
	printf("sync 		= %x\r\n",header->sync);
	printf("version 	= %x\r\n",header->version);
	printf("layer 		= %x\r\n",header->layer);
	printf("crc 		= %x\r\n",header->crc);
	printf("bitrate 	= %x\r\n",header->bitrate);
	printf("samplerate 	= %x\r\n",header->samplerate);
	printf("padding 	= %x\r\n",header->padding);
	printf("private 	= %x\r\n",header->private);
	printf("channel 	= %x\r\n",header->channel);
	printf("extension 	= %x\r\n",header->extension);
	printf("copyright 	= %x\r\n",header->copyright);
	printf("original 	= %x\r\n",header->original);
	printf("emphasis 	= %x\r\n",header->emphasis);

	switch(header->version)
	{
		case MPEG2_5:
			printf("MPEG 2.5\r\n");
			break;
		case MPEG_NONE:
			printf("Reserved\r\n");
			break;
		case MPEG2:
			printf("MPEG 2\r\n");
			break;
		case MPEG1:
			printf("MPEG 1\r\n");
			break;
		default:
			printf("Frame Header error\r\n");
			break;
	}

	switch(header->layer)
	{
		case LAYER_NONE:
			printf("Reserved\r\n");
			break;
		case LAYERIII:
			printf("Layer III\r\n");
			break;
		case LAYERII:
			printf("Layer II\r\n");
			break;
		case LAYERI:
			printf("Layer I\r\n");
			break;
		default:
			printf("Frame Header error\r\n");
			break;
	}
	switch(header->crc)
	{
		case CRC_USE:
			printf("Use crc\r\n");
			break;
		case CRC_NONE:
			printf("None CRC\r\n");
			break;
		default:
			printf("Frame Header error\r\n");
			break;
	}

	switch(header->bitrate)
	{
		case BITRATE_FREE:
			printf("free\r\n");
			break;
		case BITRATE_1:
		{
			if(header->version == MPEG1)
			{
				bitrate = 32;
				//printf("bitrate = 32 kbit/s\r\n");
			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 32;
					//printf("bitrate = 32 kbit/s\r\n");
				}
				else
				{
					bitrate = 8;
					//printf("bitrate = 8 kbit/s\r\n");
				}
			}
			break;
		}
		case BITRATE_2:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 64;
						//printf("bitrate = 64 kbit/s\r\n");
						break;
					case LAYERII:
						bitrate = 48;
						//printf("bitrate = 48 kbit/s\r\n");
						break;
					case LAYERIII:
						bitrate = 40;
						//printf("bitrate = 40 kbit/s\r\n");
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 48;
					//printf("bitrate = 48 kbit/s\r\n");
				}
				else
				{
					bitrate = 16;
					//printf("bitrate = 16 kbit/s\r\n");
				}
			}
			break;
		}
		case BITRATE_3:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 96;
						break;
					case LAYERII:
						bitrate = 56;
						break;
					case LAYERIII:
						bitrate = 48;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 56;
				}
				else
				{
					bitrate = 24;
				}
			}
			break;
		}
		case BITRATE_4:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 128;
						break;
					case LAYERII:
						bitrate = 64;
						break;
					case LAYERIII:
						bitrate = 56;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 64;
				}
				else
				{
					bitrate = 32;
				}
			}
			break;
		}
		case BITRATE_5:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 160;
						break;
					case LAYERII:
						bitrate = 80;
						break;
					case LAYERIII:
						bitrate = 64;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 80;
				}
				else
				{
					bitrate = 40;
				}
			}
			break;
		}
		case BITRATE_6:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 192;
						break;
					case LAYERII:
						bitrate = 96;
						break;
					case LAYERIII:
						bitrate = 80;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 96;
				}
				else
				{
					bitrate = 48;
				}
			}
			break;
		}
		case BITRATE_7:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 224;
						break;
					case LAYERII:
						bitrate = 112;
						break;
					case LAYERIII:
						bitrate = 96;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 112;
				}
				else
				{
					bitrate = 56;
				}
			}
			break;
		}
		case BITRATE_8:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 256;
						break;
					case LAYERII:
						bitrate = 128;
						break;
					case LAYERIII:
						bitrate = 112;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 128;
				}
				else
				{
					bitrate = 64;
				}
			}
			break;
		}
		case BITRATE_9:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 288;
						break;
					case LAYERII:
						bitrate = 160;
						break;
					case LAYERIII:
						bitrate = 128;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 144;
				}
				else
				{
					bitrate = 80;
				}
			}
			break;
		}
		case BITRATE_10:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 320;
						break;
					case LAYERII:
						bitrate = 192;
						break;
					case LAYERIII:
						bitrate = 160;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 160;
				}
				else
				{
					bitrate = 96;
				}
			}
			break;
		}
		case BITRATE_11:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 352;
						break;
					case LAYERII:
						bitrate = 224;
						break;
					case LAYERIII:
						bitrate = 192;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 176;
				}
				else
				{
					bitrate = 112;
				}
			}
			break;
		}
		case BITRATE_12:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 384;
						break;
					case LAYERII:
						bitrate = 256;
						break;
					case LAYERIII:
						bitrate = 224;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 192;
				}
				else
				{
					bitrate = 128;
				}
			}
			break;
		}
		case BITRATE_13:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 416;
						break;
					case LAYERII:
						bitrate = 320;
						break;
					case LAYERIII:
						bitrate = 256;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 224;
				}
				else
				{
					bitrate = 144;
				}
			}
			break;
		}
		case BITRATE_14:
		{
			if(header->version == MPEG1)
			{
				switch(header->layer)
				{
					case LAYERI:
						bitrate = 448;
						break;
					case LAYERII:
						bitrate = 384;
						break;
					case LAYERIII:
						bitrate = 320;
						break;
				}

			}
			else
			{
				if(header->layer == LAYERI)
				{
					bitrate = 256;
				}
				else
				{
					bitrate = 160;
				}
			}
			break;
		}
		case BITRATE_NONE:
			printf("Reserved\r\n");
			break;
		default:
			printf("Frame Header error\r\n");
			break;
	}
	printf("bitrate = %d kbit/s\r\n",bitrate);

	switch(header->samplerate)
	{
		case SAMPLERATE_0:
		{
			switch(header->version)
			{
				case MPEG1:
					samplerate = 44100;
					break;
				case MPEG2:
					samplerate = 22050;
					break;
				case MPEG2_5:
					samplerate = 11025;
					break;
			}
			break;
		}
		case SAMPLERATE_1:
		{
			switch(header->version)
			{
				case MPEG1:
					samplerate = 48000;
					break;
				case MPEG2:
					samplerate = 24000;
					break;
				case MPEG2_5:
					samplerate = 12000;
					break;
			}
			break;
		}
		case SAMPLERATE_2:
		{
			switch(header->version)
			{
				case MPEG1:
					samplerate = 32000;
					break;
				case MPEG2:
					samplerate = 16000;
					break;
				case MPEG2_5:
					samplerate = 8000;
					break;
			}
			break;
		}
		case SAMPLERATE_NONE:
			printf("Reserved\r\n");
			break;
		default:
			printf("Frame Header error\r\n");
			break;
	}
	printf("samplerate = %d Hz\r\n",samplerate);

	if(header->padding==1)
	{
		printf("each Frame data padding a slot\r\n");
	}
	else
	{
		printf("each Frame data not padding\r\n");
	}

	if(header->private == 1)
	{
		printf("private is 1\r\n");
	}
	else
	{
		printf("private is 0\r\n");
	}

	switch(header->channel)
	{
		case CHANNEL_0:
			printf("channel is stereo\r\n");
			break;
		case CHANNEL_1:
			printf("channel is mixed stereo\r\n");
			break;
		case CHANNEL_2:
			printf("channel is double channels\r\n");
			break;
		case CHANNEL_3:
			printf("channel is signel channels\r\n");
			break;
	}


}
  • 简单测试:(读MP3文件,解析MP3格式):
    void Test(void)
    {
    #if 1
    	UINT8 data[4];
    	MPEG_Head_t mp3file_head;
    	MPEG_Head_t mp3first_head;
    	const TCHAR* Mp3filePath = "0:1.mp3";
    	FIL mp3fil;
    	FRESULT nRet;  /* API result code */
    	UINT32 Readstartindex = 0;
    	UINT32 FreamCount = 0;
    	UINT32 FileLen = 0;
    	memset((UINT8*)&mp3first_head,0,sizeof(MPEG_Head_t));
    	nRet = f_open(&mp3fil,Mp3filePath,FA_READ|FA_OPEN_EXISTING);
    	if(nRet!=FR_OK)
    	{
    		printf("f_open error res = %d\r\n",nRet);
    		return;
    	}
    	FileLen = f_size(&mp3fil);
    	printf("MP3 File len = %d\r\n",FileLen);
    	while(1)
    	{
    		//nRet = f_read(&mp3fil,(UINT8*)&mp3file_head,sizeof(mp3file_head),&fnum);
    		nRet = f_read(&mp3fil,(UINT8*)data,sizeof(mp3file_head),&fnum);
    		memcpy((UINT8*)&mp3file_head,data,sizeof(mp3file_head));
    		if(nRet!=FR_OK)
    		{
    			printf("f_open error res = %d\r\n",nRet);
    			return;
    		}
    		vMH_SwitchHeader(&mp3file_head);
    		if(mp3file_head.sync == 0x7ff)
    		{
    			if(mp3first_head.sync == 0x0)
    			{
    				memcpy((UINT8*)&mp3first_head,(UINT8*)&mp3file_head,sizeof(MPEG_Head_t));
    			}
    			if(memcmp((UINT8*)&mp3first_head,(UINT8*)&mp3file_head,sizeof(MPEG_Head_t))==0)
    			{
    				printf("index = %d\r\n",Readstartindex);
    				printf("%02x %02x %02x %02x\r\n",data[0],data[1],data[2],data[3]);
    				if(FreamCount == 0)
    				{
    					gFreameStartIndex = Readstartindex;
    				}
    				if(FreamCount<10)
    				{
    					printf("Readstartindex = %d\r\n",Readstartindex);
    					vMH_GetMp3HeaderInfo(&mp3file_head);
    				}
    				FreamCount++;
    				if(FreamCount%400 == 0)
    				{
    					vMH_GetMp3HeaderInfo(&mp3file_head);
    				}
    			}
    		}
    		Readstartindex+=1;
    		if(Readstartindex+4>FileLen)
    		{
    			printf("文件结尾\r\n");
    			printf("FreamCount = %d\r\n",FreamCount);
    			f_close(&mp3fil);
    			return;
    		}
    		nRet = f_lseek(&mp3fil,Readstartindex);
    		if(nRet != RT_OK)
    		{
    			printf("uFF_WriteWaveFileData : f_lseek error res = %d\r\n",nRet);
    			f_close(&mp3fil);
    			return RT_FAIL;
    		}
    
    	}
    #endif
    
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值