MP3文件格式的解析一

这篇文章呢,是一片关于MP3解码的文章,整理了一些网上的资料,删除了一些模糊不清的东西。
现阶段主要的解码工作是ID3格式的。
从文件的第一个字节开始分析。
一、标签头
在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:
 char Header[3];     /*必须为"ID3"否则认为标签不存在*/
 char Ver;     /*版本号 ID3V2.3 就记录 3*/
 char Revision;     /*副版本号此版本记录为 0*/
 char Flag;     /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
 char Size[4];     /*标签大小,包括标签头的 10 个字节和所有的标签帧的大小*/
 标志字节(Flag)
 标志字节一般为 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)*0x400
   +(Size[2]&0x7F)*0x80

   +(Size[3]&0x7F)


这边你可以计算出0x01*0x80+0x13 大小是147字节 也就是0x93 前面呦10个字节是不算进去的 所以说 做种得到的大小就是
0x93+0xa=0x9d
 
可以看到 在0x9d的位置就是数据帧的头部
二、标签帧
每个标签帧都有一个 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]*0x100000000
 +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',并把这个字节计算在帧内容的
大小中。
标签帧主要是存储一些信息的,MP3名,专辑名等
三、数据帧
数据帧方面主要讲CBR。目前我正在研究的格式就是CBR的
1 MP3 帧头字节使用说明
名称
位长
          
同步信息 11 12字节 所有位均为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-调整,具体调整计算方法见下文。
保留字 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



看上图数据帧开始的地方FF FB 从这边开始解析,就可以得到全部的信息了,这边主要讲一下如何数据帧长度的计算:
MP3帧长取决于位率和频率,计算公式为:
 
. mpeg1.0       layer1 :   帧长= (48000*bitrate)/sampling_freq + padding
               layer2&3: 帧长= (144000*bitrate)/sampling_freq + padding
. mpeg2.0       layer1 :   帧长= (24000*bitrate)/sampling_freq + padding
layer2&3 : 帧长= (72000*bitrate)/sampling_freq + padding
例如:位率为64kbps,采样频率为44.1kHz,padding(帧长调节)为1时,帧长为210字节。
帧头后面是可变长度的附加信息,对于标准的MP3文件来说,其长度是32字节,紧接其后的是压缩的声音数据,当解码器读到此处时就进行解码了。
其中padding就是表中的帧长调节,就是1或者0两个值。一般算下来的结果都是有小数,直接取整数部分即可得到帧长。
目前这些就是我研究到的东西了,写了一篇博客记录,方便以后查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值