【MP3】MP3格式分析

来源:互联网 发布:最好的股票操盘软件 编辑:程序博客网 时间:2024/05/16 18:57

一、概述

MP3 的全称应为 MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准MPEG音频文件是MPEG1标准中的声音部分,也叫MPEG音频层,它根据压缩质量和编码复杂程度划分为三层,即Layer-1Layer2Layer3,且分别对应MP1MP2MP3这三种声音文件,并根据不同的用途,使用不同层次的编码。

MPEG 音频编码的层次越高,编码器越复杂,压缩率也越高,MP1MP2 的压缩率分别为 4:1 6:1-8:1,MP3 的压缩率则高达10:1-12:1,也就是说,一分钟CD 音质的音乐,未经压缩需要10MB的存储空间,而经过MP3 压缩编码后只有1MB 左右。不过MP3 对音频信号采用的是有损压缩方式,为了降低声音失真度,MP3采取了感官编码技术”,即编码时先对音频文件进行频谱分析,然后用过滤器滤掉噪音电平,接着通过量化的方式将剩下的每一位打散排列,最后形成具有较高压缩比的MP3 文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。

MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位

 

二、MP3文件结构

MP3 文件大体分为三部分:TAG_V2(ID3V2),音频数据,TAG_V1(ID3V1)

ID3V2

文件开始:包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。

Frame

.

.

.

Frame

一系列的帧,个数由文件大小和帧长决定

每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定

每个FRAME又分为帧头和数据实体两部分

帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立。

ID3V1

文件结尾 :包含了作者,作曲,专辑等信息,长度为128BYTE

1、ID3v2

ID3V2 到现在一共有 4 个版本,但流行的播放软件一般只支持第3 ,ID3v2.3不一定存在,但是如果存在就是在文件的开始位置。我们可以把文件的指针移动到文件的头部,然后获取三个字节,判断是否为"ID3",就可以得出此MP3文件是否存在ID3V2的标签了.这个标签最重要的信息就是可以得到第一次出现FF EX XX XX的位置.然后我们从其第一帧获取MP3的相关具体信息

 

1.1  ID3V2的结构:

ID3V2的结构图如图7-8所示,其中深色标识的结构是可选的。在ID3V2中,比特顺序采用Big endian方式排列,也就是高字节存储在高位。ID3V2的结构相对于ID3V1复杂很多,这里重点介绍ID3V2头和ID3V2帧。

每个ID3V2.3的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3文件的首部。

 

1.1.1  ID3V2

ID3V2头(Header)的长度是固定的,共10个字节3个字节总是"ID3",可以通过检查这个文件标识来判断是否是ID3V2头。随后2个字节是ID3V2的版本,其中第4个字节代表ID3V2的主版本号,第5个字节代表ID3V2的修订版本号。目前ID3V22.32.4版本应用最广泛。随后的一个字节是标志位,目前此字节的前4位在使用,其他位为0,标志位的第2比特标识了ID3V2头后面是否有扩展头,标志位的第4位标志了ID3V2最后是否含有Footer。最后的4个字节标识了ID3V2的大小,其中包括10个字节的ID3V2头。由于每个字节的第1位永远是0,因此只有28个字节用来表示大小。

1.1.2  扩展头

扩展头(Extended Header)包含了更多的数据信息,这些数据是对ID3V2头的补充,但是并非解析MP3文件的关键数据。

1.1.3  ID3V2

每个ID3V2标签含有一个或者多个ID3V2帧,每个帧由ID3V2帧头和帧体构成(如上图)ID3V2帧头由4个字节的帧ID4个字节的大小标志和2个字节的标志位组成,共计10个字节。其中帧ID4个字符组成,字符可以是09AZ,例如TIT2TALB等。紧随其后是4个字节的尺寸标识,4个字节的每个比特都可以使用,共计32位用来表示帧的大小。需要注意的是,这个大小表示的是帧体的大小,不包括帧头的10个字节,因此整个尺寸应该是帧体的大小加上10个字节。标签帧并没有固定的顺序要求,TIT2可以出现在TALB前面,也可以出现在TALB的后面。

ID3V2的帧体由字节数组构成,其内容一般是与帧ID对应的。例如,TIT2帧体内存储了歌曲的标题,TALB帧体内存储了歌曲的专辑信息。帧体的第1个字节标识了字符的编码方式,目前有4种编码方式可用。

0000 0000代表字符使用ISO-8859-1编码方式;

0000 0001代表字符使用UTF-16编码方式;

0000 0002代表字符使用UTF-16BE编码方式;

0000 0003代表字符使用UTF-8编码方式。

在读取帧体内容时,应该按照上面的编码对应表首先确定编码方式,然后再生成相关的字符串。对于TIT2TALB等帧ID来说,读取其内容比较简单。对于USLT(对应歌曲的歌词信息)等结构较复杂的帧,需要仔细研究其格式才能将内容从帧体中读取出来。

1.1.4  填充

ID3V2帧后面可以存放填充(Padding)位,填充位的值只能是0。填充位使得ID3V2帧的大小比ID3V2计算得到的大小要小一些,也就是说,留下了一些空白的空间,这些空间可以用来增加一些额外的帧信息。由于增加的信息写在一些空白的空间内,因此无须重写整个文件,这也就是填充存在的重要意义。

1.1.5  ID3V2

ID3V2 尾(Footer)是可选的,有时候可能需要从MP3文件的尾部向前搜索ID3V2的位置,这时候ID3V2的存在就可以大大地加快搜索的速度。ID3V2尾和ID3V2头的内容是一致的,只是文件标识部分由"ID3"改成了"3DI"

2、音频数据帧

帧是由帧头,附加信息,声音数据三部分组成的.并且,帧头是重要的信息

下面列举帧头

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;

 

帧头长4字节,对于固定位率的MP3文件,所有帧的帧头格式一样

 

每个bit位所代表的意义可以参照下面的图标来得出

 

当我们得到第一个FF EX XX XX的时候,(验证ID3V2存在)我们就可以依照上面的表格来得到相关的信息了.

以下是变比特率的帧头的数据结构

 

 

 

1)计算帧长度

首先区分两个术语:帧大小和帧长度。帧大小即每帧采样数表示一帧中采样的个数,这是恒定值。其值如下表所示

 

MPEG 1

MPEG 2(LSF)

MPEG 2.5(LSF)

Layer 1

384

384

384

Layer 2

1152

1152

1152

Layer 3

1152

576

576

帧长度是压缩时每一帧的长度,包括帧头。它将填充的空位也计算在内。LayerI的一个空位长4字节,LayerIILayerIII的空位是1字节。当读取MPEG文件时必须计算该值以便找到相邻的帧。注意:因为有填充和比特率变换,帧长度可能变化。

LyaerI使用公式:

帧长度(字节) = ((每帧采样数/ 8 * 比特率 ) / 采样频率 ) + 填充 * 4

LyerIILyaerIII使用公式:

帧长度(字节)= ((每帧采样数/ 8 * 比特率 ) / 采样频率 ) + 填充

2)每帧持续时间

每帧的持续时间可以通过计算获得,下面给出计算公式

每帧持续时间(毫秒) =每帧采样数 /采样频率 * 1000

3)CRC校验

如果帧头的校验位为0,则帧头后就有一个16位的CRC值,这个值是big-endian的值,把这个值和该帧通过计算得出的CRC值进行比较就可以得知该帧是否有效。

4)帧数据

在帧头后边是Side Info(姑且称之为通道信息)。对标准的立体声MP3文件来说其长度为32字节。通道信息后面是Scale factor(增益因子)信息。当解码器在读到上述信息后,就可以进行解码了。

对于mp3来说现在有两种编码方式,一种是CBR,也就是固定位率,固定位率的帧的大小在整个文件中都是是固定的(公式如上所述),只要知道文件总长度,和从第一帧帧头读出的信息,就都可以通过计算得出这个mp3文件的信息,比如总的帧数,总的播放时间等等,要定位到某一帧或某个时间点也很方便,这种编码方式不需要文件头,第一帧开始就是音频数据。另一种是VBR,就是可变位率,VBRXING公司推出的算法,所以在MP3FRAME里会有“Xing"这个关键字(也有用"Info"来标识的,现在很多流行的小软件也可以进行VBR压缩,它们是否遵守这个约定,那就不得而知了),它存放在MP3文件中的第一个有效帧的数据区里,它标识了这个MP3文件是VBR的。同时第一个帧里存放了MP3文件的帧的总个数,这就很容易获得了播放总时间,同时还有100个字节存放了播放总时间的100个时间分段的帧索引,假设4分钟的MP3歌曲,240S,分成100段,每两个相邻INDEX的时间差就是2.4S,所以通过这个INDEX,只要前后处理少数的FRAME,就能快速找出我们需要快进的帧头。其实这第一帧就相当于文件头了。不过现在有些编码器在编码CBR文件时也像VBR那样将信息记入第一帧,比如著名的lame,它使用"Info"来做CBR的标记。

3、 ID3V1

D3V1标准并不周全,存放的信息少,无法存放歌词,无法录入专辑封面、图片等。ID3V2是一个相当完备的标准,但给编写软件带来困难,虽然赞成此格式的人很多,在软件中绝大多数MP3仍在使用ID3V1标准。ID3v1标签包含艺术家,标题,唱片集,发布年代和流派。另外还有额外的注释空间。位于音频文件的最后固定为128字节。可以读取该文件的最后这128字节获得标签。

 

 

3 ID3 V1.0文件尾说明

字节

长度 (字节)

       

1-3

3

存放“TAG”字符,表示ID3 V1.0标准,紧接其后的是歌曲信息。

4-33

30

歌名

34-63

30

作者

64-93

30

专辑名

94-97

4

年份

98-127

30

附注

128

1

MP3音乐类别,共147种。

ID3V1 的各项信息都是顺序存放,没有任何标识将其分开,比如标题信息不足30个字节,则使用''\0''填充,数据结构定义如下:

typedef struct tagID3V1

{

charHeader[3];         /*标签头必须是"TAG"否则认为没有标签*/

charTitle[30];          /*标题*/

charArtist[30];          /*作者*/

charAlbum[30];        /*专集*/

charYear[4];            /*出品年代*/

charComment[28];   /*备注*/

charreserve;             /*保留*/

chartrack;              /*音轨*/

charGenre;              /*类型*/

}ID3V1, *pID3V1;

0 0
原创粉丝点击