一、 帧

帧头长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 字节)

前面的四个字节为“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秒)

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文件。在下一篇博文(四)怎样区分是否是固定位率文件和这个有关。

三、Mp3帧分析(数据帧)的更多相关文章

  1. 二、Mp3帧分析(标签帧)

    Mp3文件由帧组成,帧分成标签帧和数据帧,本文就Mp3文件的帧进行分析. 一.标签帧 MP3帧头中除了存储一些象private.copyright.original的简单音乐说明信息以外,没有考虑存放 ...

  2. 计算机是如何计算的、运行时栈帧分析(神奇i++续)

    关于i++的疑问 通过JVM javap -c 查看字节码执行步骤了解了i++之后,衍生了一个问题: int num1=50; num1++*2执行的是imul(将栈顶两int类型数相乘,结果入栈), ...

  3. mysql优化(三)–explain分析sql语句执行效率

    mysql优化(三)–explain分析sql语句执行效率 mushu 发布于 11个月前 (06-04) 分类:Mysql 阅读(651) 评论(0) Explain命令在解决数据库性能上是第一推荐 ...

  4. OO前三次作业分析

    一,第一次作业分析 度量分析: 第一次的oo作业按照常理来说是不应该有这么多的圈复杂度,但是由于第一次写的时候,完全不了解java的相关知识,按照c语言的方式来写,完全的根据指导书的逻辑,先写好了正确 ...

  5. 实验三:跟踪分析Linux内核的启动过程

    实验三:跟踪分析Linux内核的启动过程 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.16 ...

  6. LwIP协议栈开发嵌入式网络的三种方法分析

    LwIP协议栈开发嵌入式网络的三种方法分析   摘要  轻量级的TCP/IP协议栈LwIP,提供了三种应用程序设计方法,且很容易被移植到多任务的操作系统中.本文结合μC/OS-II这一实时操作系统,以 ...

  7. 开始 python programming第三版案例分析

    最近研究python,打算将python programming第三版案例分析下 但是全书1600多页 比较费时 而且 介绍太多 感觉没有必要! python programming 堪称经典之作 第 ...

  8. Wireshark抓包介绍和TCP三次握手分析

    wireshark介绍 wireshark的官方下载网站: http://www.wireshark.org/ wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示 ...

  9. C函数调用过程原理及函数栈帧分析(转)

    在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么 ...

随机推荐

  1. 根据list<Object>中的某个字段排序

    compareTo必须是两个对象之间的比较(比如Long,Integer...),以下例子是升序排序 private void businessSort(List<WxDailyBusiness ...

  2. linux 系统监控系列之vmstat

    vmstat的官方定义是:vmstat - Report virtual memory statistics,即虚拟内存的统计. 先来追根溯源: 什么是虚拟内存? 答:虚拟内存就是磁盘上虚拟出来可以当 ...

  3. 同一DataTable下创建多个结构数据相同的DataView的小问题

    昨天在根据经理的要求修改公司后台的时候,遇到了一个很奇怪的问题 DataView dvFocus = ]); DataView dvLook = ]); DataView dvNewUser = ]) ...

  4. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的解决方案

    今天写了一个excel表的导入功能,结果在excel表中的内容导入到页面时报错:SQL  Server 阻止了对组件 'Ad Hoc Distributed Queries' 的  STATEMENT ...

  5. Android SDK代理服务器解决国内不能更新下载问题(转)

    言:Android SDK代理服务器解决国内Android SDK不能更新下载问题,经常会遇到Fitch fail URL错误,要不就是Nothing was installed.目下Google遭受 ...

  6. php的一些特殊用法

    php ruturn的另一个用法 database.php <?php return array ( 'hostname' => 'localhost', 'database' => ...

  7. Emit技术使用实例及应用思路

    System.Reflection.Emit提供了动态创建类并生成程序集的功能. 适用于.NET Framework 2.0及其以后的版本. 动态生成类在对于O/R Mapping来说有很大的作用,在 ...

  8. MVC自我学起之MVCMusic开发中遇到问题:musicstore edit方法出错的原因和解决方法

    错误提示: 存储区更新.插入或删除语句影响到了意外的行数(0).实体在加载后可能被修改或删除.刷新 ObjectStateManager 项. 解决案: 1.在view中或model中增加隐藏id 1 ...

  9. Oracle自治事务

    定        义: Autonomous transactions are independent transactions that can be called from within anot ...

  10. 关于取数组地址的识记(&s+1,s+1,&s[0]+1)

    #include <stdio.h> #include <malloc.h> int main() { ', 'o'}; ); printf(]); ]+); printf(] ...