关于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);
}
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;
}
}
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
}
因篇幅问题不能全部显示,请点此查看更多更全内容