您的位置:首页 > 其它

MP3文件格式的解析一

2016-09-14 14:54 330 查看
这篇文章呢,是一片关于MP3解码的文章,整理了一些网上的资料,删除了一些模糊不清的东西。

现阶段主要的解码工作是ID3格式的。

从文件的第一个字节开始分析。

一、标签头

在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:

 char Header[3];     /*必须为"ID3"否则认为标签不存在*/

 char Ver;     /*版本号 ID3V2.3 就记录 3*/

 char Revision;     /*副版本号此版本记录为 0*/

 char Flag;     /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/

 char Size[4];     /*标签大小,包括标签头的 10 个字节和所有的标签帧的大小*/

 标志字节(Flag)

 标志字节一般为 0,定义如下:

 abc00000

 a -- 表示是否使用 Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)

 b -- 表示是否有扩展头部,一般没有(至少 Winamp 没有记录),所以一般也不设置

 c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)

 2).标签大小

 一共四个字节,但每个字节只用 7 位,最高位不使用恒为 0。所以格式如下

 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

 计算大小时要将 0 去掉,得到一个 28 位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如

下:

 

 int total_size;

 total_size =    (Size[0]&0x7F)*0x200000

   +(Size[1]&0x7F)*0x400

   +(Size[2]&0x7F)*0x80

   +(Size[3]&0x7F)

这边你可以计算出0x01*0x80+0x13 大小是147字节 也就是0x93 前面呦10个字节是不算进去的 所以说 做种得到的大小就是

0x93+0xa=0x9d


 

可以看到 在0x9d的位置就是数据帧的头部

二、标签帧

每个标签帧都有一个 10 个字节的帧头和至少一个字节的不固定长度的内容组成。                    它们也是顺序存放在文件

中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大

小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。

帧头的定义如下:

 char FrameID[4];   /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/

 char Size[4];    /*帧内容的大小,不包括帧头,不得小于 1*/

 char Flags[2];    /*存放标志,只定义了 6 位,稍后详细解说*/

 1).帧标识

 用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:

 TIT2=标题 表示内容为这首歌的标题,下同

 TPE1=作者

 TALB=专集

 TRCK=音轨 格式:N/M        其中 N 为专集中的第 N 首,M 为专集中共 M 首,N 和 M 为 ASCII 码表示的数字

 TYER=年代 是用 ASCII 码表示的数字

 TCON=类型 直接用字符串表示

 COMM=备注 格式:"eng/0 备注内容",其中 eng 表示备注所使用的自然语言

 2).大小

 这个可没有标签头的算法那么麻烦,每个字节的 8 位全用,格式如下

 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

 算法如下:

 int FSize;

 FSize = Size[0]*0x100000000

 +Size[1]*0x10000

 +Size[2]*0x100

 +Size[3];

 3).标志

 只定义了 6 位,另外的 10 位为 0,但大部分的情况下 16 位都为 0 就可以了。格式如下:

 abc00000 ijk00000

 a -- 标签保护标志,设置时认为此帧作废

 b -- 文件保护标志,设置时认为此帧作废

 c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)

 i -- 压缩标志,设置时一个字节存放两个 BCD 码表示数字

 j -- 加密标志(没有见过哪个 MP3 文件的标签用了加密)

 k -- 组标志,设置时说明此帧和其他的某帧是一组

 值得一提的是 winamp 在保存和读取帧内容的时候会在内容前面加个'/0',并把这个字节计算在帧内容的

大小中。

标签帧主要是存储一些信息的,MP3名,专辑名等

三、数据帧

数据帧方面主要讲CBR。目前我正在研究的格式就是CBR的

表1 MP3帧头字节使用说明
[align=center]名称[/align]
[align=center]位长[/align]
[align=center]说          明[/align]
同步信息11第1、2字节所有位均为1,第1字节恒为FF。
版本200-MPEG 2.5   01-未定义     10-MPEG 2     11-MPEG 1
200-未定义      01-Layer 3     10-Layer 2      11-Layer 1
CRC校验10-校验        1-不校验
位率4第3字节 取样率,单位是kbps,例如采用MPEG-1 Layer 3,64kbps是,值为0101。
bitsV
10207
1,L1
V1,L2V1,L3V2,L1V2,L2V2,L3
0000freefreefreefreefreefree
000132323232(32)32(8)8 (8)
001064484064(48)48(16)16 (16)
001196564896(56)56(24)24 (24)
01001286456128(64)64(32)32 (32)
01011608064160(80)80(40)64 (40)
01101929680192(96)96(48)80 (48)
011122411296224(112)112(56)56 (56)
1000256128112256(128)128(64)64 (64)
1001288160128288(144)160(80)128 (80)
1010320192160320(160)192(96)160 (96)
1011352224192352(176)224(112)112 (112)
1100384256224384(192)256(128)128 (128)
1101416320256416(224)320(144)256 (144)
1110448384320448(256)384(160)320 (160)
1111badbadbadbadbadbad
V1 - MPEG 1    V2 - MPEG 2 and MPEG 2.5

L1 - Layer 1     L2 - Layer 2     L3 - Layer 3

"free" 表示位率可变    "bad"  表示不允许值
采样频率2采样频率,对于MPEG-1:  00-44.1kHz    01-48kHz    10-32kHz      11-未定义
          对于MPEG-2:  00-22.05kHz   01-24kHz    10-16kHz      11-未定义
          对于MPEG-2.5: 00-11.025kHz 01-12kHz    10-8kHz       11-未定义
帧长调节1用来调整文件头长度,0-无需调整,1-调整,具体调整计算方法见下文。
保留字1没有使用。
声道模式2第4字节表示声道, 00-立体声Stereo    01-Joint Stereo    10-双声道       
11-单声道
扩充模式2当声道模式为01是才使用。
Value强度立体声MS立体声
00offoff
01onoff
10offon
11onon
版权1文件是否合法,0-不合法   1-合法
原版标志1是否原版,    0-非原版   1-原版
强调方式2用于声音经降噪压缩后再补偿的分类,很少用到,今后也可能不会用。
00-未定义     01-50/15ms     10-保留       11-CCITT J.17

看上图数据帧开始的地方FF FB 从这边开始解析,就可以得到全部的信息了,这边主要讲一下如何数据帧长度的计算:

MP3帧长取决于位率和频率,计算公式为:

 

. mpeg1.0       layer1 :   帧长= (48000*bitrate)/sampling_freq + padding

               layer2&3: 帧长= (144000*bitrate)/sampling_freq + padding

. mpeg2.0       layer1 :   帧长= (24000*bitrate)/sampling_freq + padding

layer2&3 : 帧长= (72000*bitrate)/sampling_freq + padding

例如:位率为64kbps,采样频率为44.1kHz,padding(帧长调节)为1时,帧长为210字节。

帧头后面是可变长度的附加信息,对于标准的MP3文件来说,其长度是32字节,紧接其后的是压缩的声音数据,当解码器读到此处时就进行解码了。

其中padding就是表中的帧长调节,就是1或者0两个值。一般算下来的结果都是有小数,直接取整数部分即可得到帧长。

目前这些就是我研究到的东西了,写了一篇博客记录,方便以后查询。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: