赞
踩
MPEG-1 or MPEG-2 Audio Layer III是一种音频压缩技术,其全称是动态影像专家压缩标准音频层面3(Moving Picture Experts Group Audio Layer III),简称为MP3,是目前最流行的音频编码格式。
MP3文件是由帧(frame)构成的,帧是MP3文件最小的组成单位。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文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。根据MPEG规范的说法,MPEG-4中的AAC(Advanced audio coding)将是MP3格式的下一代。
在众多音频压缩方法中,这些方法在保持声音质量的同时尽量压缩数字音频使之占用更小的存储空间。MPEG压缩是该领域中效果最好的一个。这种压缩是有损压缩,这意味着,当运用这一方法压缩时肯定会丢失一部分音频信息。但是,由于压缩方法的控制很难发现这种损失。使用几个非常复杂和苛刻的数学算法,使得只有原始音频中几乎听不到的部分损失掉。这就给重要的信息剩下了更多的空间。通过这种方法可以将音频压缩12倍(可以选择压缩率),效果显著。正是应为他的质量,MPEG音频变得流行起来。
MPEG-1,MPEG-2和MPEG-4都是人们熟悉的MPEG标准,MP3只涉及到前两中,另外还有一个非官方标准MPEG-2.5用于扩展MPEG-2/LSF到更低的采样率。
MPEG-1音频(ISO/IEC 11172-3)描述了具有如下属性的三层音频编码:
每一层都有自己的优点。
MPEG-2音频(ISO/IEC 13818-3)有两个MPEG-1的扩展,通常叫做MPEG-2/LSF和MPEG-2/Multichannel。
MPEG-2/LSF有如下特点:
MPEG-2/Mutichannel有如下特点:
音乐CD具有44.1KHz 16Bits立体声的音频质量,一张CD可以存储74分钟的歌曲(大约15首左右)。如何将这些歌曲无损或基本无损地进行压缩,以使在同样的媒体上存储更多的歌曲,一直困扰着软件业。当MPEG协会提出MPEG Audio Layer1~Layer3后,机会产生了。通过使用MPEG1 Layer3编码技术,制作者得以用大约12∶1的压缩率记录16KHz带宽的有损音乐信号。不过,同CD原声区别不大。人的听力系统具有非常优越的性能,其动态范围超过96dB。你既可以听到扣子掉在地上这样小的声音,也可以听到波音747的强大的轰鸣声。但当我们站在飞机场听着波音747的轰鸣时,你还能分辨出扣子掉在地上的声音吗?不可能。人的听力系统适应声音的动态变化,人们对这种适应及屏蔽特性音质研究后得出对声音压缩非常有用的理论。人们很早以前就知道利用这种特性来为磁带录音降低噪音了(当没有音乐时嘶嘶声很容易听到,而当音乐信号电平很高时嘶嘶声不容易听到)。当声音较强时产生屏蔽效应。在阈值曲线下的噪音或小信号声音无法被人耳听到。在较强信号出现时,允许通过更多的信号。在此时增加被量化过的小信号数据(使用无用的位来携带更多的信息)可以达到一定程度的压缩的目的。通常情况下,MP3压缩器将原始声音通过FFT(快速傅立叶变换)变化到频域,然后通过一定的算法算出何种频率声音可以携带更多的信息。而在还原时解码器所需要做的仅仅是将其从频域再变换回来。
MP3文件大体分为三部分:TAG_V2(ID3V2),音频数据,TAG_V1(ID3V1)
表格 1-1
section | description |
---|---|
ID3V2 | 在文件开始的位置,包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量 |
Frame . . . Frame |
一系列的帧,在文件的中间位置,个数由文件大小和帧长决定; 每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定; 每个FRAME又分为帧头和数据实体两部分; 帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立。 |
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-1
蓝色部分即为ID3V2.3的头部:前4个字节就是ID30x03(第3版)
第5个字节:副版本号,为0
注:文中关于mp3文件数据截图均为“紫藤花.mp3”文件中的数据截图。
(1)标志字节
标志字节一般为0,定义如下:
abc00000
a – 表示是否使用Unsynchronisation(一般不设置)
b – 表示是否有扩展头部,一般没有(至少Winamp 没有记录),所以一般也不设置
c – 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
上图蓝色部分第6个字节:存放标志的字节,只定义了三位,这里值为0。
(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)
上图蓝色部分第7到10字节:表示ID3标签的大小,这里为
total_size =(0x00&0x7F)*0x200000 + (0x00&0x7F)*0x4000 + (0x10&0x7F)*0x80 + (0x72 &0x7F) = 0x872 = 2162
(二)标签帧
每个标签帧都由一个10个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头及其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中得到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char ID[4]; /用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表/
char Size[4]; /帧内容的大小,不包括帧头,不得小于1/
char Flags[2]; /存放标志,只定义了6位,稍后详细解说/
图 1-2
蓝色部分是一个歌曲标题的标签帧
(1)帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:
TIT2 = 标题 //表示内容为这首歌的标题,下同
TPE1=作者
TALB=专集
TRCK=音轨 //格式:N/M其中N 为专集中的第N首,M为专集中共M首,N和M为ASCII码表示的数字
TYER=年代 //是用ASCII 码表示的数字
TCON=类型 //直接用字符串表示
COMM=备注 //格式:“eng\0备注内容”,其中eng表示备注所使用的自然语言
注:前4个字节为帧标识,这里是54 49 54 32(TIT2)是标题的标签帧。
表1-2 标签帧的标识以及其意义对照表
index | content | index | content |
---|---|---|---|
AENC | [Audio encryption] | TKEY | [Initial key] |
APIC | [Attached picture] | TLAN | [Language(s)] |
COMM | [Comments] | TLEN | [Length] |
COMR | [Commercial frame] | TMED | [Media type] |
ENCR | [Encryption method registration] | TOAL | [Original album/movie/show title] |
EQUA | [Equalization] | TOFN | [Original filename] |
ETCO | [Event timing codes] | TOLY | [Original lyricist(s)/text writer(s)] |
GEOB | [General encapsulated object] | TOPE | [Original artist(s)/performer(s)] |
GRID | [Group identification registration] | TORY | [Original release year] |
IPLS | [Involved people list] | TOWN | [File owner/licensee] |
LINK | [Linked information] | TPE1 | [Lead performer(s)/Soloist(s)] |
MCDI | [Music CD identifier] | TPE2 | [Band/orchestra/accompaniment] |
MLLT | [MPEG location lookup table] | TPE3 | [Conductor/performer refinement] |
OWNE | [Ownership frame] | TPE4 | [Interpreted, remixed, or otherwise modified by] |
PRIV | [Private frame] | TPOS | [Part of a set] |
PCNT | [Play counter] | TPUB | [Publisher] |
POPM | [Popularimeter] | TRCK | [Track number/Position in set] |
POSS | [Position synchronisation frame] | TRDA | [Recording dates] |
RBUF | [Recommended buffer size] | TRSN | [Internet radio station name] |
RVAD | [Relative volume adjustment] | TRSO | [Internet radio station owner] |
RVRB | [Reverb] | TSIZ | [Size] |
SYL | [Synchronized lyric/text] | TSRC | [ISRC (international standard recording code)] |
SYTC | [Synchronized tempo codes] | TSSE | [Software/Hardware and settings used for] |
TALB | [Album/Movie/Show title] | TYER | [Year] |
TBPM | [BPM (beats per minute)] | TXXX | [User defined text information frame] |
TCOM | [Composer] | UFID | [Unique file identifier] |
TCON | [Content type] | USER | [Terms of use] |
TCOP | [Copyright message] | USLT | [Unsychronized lyric/text transcription] |
TDAT | [Date] | WCOM | [Commercial information] |
TDLY | [Playlist delay] | WCOP | [Copyright/Legal information] |
TENC | [Encoded by] | WOAF | [Official audio file webpage] |
TEXT | [Lyricist/Text writer] | WOAR | [Official artist/performer webpage] |
TFLT | [File type] | WOAS | [Official audio source webpage] |
TIME | [Time] | WORS | [Official internet radio station homepage] |
TIT1 | [Content group description] | WPAY | [Payment] |
TIT2 | [Title/songname/content description] | WPUB | [Publishers official webpage] |
TIT3 | [Subtitle/Description refinement] | WXXX | [User defined URL link frame] |
(2)大小
这个可没有标签头的算法那么麻烦,每个字节的8 位全用,格式如下:
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x100000000 + Size[1]*0x10000+ Size[2]*0x100 + Size[3];
第5到8字节为标签帧的大小,这里为
FSize = 0x00*0x100000000+ 0x00*0x10000 + 0x00*0x100 + 0x24 = 0x24 = 36
注意:这里的帧大小,并不包含帧头的10个字节,只表示帧内容的大小。
(3)标志
只定义了6位,另外的10位为0,但大部分的情况下16位都为0就可以了。格式如下:abc00000ijk00000
值得一提的是winamp在保存和读取帧内容的时候会在内容前面加个’‘\0’',并把这个字节计算在帧内容的大小中。
第9到10字节为标签帧的标记,如上所述,这里为00。
帧内容是歌曲标题,标题的36个字节的内容为:紫藤花☆ゞ忍音.地带[renyin.12u.cn]。
每个帧都有一个帧头Header,长度是4Byte(32bit),帧头后面可能有两个字节的CRC 校验值,这两个字节的校验值是否存在决定于Header信息的第16bit,为1则帧头后面无校验,为0则有校验,校验值长度为2个字节,紧跟在Header后面的就是帧的实体数据,也就是压缩的声音数据,当解码器读到此处时就进行解码了。格式如下:
(1)帧头格式
帧头长4字节,对于固定位率的MP3文件,所有帧的帧头(即CBR帧头)格式一样,其数据结构如下(注:此结构要自己定义):
typedef struct 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; //强调模式 }FHEADER, *LPHEADER;
表1-3 MP3帧头字节使用说明
名字 | 位长 | 说明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
同步信息 | 11 | 第1、2字节 | 所有位均为1,第1字节恒为FF。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
版本 | 2 | 00-MPEG2.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。
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
采样率 | 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-双声道Dual channel 11-单声道Single channel | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
扩充模式 | 2 | 当声道模式为01是才使用。
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
版权 | 1 | 文件是否合法,0-不合法 1-合法 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
原版标志 | 1 | 是否原版,0-非原版 1-原版 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
强调方式 | 2 | 用于声音经降噪压缩后再补偿的分类,很少用到,今后也可能不会用。 00-未定义 01-50/15ms 10-保留 11-CCITT J.17 |
注意:关于读取帧头也可以使用下面的方法
定义一个结构体:
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;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。