MP3格式音频文件结构解析

格式介绍具体介绍可参考:
mp3文件格式详解

MP3简介

MP3的全称是MPEG Audio Layer3,它是一种高效的计算机音频编码方案,它以较大的压缩比将音频文件转换成较小的扩展名为.MP3的文件,基本保持原文件的音质。MP3是ISO/MPEG标准的一部分,ISO/MPEG标准描述了使用高性能感知编码方案的音频压缩,此标准一直在不断更新以满足“质高量小”的追求,现已形成MPEGLayer1、Layer2、Layer3三个音频编码解码方案。MPEGLayer3压缩率可达1:10至1:12,1M的MP3文件可播放1分钟,而1分钟CD音质的WAV文件(44100Hz,16bit,双声道,60秒)要占用10M空间,这样算来,一张650M的MP3光盘播放时间应在10小时以上,而同样容量的一张CD盘播放时间在70分钟左右。MP3的优势是CD难以比拟的。

MPEG Audio 标准

MPEG(MovingPictureExpertsGroup)是ISO下的一个动态图 像专家组,它制定的MPEG标准广泛应用于各种多媒体中。 MPEG标准包括视频和音频标准,其中音频标准已制定出MPEG-1、MPEG-2、MPEG-2AAC和MPEG-4。

MPEG-1和MPEG-2标准使用同一个音频编码解码族—Layer1、2、3。MPEG-2一个新特点是采用低采样率扩展降低数据流量,另一特点是多通道扩展,将主声道增加为5个。MPEG-2AAC(MPEG-2AdvancedAudioCoding)标准是FraunhoferIIS 同AT&T公司于1997年推出的,旨在显著减少数据流量,MPEG22AAC采用的修正的离散余弦变换(MDCT,ModifiedDiscreteCo2sineTransform)算法,采样率可在8KHz到96KHz之间,声道数可在1-48之间。

MPEG Audio Layer1、2、3三个层使用相同的滤波器组、位流结构和头信息,采样频率为32KHz、4411KHz或48KHz。Layer1是为数字压缩磁带DCC(DigitalCompactCassette)设计的,数据流量为384kbps,Layer2在复杂性和性能间作了权衡,数据流量下降到256kbps-192kbps。Layer3一开始就为低数据流量而设计,数据流量在128kbps-112kbps,Layer3增加了MDCT变换,使其频率分辨能力是Layer2的18倍,Layer3还使用了与MPEGVid2eo类似的平均信息量编码(EntropyCoding),减少了冗余信息。MP3绝大部分使用的是MPEG21标准。

音频压缩

MP3格式始于80年代中期,德国Erlangen的Fraunhofer研究 所致力于高质量、低数据率的声音编码。

MP3音频压缩包含编码和解码两个部分。编码是将WAV文件中的数据转换成高压缩率的位流形式,解码是接受位流并将其重建到WAV文件中。

MP3采用了感知音频编码(PerceptualAudioCoding)这一失真算法。人耳感受声音的频率范围是20Hz-220kHz,MP3截掉了大量的冗余信号和无关的信号,编码器通过混合滤波器组将原始声音变换到频率域,利用心理声学模型,估算刚好能被察觉到的噪声水平,再经过量化,转换成Huffman编码,形成MP3位流。解码器要简单得多,它的任务是从编码后的谱线成分中,经过反 量化和逆变换,提取出声音信号。

在压缩音频数据时,先将原始声音数据分成固定的分块,然后作顺向MDCT变换,MDCT本身并不进行数据压缩,只是将一组时域数据转换成频域数据,以得知时域变化情况,顺向MDCT将每块的值转换为512个MDCT系数。量化使数据得到压缩,在对量化后的变换样值进行比特分配时要考虑使整个量化块最小,这就成为有损压缩了。解压时,经反向MDCT将512个系数还原成原始声音数据,前后的原始声音数据是不一致的,因为在压缩过程中,去掉了冗余和不相关数据。

MP3文件结构

MP3 文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)

ID3V2 :包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量
Frame:
一系列的帧,个数有文件大小和帧长决定
每个FRAM的长度可能不固定,也可能固定,由位率bitrate决定
每个FRAME由分为帧头和数据实体两部分
帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立
ID3V1:包含了作者,作曲,专辑等信息,长度为128BYTE

1. 帧头格式

下面是一个头内容图示,使用字符 A 到 M 表示不同的区域。在表格中你可以看到每一区域
的详细内容。
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于读取帧头我使用了下面的方法
定义一个结构体
typedef struct frameHeader
{
unsigned int sync1:8; //同步信息 1
unsigned int error_protection:1; //CRC 校验
unsigned int layer:2; //层
unsigned int version:2; //版本
unsigned int sync2:3; //同步信息 2
unsigned int extension:1; //版权
unsigned int padding:1; //填充空白字
unsigned int sample_rate_index:2; //采样率索引
unsigned int bit_rate_index:4; //位率索引
unsigned int emphasis:2; //强调方式
unsigned int original:1; //原始媒体
unsigned int copyright:1; //版权标志
unsigned int mode_extension:2; //扩展模式,仅用于联合立体声
unsigned int channel_mode:2; //声道模式
}FHEADER, *pFHEADER;请注意我的同步信息分成了两个部分,而且其他的位的顺序也和上表列出的有所差别,这个
主要是因为 c 语言在存取数据时总是从低位开始,而这个帧头是需要从高位来读取的。
读取方式如下
FHEADER header;
fread( &header, sizeof( FHEADER ), 1, streams );//这里假设文件已打开,读取位置已经指向帧
头所在的位置
这样一次就可以读入帧头的所有信息了。

2、如何计算帧长度

我们首先区分两个术语:帧大小和帧长度。帧大小即每帧采样数表示一帧中采样的个数,这是恒定值。其值入下表所示
在这里插入图片描述
帧长度是压缩时每一帧的长度,包括帧头。它将填充的空位也计算在内。LayerI 的一个空位长 4 字节,LayerII 和 LayerIII 的空位是 1 字节。当读取 MPEG 文件时必须计算该值以便找到相邻的帧。
注意:因为有填充和比特率变换,帧长度可能变化。
从头中读取比特率,采样频率和填充,
LyaerI 使用公式:
帧长度(字节) = (( 每帧采样数 / 8 * 比特率 ) / 采样频率 ) + 填充 * 4
LyerII 和 LyaerIII 使用公式:
帧长度(字节)= (( 每帧采样数 / 8 * 比特率 ) / 采样频率 ) + 填充
例:
LayerIII 比特率 128000,采样频率 44100,填充 0
=〉帧大小 417 字节

3、每帧的持续时间

之前看了一些文章都说 mp3 的一帧的持续时间是 26ms,结果在实际程序的编写中发现无法正确按时间定位到帧,然后又查了一些文章才知道,所谓 26ms 一帧只是针对 MPEG1 Layer III 而且采样率为 44.1KHz 来说是对的,但 mp3 文件并不都是如此,其实这个时间也是可以通过计算来获得,下面给出计算公式

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

这样通过计算可知 MPEG1 Layer III 采样率为 44.1KHz 的一帧持续时间为 26.12…不是整数,不过我们权且认为它就是 26 毫秒吧。
如果是 MPEG2 Layer III 采样率为 16KHz 的话那一帧要持续 36 毫秒,这个相差还是蛮大的,所以还是应该通过计算来获的,当然可以按 MPEG 版本,层数和采样率来建一个表,这样直接查表就可以知道时间了。

5、帧数据

在帧头后边是 Side Info(姑且称之为通道信息)。对标准的立体声 MP3 文件来说其长度为 32字节。通道信息后面是 Scale factor(增益因子)信息。当解码器在读到上述信息后,就可以进行解码了。当 MP3 文件被打开后,播放器首先试图对帧进行同步,然后分别读取通道信息及增益因子等数据,再进行霍夫曼解码,至此我们已经获得解压后的数据。但这些数据仍然不能进行播放,它们还处于频域,要想听到歌曲还要将它由频域通过特定的手段转换到时域。接下来的处理分别为立体化处理;抗锯齿处理;IMDCT 变换;IDCT 变换及窗口化滑动处理。

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

6、VBR 头

这里列出 VBR 的第一帧存储文件信息的头的格式。有两种格式,一种是常见的 XING Header
(头部包含字符‘Xing’)
,另一种是 VBRI Header (头部包含字符‘VBRI’)鉴于 VBRI Header
不 常 见 , 下 面 只 说 XING Header , 关 于 VBRI Header 请 看
http://www.codeproject.com/audio/MPEGAudioInfo.asp。
XING Header 的起始位置,相对于第一帧帧头的位置,单位是字节
36-39 “Xing”
21-24 “Xing”
21-24 “Xing”
13-16 “Xing”
文件为 MPEG1 并且不是单声道(大多数 VBR 的 mp3 文件都是如此)
文件为 MPEG1 并且是单声道
文件为 MPEG2 并且不是单声道
文件为 MPEG2 并且是单声道

XING Header 格式
在这里插入图片描述
在这里插入图片描述
这样算来,XING Header 包括帧头一共最多只需要 156 个字节就够了。当然也可以在 XING
Header 后面存储编码器的信息,比如 lame 在其后就是存储其版本,这需要给第一帧留足够
的空间才行。
至于 mp3 的信息用从 XING Header 读出的信息就可以计算
比如
总持续时间 = 总帧数 * 每帧采样数 / 采样率 (结果为秒)
平均位率 = 文件长度 / 总持续时间 * 8

MPEG 音频标签

MPEG 音频标签分为两种,一种是 ID3v1,存在文件尾部,长度 128 字节,另一种是 ID3v2,
是对 ID3v1 的扩展,存在文件头部,长度不定。

1、ID3v1

ID3v1 标签用来描述 MPEG 音频文件。包含艺术家,标题,唱片集,发布年代和流派。另
外还有额外的注释空间。位于音频文件的最后固定为 128 字节。可以读取该文件的最后这
128 字节获得标签。
结构如下
AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB
BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE
EFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFG
在这里插入图片描述
该规格要求所有的空间必须以空字符(ASCII 0)填充。但是并不是所有的应用程序遵循该规
则,比如 winamp 就用空格(ASCII 32)代替之。
在 ID3v1.1 结构中有些改变。注释部分的最后一个字节用来定义唱片集中的轨道号。如果不
知道该信息时可以用空字符(ASCII 0)代替。
流派使用原码表示,为下列数字之一:
在这里插入图片描述
Winamp 扩充了这个表
在这里插入图片描述
在这里插入图片描述

2、ID3V2

ID3V2 到现在一共有 4 个版本,但流行的播放软件一般只支持第 3 版,既 ID3v2.3。由于
ID3V1 记录在 MP3 文件的末尾,ID3V2 就只好记录在 MP3 文件的首部了(如果有一天发
布 ID3V3,真不知道该记录在哪里)。也正是由于这个原因,对 ID3V2 的操作比 ID3V1 要
慢。而且 ID3V2 结构比 ID3V1 的结构要复杂得多,但比前者全面且可以伸缩和扩展。
下面就介绍一下 ID3V2.3。
每个 ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标
签至少要有一个标签帧。标签头和标签帧一起顺序存放在 MP3 文件的首部。

(一)、标签头

在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:
char Header[3]; /必须为"ID3"否则认为标签不存在/
char Ver; /版本号 ID3V2.3 就记录 3/
char Revision; /副版本号此版本记录为 0/
char Flag; /存放标志的字节,这个版本只定义了三位,稍后详细解说/
char Size[4]; /标签大小,包括标签头的 10 个字节和所有的标签帧的大小/
注:对这里我有疑惑,因为在实际寻找首帧的过程中,我发现有的 mp3 文件的标签大小是不
包含标签头的,但有的又是包含的,可能是某些 mp3 编码器写标签的 BUG,所以为了兼容
只好认为其是包含的,如果按大小找不到,再向后搜索,直到找到首帧为止。

(1).标志字节

标志字节一般为 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)*0x4000
+(Size[2]&0x7F)*0x80
+(Size[3]&0x7F)

(二)、标签帧

每个标签帧都有一个 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]*0x1000000
+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’,并把这个字节计
算在帧内容的
大小中。
附:帧标识的含义

(4). Declared ID3v2 frames

The following frames are declared in this draft.AENC Audio encryption
APIC Attached picture
COMM Comments
COMR Commercial frame
ENCR Encryption method registration
EQUA Equalization
ETCO Event timing codes
GEOB General encapsulated object
GRID Group identification registration
IPLS Involved people list
LINK Linked information
MCDI Music CD identifier
MLLT MPEG location lookup table
OWNE Ownership frame
PRIV Private frame
PCNT Play counter
POPM Popularimeter
POSS Position synchronisation frame
RBUF Recommended buffer size
RVAD Relative volume adjustment
RVRB Reverb
SYLT Synchronized lyric/text
SYTC Synchronized tempo codes
TALB Album/Movie/Show title
TBPM BPM (beats per minute)
TCOM Composer
TCON Content type
TCOP Copyright message
TDAT Date
TDLY Playlist delay
TENC Encoded by
TEXT Lyricist/Text writer
TFLT File type
TIME Time
TIT1 Content group description
TIT2 Title/songname/content description
TIT3 Subtitle/Description refinement
TKEY Initial key
TLAN Language(s)
TLEN Length
TMED Media type
TOAL Original album/movie/show title
TOFN Original filename
TOLY Original lyricist(s)/text writer(s)TOPE Original artist(s)/performer(s)
TORY Original release year
TOWN File owner/licensee
TPE1 Lead performer(s)/Soloist(s)
TPE2 Band/orchestra/accompaniment
TPE3 Conductor/performer refinement
TPE4 Interpreted, remixed, or otherwise modified by
TPOS Part of a set
TPUB Publisher
TRCK Track number/Position in set
TRDA Recording dates
TRSN Internet radio station name
TRSO Internet radio station owner
TSIZ Size
TSRC ISRC (international standard recording code)
TSSE Software/Hardware and settings used for encoding
TYER Year
TXXX User defined text information frame
UFID Unique file identifier
USER Terms of use
USLT Unsychronized lyric/text transcription
WCOM Commercial information
WCOP Copyright/Legal information
WOAF Official audio file webpage
WOAR Official artist/performer webpage
WOAS Official audio source webpage
WORS Official internet radio station homepage
WPAY Payment
WPUB Publishers official webpage
WXXX User defined URL link frame

MP3 文件实例剖析

在 VC++中打开一个名为 test.mp3 文件,其内容如下:
000000 FF FB 52 8C 00 00 01 49 09 C5 05 24 60 00 2A C1
000010 19 40 A6 00 00 05 96 41 34 18 20 80 08 26 48 29
000020 83 04 00 01 61 41 40 50 10 04 00 C1 21 41 50 64

0000D0 FE FF FB 52 8C 11 80 01 EE 90 65 6E 08 20 02 30
0000E0 32 0C CD C0 04 00 46 16 41 89 B8 01 00 08 36 48
0000F033 B7 00 00 01 02 FF FF FF F4 E1 2F FF FF FF FF

0001A0 DF FF FF FB 52 8C 12 00 01 FE 90 58 6E 09 A0 02
0001B0 33 B0 CA 85 E1 50 01 45 F6 19 61 BC 26 80 28 7C
0001C0 05 AC B4 20 28 94 FF FF FF FF FF FF FF FF FF FF…
001390 7F FF FF FF FD 4E 00 54 41 47 54 45 53 54 00 00
0013A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0013F000 00 00 00 04 19 14 03 00 00 00 00 00 00 00 00
001400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
001410 00 00 00 00 00 00 4E
该文件长度 1416H(5.142K),帧头为:FF FB 52 8C,转换成二进制为:
11111111 11111011
01010010 10001100
在这里插入图片描述
第 1397H 开始的三个字节是 54 41 47,存放的是字符“TAG”,表示此文件有 ID3 V1.0 信息。
139AH 开始的 30 个字节存放歌名,前 4 个非 00 字节是 54 45 53 54,表示“TEST”;
13F4H 开始的 4 个字节是 04 19 14 03,存放年份“04/25/2003”;
最后 1 个字节是 4E,表示音乐类别,代号为 78,即“Rock&Roll”;
其它字节均为 00,未存储信息。

  • 2
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
解析MP3音频格式 一、概述 MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3 的全称应为MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即 Layer-1、Layer2、Layer3,且分别对应MP1、MP2、MP3 这三种声音文件,并根据不同的用途,使用不同层 次的编码。MPEG音频编码的层次越高,编码器越复杂,压缩率也越高,MP1 和MP2 的压缩率分别为4:1 和 6:1-8:1,而MP3 的压缩率则高达10:1-12:1,也就是说,一分钟CD 音质的音乐,未经压缩需要10MB的存储空间,而经过MP3 压缩编码后只有1MB 左右。不过MP3 对音频信号采用的是有损压缩方式,为了降低声音失真度,MP3 采取了“感官编码技术”,即编码时先对音频文件进行频谱分析,然后用过滤器滤掉噪音电平,接着通过量化的方式将剩下的每一位打散排列,最后形成具有较高压缩比的MP3 文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。 名词解释: 比特率是指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送的数据越大。 比特率比特率表示经过编码(压缩)后的音、视频数据每秒钟需要用多少个比特来表示,而比特就是二进制里面最小的单位,要么是0,要么是1。比特率与音、视频压缩的关系,简单的说就是比特率越高,音、视频的质量就越好,但编码后的文件就越大;如果比特率越少则情况刚好相反。 采样率(也称为采样速度或者采样频率)定义了每秒从连续信号中提取并组成离散信号的采样个数,单位用赫兹(Hz)来表示。采样频率的倒数是采样周期(也称为采样时间),它表示采样之间的时间间隔。这里要注意不要将采样率与位速相混淆。 二、MP3文件整体结构 MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1) ID3V2标签帧 ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。 音频数据帧 一系列的帧,个数由文件大小和帧长决定,每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定,每个FRAME又分为帧头和数据实体两部分,帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立 ID3V1标签帧 ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。 三、MP3结构具体分析 1.ID3V2标签 每个ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3 文件的首部。 标签头 在文件的首部顺序记录10 个字节的ID3V2.3 的头部。数据结构如下: char Header[3]; /*必须为"ID3"否则认为标签不存在*/ char Ver; /*版本号ID3V2.3 就记录3*/ char Revision; /*副版本号此版本记录为0*/ char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/ char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/ 注:最后4个字节表示ID3V2标签的大小,在实际寻找首帧的过程中,我发现大部分的mp3文件的标签大小是包含标签头的,但有的又是不包含的,可能是某些mp3编码器写标签的BUG,所以为了兼容只好认为其是包含的,如果按大小找不到,再向后搜索,直到找到首帧为止。 计算ID3V2标签帧的大小: 最后四个字节表示,但每个字节只用7 位,最高位不使用恒为0。所以格式如下: 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 计算大小时要将0 去掉,得到一个28 位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如 下: int ID3V2_Size; ID3V2_Size = (Size[0]&0x7F;)*0x200000 +(Size[1]&0x7F;)*0x4000 +(Size[2]&0x7F;)*0x80 +(Size[3]&0x7F;) (2) 标签帧 每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。 一般我们从标签头中获取信息计算出整个ID3V2标签的大小即可,对于ID3V2的标签帧就不再仔细分析。 2.音频数据 数据帧往往有多个,至于有多少,由文件大小和帧大小来决定。每个帧都有一个四字节长的帧头,接下来可能有两个字节的CRC校验,其存在由帧头中的具体信息决定。接着就是帧的实体数据,也就是MAIN_DATA了。 (1)音频数据帧的帧头 格式如下: AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM 符号 长度(bit) 位置(bit) 描述 A 11 (31~21) 帧同步(所有位置1) B 2 (20~19) MPEG 音频版本ID 00 – MPEG 2.5 01 – 保留 10 – MPEG 2 (ISO/IEC 13818-3) 11 – MPEG 1 (ISO/IEC 11172-3) C 2 (18~17) Layer描述 00 - 保留 01 - Layer III 10 - Layer II 11 - Layer I D 1 (16) 校验位(0 - 紧跟帧头后有16位即2个字节用作CRC校验1 - 没有校验) E 4 (15~12) 比特率(位率)(见比特率索引表) F 2 (11~10) 采样率(见采样率索引表) G 1 (9) 填充位(填充用来达到正确的比特率。) 0 – 没有填充 1 – 填充了一个额外的空位 H 1 (8) 私有bit,可以用来做特殊应用。例如可以用来触发应用程序的特殊事件。 I 2 (7~6) 声道 00 立体声 01 联合立体声(立体声) 10 双声道(立体声) 11 单声道(单声) J 2 (5~4) 扩展模式(仅在联合立体声时有效) 扩展模式用来连接对立体声效果无用的信息,来减少所需的资源。这两个位在联合立体声模式下有编码器动态指定。 K 1 (3) 版权 0无版权 1有版权 L 1 (2) 原创 0 原创拷贝 1 原创 M 2 (1) 强调 00 - 无 01 - 50/15 ms 10 - 保留 11 - CCIT J.17 【帧头信息表】 索引值 MPEG1 MPEG2&MPEG2;.5 Layer1 Layer2 Layer3 Layer1 Layer2&3 0000 Free 0001 32 32 32 32 8 0010 64 48 40 48 16 0011 96 56 48 56 24 0100 128 64 56 64 32 0101 160 80 64 80 40 0110 192 96 80 96 48 0111 224 112 96 112 56 1000 256 128 112 128 64 1001 288 160 128 144 80 1010 320 192 160 160 96 1011 352 224 192 176 112 1100 384 256 224 192 128 1101 416 320 256 224 144 1110 448 384 320 256 160 1111 Bad 【比特率索引表】 Bits MPEG1 MPEG2 MPEG3 00 44100 22050 11025 01 48000 24000 12000 10 32000 16000 8000 11 保留 【采样率索引表】 (2)如何计算音频数据帧长度 我们首先区分两个术语:帧大小和帧长度。帧大小即每帧采样数表示一帧中采样的个数,这是恒定值。其值入下表所示 MPEG1 MPEG2 MPEG2.5 Layer1 384 384 384 Layer2 1152 1152 1152 Layer3 1152 576 576 【每帧采【每帧采样数表】 帧长度是压缩时每一帧的长度,包括帧头。它将填充的空位也计算在内。LayerI的一个空位长4字节,LayerII和LayerIII的空位是1字节。当读取MPEG文件时必须计算该值以便找到相邻的帧。 注意:因为有填充和比特率变换,帧长度可能变化。 从头中读取比特率,采样频率和填充, LyaerI使用公式: 帧长度(字节) = 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 +填充 * 4 LyerII和LyaerIII使用公式: 帧长度(字节)= 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 + 填充 例: LayerIII 比特率 128000,采样频率 44100,填充0 =〉帧大小 417字节 (3)计算每帧的持续时间 之前看了一些文章都说mp3的一帧的持续时间是26ms,结果在实际程序的编写中发现无法正确按时间定位到帧,然后又查了一些文章才知道,所谓26ms一帧只是针对MPEG1 Layer III而且采样率为44.1KHz来说是对的,但mp3文件并不都是如此,其实这个时间也是可以通过计算来获得,下面给出计算公式 每帧持续时间(秒) = 每帧采样数 / 采样频率(HZ) 可以这么理解:每帧采用数就是要采取的总数,采样率就是采取的速度,相除 就得到时间。 这样通过计算可知 MPEG1 Layer III 采样率为44.1KHz的一帧持续时间为26.12...不是整数,不过我们权且认为它就是26毫秒吧。 如果是MPEG2 Layer III 采样率为16KHz的话那一帧要持续36毫秒,这个相差还是蛮大的,所以还是应该通过计算来获的,当然可以按MPEG版本,层数和采样率来建一个表,这样直接查表就可以知道时间了。 3.ID3V1标签 ID3v1标签用来描述MPEG音频文件。包含艺术家,标题,唱片集,发布年代和流派。另外还有额外的注释空间。位于音频文件的最后固定为128字节。可以读取该文件的最后这128字节获得标签。以最后128个字节的头三个字节为“TAG”作为有ID3V1的判断依据。 结构如下: AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE EFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFG 符号 长度(byte) 位置 描述 A 3 (0~2) 标签标志。如果存在标签并且正确的话,必须包含'TAG'。 B 30 (3~32) 标题 C 30 (33~62) 艺术家 D 30 (63~92) 唱片集 E 4 (93~96) 年代 F 30 (97~126) 注释 G 1 (127) 流派 有了上述的这些信息,我们就可以自己写代码,从MP3文件中抓取信息以及修改文件名了。但是,如果真的想写一个播放软件,还是需要读它的数据帧,并进行解码。 四、解析方法 当你想读取MPEG文件的信息时,解析前三个字节,判断是否有ID3V2标签,有则根据上面的方法算出ID3V2标签的总大小,这样就找到了音频数据帧的第一帧,读取它的头信息,获取比特率、采样率、MPEG版本号、Layer描述号等信息,根据上面提供的方法算出每帧的长度和每帧持续时间,对于定比特率的其它帧是相同的,也就是说解析第一帧就达到了目的。但这也不是所有情况。变比特率的MPEG文件使用使用所谓比特变换,也就是说每一帧的比特率依照具体内容变化。这时就需要你每一帧都解析
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值