一、 帧

帧头长4字节,是的,是4个字节,共32位。 帧头后面可能有两个字节的CRC 校验,这两个字节的是否存在决定于FRAMEHEADER 信息的第16bit, 为0 则帧头后面无校验,为1 则有校验,校验值长度为2 个字节,(后面是可变长度的附加信息,对于标准的MP3文件来说,其长度是32字节,本段括号内的文字内容有待商榷,暂时没见到这样的文件),紧接其后的 是压缩的声音数据,当解码器读到此处时就进行解码了。

typedef FrameHeader {

unsigned int sync: 11;                         //同步信息

unsigned int version: 2;                       //版本

unsigned int layer: 2;                                     //层

unsigned int error protection: 1;                  // CRC校验

unsigned int bitrate_index: 4;             //位率

unsigned int sampling_frequency: 2;         //采样频率

unsigned int padding: 1;                     //帧长调节

unsigned int private: 1;                        //保留字

unsigned int mode: 2;                          //声道模式

unsigned int mode extension: 2;        //扩充模式

unsigned int copyright: 1;                            // 版权

unsigned int original: 1;                       //原版标志

unsigned int emphasis: 2;                   //强调模式

}HEADER, *LPHEADER;

1.1  帧头4字节使用说明见表1。

表1 MP3帧头字节使用说明

名称

位长

说          明

同步信息

11

第1、2字节

所有位均为1,第1字节恒为FF。

版本

2

00-MPEG 2.5   01-未定义     10-MPEG 2     11-MPEG 1

2

00-未定义      01-Layer 3     10-Layer 2      11-Layer 1

CRC校验

1

0-校验        1-不校验

位率

4

第3字节

取样率,单位是kbps,例如采用MPEG-1 Layer 3,64kbps是,值为0101。

bits

V1,L1

V1,L2

V1,L3

V2,L1

V2,L2

V2,L3

0000

free

free

free

free

free

free

0001

32

32

32

32(32)

32(8)

8 (8)

0010

64

48

40

64(48)

48(16)

16 (16)

0011

96

56

48

96(56)

56(24)

24 (24)

0100

128

64

56

128(64)

64(32)

32 (32)

0101

160

80

64

160(80)

80(40)

64 (40)

0110

192

96

80

192(96)

96(48)

80 (48)

0111

224

112

96

224(112)

112(56)

56 (56)

1000

256

128

112

256(128)

128(64)

64 (64)

1001

288

160

128

288(144)

160(80)

128 (80)

1010

320

192

160

320(160)

192(96)

160 (96)

1011

352

224

192

352(176)

224(112)

112 (112)

1100

384

256

224

384(192)

256(128)

128 (128)

1101

416

320

256

416(224)

320(144)

256 (144)

1110

448

384

320

448(256)

384(160)

320 (160)

1111

bad

bad

bad

bad

bad

bad

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-调整,具体调整计算方法见下文。padding

保留字

1

没有使用。

声道模式

2

第4字节

表示声道, 00-立体声Stereo    01-Joint Stereo    10-双声道        11-单声道

扩充模式

2

当声道模式为01是才使用。

Value

强度立体声

MS立体声

00

off

off

01

on

off

10

off

on

11

on

on

版权

1

文件是否合法,0-不合法   1-合法

原版标志

1

是否原版,    0-非原版   1-原版

强调方式

2

用于声音经降噪压缩后再补偿的分类,很少用到,今后也可能不会用。

00-未定义     01-50/15ms     10-保留       11-CCITT J.17

规律说明:根据上表的分析,所有的Mp3文件的数据帧开始的两个字节必需是“FF FA”或者 “FF FB”。

1.2 MP3帧长的计算

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

Size=((采样个数  * (1 / 采样率))* 帧的比特率)/8  + 帧的填充大小

对于Mp3格式,Size=((1152 * (1 / 采样率))* 帧的比特率)/8  + 帧的填充大小

=144*帧的比特率/采样率+帧的填充大小

a,帧的填充大小就是第23位的帧长调节,不是0就是1。

b,采样个数:MPEG的不同规范(MPEG-1/2/3),以及同一规范中不同的 Layer(Layer I/II/III),每一帧
所对应的采样数,都是固定的,其具体的值参见下表:表 4   MPEG帧的采样数索引表(单位:个/帧)

MPEG 1

MPEG 2 (LSF)

MPEG 2.5 (LSF)

Layer I

384

384

384

Layer II

1152

1152

1152

Layer III

1152

576

576

3.举例说明

本例是王菲的怀念(大小4,680,730 字节)

三、Mp3帧分析(数据帧)-LMLPHP

前面的四个字节为“FF FB B0 64”对应的二进制串为“11111111  11111011  10110000

01100100”,参照前面的分析,第16位为“1”,则无校验数据;第17至20位为“1011”,则比特率=192kbps;第21至22位为
“00”,则采样频率=44.1kHz;第23位为“0”,则帧长调整是0;所以帧长Size=144*192/44.1+0=626,前面除法需向下求
整(但有时又是四舍五入)。所以在地址0x272处又开始了新的帧,我这里是“FF
FB B0 44”。

二 VBR 标志帧

前面分析了帧的结构,Mp3文件分为CBR和VBR两种,这里着重分析一下VBR文件,VBR文件的第一个帧不是有效的数据帧,是它的标志帧。这种标志帧有Xing帧和VBRi帧。

2.1 Xing 帧

VBR 是XING 公司推出的算法,所以在MP3 的FRAME
里会有“XING"这个关键字(现在很多流行的小软件也可以进行VBR 压缩,它们是否遵守这个约定,那就不得而知了),它存放在MP3
文件中的第一个有效FRAME 里,它标识了这个MP3 文件是VBR 的。同时第一个FRAME 里存放了MP3 文件的FRAME
的总个数,这就很容易获得了播放总时间,同时还有100 个字节存放了播放总时间的100 个时间分段的FRAME 的INDEX,假设4 分钟的MP3
歌曲,240S, 分成100
段,每两个相邻INDEX 的时间差就是2.4S, 所以通过这个INDEX,只要前后处理少数的FRAME,就能快速找出我们需要快进的FRAME
头。

2.1.1 解析帧

表2 VBR Xing文件第一帧结构

字节

说    明

1-4

标准声音帧头(Mp3时,为“FF FA xx xx”或者“FF FB xx xx”)

5-40

存放VBR文件标识“Xing”(58 69 6E 67),此标识具体位置视采用的MPEG标准和声道模式而定。标识的前后字节没有使用。

37-40

MPEG-1和非单声道(常见)

注意:Mp3的就是这种情况,第5至36的数据存储的是前面提到过的32字节的边信息,无效边信息时是32字节的“00”

22-25

MPEG-1和单声道

22-25

MPEG-2和非单声道

14-17

MPEG-2和单声道

41-44

标志,说明是否存储了帧数、文件长度、目录表和VBR规模信息,如果存储了,则01 02 04 08。注意:如果四种信息都存储了则这4个字节为“00 00 00 0F”,即F的二进制是“1111”,相应地,如果存储了帧数、文件长度、目录表,则这4个字节为“00 00 00 0E”

45-48

帧数(包括第一帧)

49-52

文件长度

53-152

目录表,用来按时间进行字节定位。

153-156

VBR规模,用于位率变动音频质量指示,最差 0,最好 100,大端[可
选]

2.1.2 举例说明

曲子是:刘德华 - 虹桥机场的咖啡厅.mp3(5,898,130字节,时长3分14秒)

三、Mp3帧分析(数据帧)-LMLPHP

a,第37至40地址为“58 69 6E 67”,就是“Xing”标志了;

b,第41至44地址为“00 00 00 0F”,这里是Flag了,表示该帧存储了帧数、文件长度、目录表和VBR规模信息。

c,第45至48地址为“00 00 1D 11”,这里是文件的总帧数(包括第一帧),是big-endia的,(1*16^3+13*16^2+1*16+1)帧。

d,第49至52地址为“00 59 FD
DE”,这里是文件的总大小,也是Big-Endian的,
(5*16^5+9*16^4+15*16^3+13*16^2+13*16+14)=5,897,694(字节),
但是右键文件的属性发现却是5,898,130字节,这多出来的字节暂时还没弄明白(郁闷中)。

e,第53至152地址,就是一百个字节的目录表了(称作TOC表),如图蓝色地部分。

TOC (Table of Contents)

Contains of 100 indexes (one Byte length) for easier lookup in file. Approximately

solves problem with moving inside file.

Each Byte has a value according this formula:

(TOC[i] / 256) * fileLenInBytes

So if song lasts eg. 240 sec. and you want to jump to 60. sec. (and file is 5 000

000 Bytes length) you can use:

TOC[(60/240)*100] = TOC[25]

and corresponding Byte in file is then approximately at:

(TOC[25]/256) * 5000000

If you want to trim VBR file you should also reconstruct Frames, Bytes and TOC

properly.

TCO 索引的计算方式如下  文件长度 100 比如文件持续 240 秒,我需要跳到 60 秒,文件长度为 5000000 字节 计算如下TOC[(60/240)*100] =TOC[25]/256) * 5000000 如果要自己重建的话,基本是把这个步骤反过来做就可以了。要求准确的话,就需要根据时间点找到正确帧的位置然后再计算, 定位帧的做法都是从第一帧开始搜索。

f,第153至156字节地址为“00 00 00 64”,,音频质量指示质量指示器,为 0(最好)-100(最差)的 Big-Endian 值,没想到这个文件的音质是最差的100。

g,接下来是Lame版本的相关信息

2.2 VBRI帧(该种文件没有找到,此部分内容是完全摘抄的,供参考)

据了解,目前此头信息,只有用 Fraunhofer 的编码器生成的 MPEG音频文件,才会用到此
头。其和Xing 头不一样,其放在第一个MPEG头的后面,大小正好是 32字节。其位置,
长度和示例,都是以字节为单位。下表是 VBRi 头的具体格式及含义,单位为字节:

位置 (字节)

长度 (字节)

含义

示例

0

4

4个 ASCII字符的 VBR 头ID: “VBRI”无NULL结尾

“VBRI”

4

2

版本 ID,大端,类型:DWORD

1

6

2

延迟,类型:float

7344

8

2

音频质量指示

75

10

4

文件总大小,大端,类型:DWORD

45000

14

4

总的帧数,大端,类型:DWORD

7344

18

2

TOC 表的表项数目,大端,类型:WORD

100

20

2

TOC 表项的缩放因子,大端,类型:DWORD

1

22

2

单个 TOC 表项的大小,单位字节,最大为 4,大端,

类型:DWORD

2

24

2

帧数/表项,大端,类型:WORD

845

26

用于检索的 TOC 表,整型值,可以通过每个表项大小乘于表项个数得到此 TOC 表的总大小,大端

三 Info 帧

info帧,结构和Xing帧是相同的,从一些网上的资料显示:这种类型的帧有点怪,在CBR文件中的第一个数据帧可以是Info帧,在VBR文件中的第
一个数据帧也有可能是Info帧,但是我个人更倾向于认为第一个数据帧为Info帧的文件是CBR文件,比如Kugoo软件制作的铃声的第一帧都是
Info帧,而且是CBR文件。在下一篇博文(四)怎样区分是否是固定位率文件和这个有关。

04-30 03:59