MP3解码流程(一)-----音频文件结构解析

  • 本文多处摘自互联网,仅供本人学习使用,出处标示于文章尾端。

#一、概述
    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 文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。

#二、MP3 文件结构
    MP3 文件大体分为三部分:TAG_V2(ID3V2)音频数据TAG_V1(ID3V1)

    a). ID3V2 在文件开始的位置,包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1 的信息量。

    b). 一系列的音频数据的帧,在文件的中间位置,个数由文件大小和帧长决定;
每个帧的长度可能不固定,也可能固定,由位率bitrate决定
每个帧又分为帧头和数据实体两部分
帧头记录了mp3 的位率,采样率,版本等信息,每个帧之间相互独立 。

    c). ID3V1在文件结尾的位置,包含了作者,作曲,专辑等信息,长度为128Byte。

##2.1、ID3V2
    ID3V2 到现在一共有4 个版本,但流行的播放软件一般只支持第3 版, 既ID3v2.3。

    由于ID3V1 记录在MP3 文件的末尾,ID3V2就只好记录在MP3 文件的首部了(如果有一天发布ID3V3,真不知道该记录在哪里)。也正是由于这个原因,对ID3V2 的操作比ID3V1 要慢。而且ID3V2 结构比ID3V1 的结构要复杂得多,但比前者全面且可以伸缩和扩展。

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

###2.1.1、标签头
    在文件的首部顺序记录10 个字节的ID3V2.3 的头部。数据结构如下:

typedef struct Zs_head_lable
{
    char Header[3]; // 必须为字符串"ID3",否则认为标签不存在 对应16进制:49 44 33
    char ver;   // 版本号ID3V2.3 就记录0x03
    char Revision;// 副版本号此版本记录为0x00
    char Flag;  // 存放标志的字节,这个版本只定义了3bit
    char Size[4];   // 标签帧的大小,不包括标签头的10个字节
}head_lable;

图2.1.1
这里写图片描述
红色框部分即为ID3V2.3的头部:

前3个字节就是 ID30x03(第3版) 49 44 33

第4个表示版本号 03

第5个字节:副版本号,为00

第6个字节是标志字节 为00
标志字节一般为0,按位定义如下:
abc00000
a – 表示是否使用Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)
b – 表示是否有扩展头部,一般没有(至少Winamp 没有记录),所以一般也不设置
c – 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)

第7-10个字节表示标签帧大小
一共四个字节,但每个字节只用7位,最高位不使用恒为0。所以格式如下
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

计算大小时要将0 去掉,得到一个28 位的二进制数,就是标签大小,计算公式如下:

int label_frame_size;
label_frame_size=((Size[0]&0x7F)<<21)
                        + ((Size[1]&0x7F)<<14))
                        + ((Size[2]&0x7F)<<7)
                        + (Size[3]&0x7F);

第7到10字节:表示ID3标签的大小,这里为

label_frame_size=((0x00&0x7F)<<21)+((0x00&0x7F)<<14)+((0x07&0x7F)<<7) +(0x76 &0x7F)
= 0x3F6=1014;

这里的 0x3F6帧大小,并不包含标签头的10个字节,只表示标签帧内容的大小 加上标签头是10个字节,音频数据就是从1024后面的字节开始算。

###2.1.2、标签帧
    接上面的例子,接下里4086个字节都是标签帧的内容。
每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。

帧头的定义如下:

typedef struct Zs_lable_frame_head
{
	char ID[4]; //用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表
	char Size[4]; //帧内容的大小,不包括帧头,不得小于1
	char Flags[2]; //存放标志,只定义了6 位
}lable_frame_head,*plable_frame_head;

图2.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 59 45 52 (TYER) 是年代

####2)大小
这个可没有标签头的算法那么麻烦,每个字节的8 位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:

int FrameSize;
FrameSize= (Size[0]<<24) 
			+(Size[1]<<16)
			+ (Size[2]<<8)
			+ Size[3];

这里为

FrameSize =(0x00<<24) +( 0x00<<16) + (0x00<<8) + 0x05 = 5;

注意:这里的帧大小,并不包含帧头的10个字节,只表示帧内容的大小

####3)标志
只定义了6 位,另外的10 位为0,但大部分的情况下16 位都为0 就可以了。格式如下:
abc00000ijk00000

a – 标签保护标志,设置时认为此帧作废

b – 文件保护标志,设置时认为此帧作废

c – 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)

i – 压缩标志,设置时一个字节存放两个BCD 码表示数字

j – 加密标志(没有见过哪个MP3 文件的标签用了加密)

k – 组标志,设置时说明此帧和其他的某帧是一组

值得一提的是winamp 在保存和读取帧内容的时候会在内容前面加个”\0”,并把这个字节计算在帧内容的大小中。
第9到10字节为标签帧的标记,如上所述,这里为00

第一个帧内容是歌曲年代,标题的5个字节的内容为:
0x00 0x32 0x30 0x31 0x35
‘\0’ ‘2’ ‘0’ ‘1’ ‘5’
上图中的内容依次读出为:
TYER:2015
TALB:Purpose
COMM:eng
TIT2:LoveYourself
TPE1:JustinBieber

##2.2、音频数据帧

一个MP3数据帧分为5个部分:帧头、CRC校验值、通道信息、主数据、附加数据。

###2.2.1、MP3帧头字节说明
每个帧都有一个帧头Header,长度是4Byte(32bit),帧头后面可能有两个字节的CRC 校验值,这两个字节的是否存在决定于Header 信息的第16bit,为0 则帧头后面无校验,为1 则有校验,校验值长度为2 个字节,紧跟在Header 后面,接着就是帧的实体数据了.
图2.2.1
这里写图片描述


红色部分的4个字节即是帧头

**表2.1.1 MP3帧头字节说明**表
名称 位长
说明
同步信息 11 所有位均为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 单位是kbps,例如采用MPEG-1 Layer 3,128kbps是,值为1001
具体参数对应比特率表
采样率 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 表示声道, 00-立体声Stereo 01-Joint Stereo 10-双声道 11-单声道
扩充模式 2 当声道
  • 13
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值