mp3文件解析代码

头文件:

#ifndef _MP3_H_
#define _MP3_H_

#include "stdint.h"

enum {
	BITRATE_MPEG1,
	BITRATE_MPEG2,
	BITRATE_NUM
};


enum {
	SAMPLERATE_MPEG1,
	SAMPLERATE_MPEG2,
	SAMPLERATE_MPEG25,
	SAMPLERATE_NUM
};

#define MP3_FRAME_SYNC			0xFFE00000

#define MASK_VERSION			0x00180000
#define SHIFT_VERSION			19

#define MPEG_1				3
#define MPEG_2				2
#define MPEG_25				0

#define SHIFT_LAYER			17
#define LAYER_3				1
#define LAYER_2				2
#define LAYER_1				3

#define PROTECTION_BIT			0x00010000

#define MASK_BITRATE			0x0000f000
#define SHIFT_BITRATE		 	12


#define MASK_SAMPLERATE			0x00000C00
#define SHIFT_SAMPLERATE 		10

#define MASK_PADDING			0x00000200

#define MASK_CHANNEL                0x000000C0
#define CHANNEL_STEREO       		0x00000000
#define CHANNEL_JOINT   	        0x00000040
#define CHANNEL_DUAL	            0x00000080
#define CHANNEL_MONO	            0x000000C0

struct mp3_frame {
	uint32_t version;
	uint32_t channel;
	int bitrate;
	int samplingRate;
	int samples;
	int size;
	const unsigned char *data;
};

// 解析一帧mp3数据
int getNextFrame(FILE * mp3fp, struct mp3_frame * frame);


#endif // _MP3_H_

源文件:

#include "mp3.h"


// bit率   128K bit/s  
static int bitrateTbl[16][BITRATE_NUM] =
{
	{ -1,  -1},
	{ 32,   8},
	{ 40,  16},
	{ 48,  24},
	{ 56,  32},
	{ 64,  40},
	{ 80,  48},
	{ 96,  56},
	{112,  64},
	{128,  80},
	{160,  96},
	{192, 112},
	{224, 128},
	{256, 144},
	{320, 160},
	{ -1,  -1}
};

// 采样率
static int samplingRateTbl[3][SAMPLERATE_NUM] =
{
	{ 44100, 22050, 11025 },
	{ 48000, 24000, 12000 },
	{ 32000, 16000,  8000 }
};

// 检查帧头信息
int checkHdr(uint32_t hdr)
{
	if( (hdr & MP3_FRAME_SYNC) != MP3_FRAME_SYNC
		|| ((hdr>>SHIFT_VERSION) & 0x3) == 1
		|| ((hdr>>SHIFT_LAYER) & 0x3) == 0
		|| ((hdr>>SHIFT_BITRATE) & 0xf) == 0xf 
		|| ((hdr>>SHIFT_BITRATE) & 0xf) == 0
		|| ((hdr>>SHIFT_SAMPLERATE)&0x3) == 0x3
		|| (hdr & 0xffff0000) == 0xfffe0000)
		return 0;
	return 1;
}

#define READ_ERROR(ret) if((ret) < 0) return (ret);

int READ_CHAR(FILE * fp, uint32_t * v)
{
	char buf[1];

	if(fread(buf, 1, 1, fp) <= 0)
		return -1;

	*v = 0xff & buf[0];
	return 0;
}

int READ_UINT16(FILE * fp, uint32_t * v)
{
	uint32_t tmp;
	int ret;

	ret = READ_CHAR(fp, &tmp);
	READ_ERROR(ret);
	*v = (tmp << 8);

	ret = READ_CHAR(fp, &tmp);
	READ_ERROR(ret);
	*v |= (tmp);

	return 0;
}

int READ_UINT24(FILE * fp, uint32_t * v)
{
	uint32_t tmp;
	int ret;

	ret = READ_UINT16(fp, &tmp);
	READ_ERROR(ret);
	*v = (tmp << 8);
	
	ret = READ_CHAR(fp, &tmp);
	READ_ERROR(ret);
	*v |= (tmp);

	return 0;
}

int READ_UINT32(FILE * fp, uint32_t * v)
{
	uint32_t tmp;
	int ret;

	ret = READ_UINT24(fp, &tmp);
	READ_ERROR(ret);
	*v = (tmp << 8);
	
	ret = READ_CHAR(fp, &tmp);
	READ_ERROR(ret);
	*v |= (tmp);

	return 0;
}									

// 解析mp3帧
int getNextFrame(FILE * mp3fp, struct mp3_frame * frame)
{
	uint32_t hdr, br_idx, sr_idx;	
	int ret;
	int factor;	
	
	do
	{
		ret = READ_UINT32(mp3fp, &hdr);
		//ret = fread(&hdr, 4, 1, mp3fp);
		if (ret < 0)
			return -1;
		if (checkHdr(hdr))
			break;
		
		fseek(mp3fp, -3, 1);
	}while (1);
	
	frame->version = (hdr >> SHIFT_VERSION) & 0x3;
	br_idx = (hdr >> SHIFT_BITRATE) & 0xf;
	sr_idx = (hdr >> SHIFT_SAMPLERATE) & 0x3;

	switch(frame->version)
	{
	case MPEG_25:
		frame->bitrate = bitrateTbl[br_idx][BITRATE_MPEG2];
		frame->samplingRate = 
			samplingRateTbl[sr_idx][SAMPLERATE_MPEG25];
		factor = 72;
		break;
	case MPEG_2:
		frame->bitrate = bitrateTbl[br_idx][BITRATE_MPEG2];
		frame->samplingRate = 
			samplingRateTbl[sr_idx][SAMPLERATE_MPEG2];
		factor = 72;
		break;
	case MPEG_1:
		frame->bitrate = bitrateTbl[br_idx][BITRATE_MPEG1];
		frame->samplingRate = 
			samplingRateTbl[sr_idx][SAMPLERATE_MPEG1];
		factor = 144;
		break;
	default:
		printf("invalid header %x\n", hdr);
		return -1;
	}

	frame->size = (factor * frame->bitrate * 1000) / frame->samplingRate;	
	if(frame->size == 0)
	{
		printf("size == 0\n");
		return -1;
	}

	if((hdr & MASK_PADDING) != 0)
		frame->size++;

	if(frame->samplingRate > 32000)
		frame->samples = 1152;
	else
		frame->samples = 576;

	frame->channel = hdr & MASK_CHANNEL;

	fseek(mp3fp, -4, 1);

	return 0;
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值