大家好,欢迎来到IT知识分享网。
mp3 编码
在MPEG文件中,没有主标头,因为MPEG的音频文件是由一系列被称为帧的较小部分组成的。每个帧都是一个具有自己标头和音频信息的数据块。
Layer II,II,III的音频帧头都是相同的,不同之处体现在音频数据的编码方式。帧本身是由slot组成的。Layer I的slot大小是4字节,其余情况是1字节。
除了Layer之外,MPEG音频本身也有3个版本,这个几个版本的不同之处体现在能处理的采样率不同(参考 表2.1.2)。MPEG 1 (ISO/IEC 13818-3) 和MPEG2(ISO/IEC 11172-3)是ISO标准. MPEG2.5对MPEG2进行的非官方的扩展,它是为了支持更低的采样率。MPEG2/2.5 也常被简称为LSF(Low SamplingFrequencies),既低采样率
对于Layer I和Layer II,帧是完全彼此独立的,因此您可以剪切MEPG音频文件的任何部分并正确的播放。然后,播放器将从发现的第一个完整有效的帧开始播放。但是,Layer III,帧不总是独立的,因为它可能使用了byte resevoir,这是一种内部缓冲区,因此帧之间通常是相互依赖的。在最坏的情况下,可能至少需要输入9个帧才能解码单个帧。
如果你需要检索有关MPEG的音频文件的信息,那么可以简单的找到第一帧,然后从它的header中获取信息。除比特率外,其他帧中的信息应该与第一个帧是一致的,因为可能当前是VBR的文件。在VBR的文件中,可以在每个帧中更改比特率。例如,为了在整个文件中保持音乐的高质量,当音乐比较复杂时就需要更多的位来做编码
帧头本身的长度是32位的(4字节)。帧头的前十二位(在MPEG2.5扩展的情况下为前十一位)始终设置为1,称为帧同步。帧还可能有可选的CRC校验和。它长16位,如果存在,则紧跟在帧头之后。CRC之后就是音频数据。通过重新计算CRC并将值与文件中的值进行比较,就可以检查比特流在传输期间是否已经被更改。
一个文件可以被编码成恒定比特率(CBR)或可变比特率(VBR),这意味着每帧可以有不同的比特率。可变比特率的质量往往比恒定比特率编码的文件更高,因为他们可以在需要的地方使用更高的比特率。
MP3文件的整体结构:
- [ID3 V2] | [APE 头]: 可选
- ID3 V2的头,大多数最新的MP3,都有这个头
- 用于APE格式的头,现在也用于MPEG
- 第一帧
- MPEG 音频头, 通常大小为4字节.(当Protection bit==0时,帧头后会有16bit=2byte的CRC,此时帧头大小为6字节)
- 边信息,9/17/32 字节
- [Xing 头]: 可选 8-120字节,如果是VBR,多数都有此Xing头,而且只有第一帧有
- 音频数据
- 第二帧
- 帧头
- 边信息
- 音频数据
- 第三帧
- 帧头
- 边信息
- 音频数据
- 最后一帧
- 帧头
- 边信息
- 音频数据
- [TAG]: 可选。128字节的ID3 V1信息,如果没有前面的ID3 V2,多数都有这个ID3 V1的头
mp3帧头编码
起始位置0位高位开始
起始位置 |
大小 |
位置 |
描述 |
0 |
11 |
31-21 |
帧同步标识,11个‘1’。用于定位帧头起始位置 |
11 |
2 |
20-19 |
MPEG音频版本 |
13 |
2 |
18-17 |
Layer序列号 |
15 |
1 |
16 |
Protection bit |
16 |
4 |
15,12 |
比特率 |
20 |
2 |
11-10 |
采样率 |
22 |
1 |
9 |
Padding bit的定义 |
23 |
1 |
8 |
保护位 |
24 |
2 |
7-6 |
channel模式 |
26 |
2 |
5-4 |
只用于Joint stereo 模式扩展 |
28 |
1 |
3 |
版权位 0:无版权 1:有版权 |
29 |
1 |
2 |
原始位 0:原始媒体的副本 1:原始媒体 |
30 |
2 |
1-0 |
Emphasis |
MPEG音频版本
设置值 |
描述 |
00 |
MPEG version2.5 |
01 |
保留 |
10 |
MPEG version2 |
11 |
MPEG version1 |
Layer序列号
设置值 |
描述 |
00 |
保留 |
01 |
Layer III |
10 |
Layer II |
11 |
Layer I |
Protection-bit
设置值 |
描述 |
0 |
protected by 16 bit CRC following header |
1 |
no CRC |
比特率
bits |
V1,L1 |
V1,L2 |
V1,L3 |
V2,L1 |
V2, L2 & L3 |
0000 |
free |
free |
free |
free |
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 |
bad |
bad |
bad |
bad |
NOTES: All values are in kbps
- V1: MPEG Version 1
- V2: MPEG Version 2 and Version 2.5
- L1: Layer I
- L2: Layer II
- L3: Layer III
- “free”:: free fromat. free bitrate必须保持恒定,并且必须小于允许的最大的比特率. 解码器不需要支持free bitrate的流
- “bad”: 意思是这个值是不被允许的.
MPEG文件可能具有可变的比特率(VBR)。每一个帧可以用不同的比特率来创建。这是可以在所有的layer中使用。Layer III必须这个方式,Layer I 和 Layer II 解码器可以选择支持 针对Layer II,不允许使用比特率和模式的一些组合。下面是一些允许的组合
bitrate |
单通道 |
立体声 |
intensity stereo |
dual channe |
free |
yes |
yes |
yes |
yes |
32 |
yes |
no |
no |
no |
48 |
yes |
no |
no |
no |
56 |
yes |
no |
no |
no |
64 |
yes |
yes |
yes |
yes |
80 |
yes |
no |
no |
no |
96 |
yes |
yes |
yes |
yes |
112 |
yes |
yes |
yes |
yes |
128 |
yes |
yes |
yes |
yes |
160 |
yes |
yes |
yes |
yes |
192 |
yes |
yes |
yes |
yes |
224 |
no |
yes |
yes |
yes |
256 |
no |
yes |
yes |
yes |
320 |
no |
yes |
yes |
yes |
384 |
no |
yes |
yes |
yes |
采样率
抽样速率指定每秒钟有多少个样本被记录。每个MPEG版本可以处理不同的samplingrates。
采样率索引 |
MPEG-1 (Hz) |
MPEG-2 (Hz) |
MPEG-2.5 (Hz) |
00 |
44100 |
22050 |
11025 |
01 |
48000 |
24000 |
12000 |
10 |
32000 |
16000 |
8000 |
11 |
reserved |
reserved |
reserved |
Padding-bit
如果设置了,则用一个slot填充数据(slot对框架大小的计算很重要) Layer I的slot大小是4字节,其余情况是1字节。
设置值 |
描述 |
0 |
没有填充 |
1 |
使用一个额外的slot填充数据 |
channel模式
设置值 |
描述 |
00 |
立体声 |
01 |
Joint stereo |
10 |
Dual channel(2 mono channels) |
11 |
Single channel(mono) |
注意:双通道文件由两个独立的单声道组成。每一个都只使用了文件的一半比特率。大多数解码器将其输出为立体声,但情况并非总是如此。使用一个例子是在相同的比特流中承载了两个不同语言的语音,那么解码器需要仅解码所选择的语言进行播放
模式扩展
扩展模式被用来增加了一些没有在立体声效果使用的信息,从而减少了所需的位。这些位由在Joint stereo模式下的编码器动态的确定,每一个帧的Joint stereo都可以改变,甚至可以打开或者关闭
MPEG文件的整个的频率范围分为了多个子带,共有32个子带。对于Layer I和Layer II来说两个位确定了当应用intensity stereo时的频率范围(频带)。针对Layer III,这两个位决定了使用哪一种类型的joint stereo(intensity stereo或者m/s stereo). 频率范围由解压缩算法来确定
设置值 |
Layer I & II |
00 |
bands 4 to 31 |
01 |
bands 8 to 31 |
10 |
bands 12 to 31 |
11 |
bands 16 to 31 |
Layer III:
Intensity stereo |
MS stereo |
off |
off |
on |
off |
off |
on |
on |
on |
Emphasis
设置值 |
描述 |
00 |
none |
01 |
50/15 ms |
10 |
reserved |
11 |
CCIT J.17 |
MP3边信息
边信息紧接着帧头。它包含了一些解码器会用到的一些信息,用于解码器控制音频流的播放,但不包含实际的音频数据。下表显示了所有Layer III文件的边信息的大小
模式 |
MPEG 1 |
MPEG 2/2.5 (LSF) |
立体声,联合立体声,双通道 |
32 |
17 |
Mono |
17 |
9 |
对于Layer I的文件,你必须考虑到扩展模式(见表2.1.6)。然后你可以以下公式计算出用于计算CRC的比特位的数量:
4 * ( 声道数 * bound of intensity stereo + (32 – bound of intensity stereo) );
这可以被读成两倍的立体声子带加上单子带的数量和结果乘以4。对于简单的mono帧,这等于128,因为通道的数目是1,而强度立体声的边界是32,这意味着没有强度立体声。对于立体帧,这是256。有关更多信息,请查看类CMPAFrame中的rc代码。
MP3解析的解析
基于MPG123库
核心数据结构
typedef struct mpstr_tag { struct buf *head, *tail; /* buffer linked list pointers, tail points to oldest buffer */ int vbr_header; /* 1 if valid Xing vbr header detected */ int num_frames; /* set if vbr header present */ int enc_delay; /* set if vbr header present */ int enc_padding; /* set if vbr header present */ /* header_parsed, side_parsed and data_parsed must be all set 1 before the full frame has been parsed */ int header_parsed; /* 1 = header of current frame has been parsed */ int side_parsed; /* 1 = header of sideinfo of current frame has been parsed */ int data_parsed; int free_format; /* 1 = free format frame */ int old_free_format; /* 1 = last frame was free format */ int bsize; int framesize; int ssize; /* number of bytes used for side information, including 2 bytes for CRC-16 if present */ int dsize; int fsizeold; /* size of previous frame, -1 for first */ int fsizeold_nopadding; struct frame fr; /* holds the parameters decoded from the header */ struct III_sideinfo sideinfo; unsigned char bsspace[2][MAXFRAMESIZE + 1024]; /* bit stream space used ???? */ /* MAXFRAMESIZE */ real hybrid_block[2][2][SBLIMIT * SSLIMIT]; int hybrid_blc[2]; unsigned long header; int bsnum; real synth_buffs[2][2][0x110]; int synth_bo; int sync_bitstream; /* 1 = bitstream is yet to be synchronized */ int bitindex; unsigned char *wordpointer; plotting_data *pinfo; lame_report_function report_msg; lame_report_function report_dbg; lame_report_function report_err; } MPSTR, *PMPSTR;
数据结构关键字段说明:
- struct buf *head, *tail
- 这是一个字符串双向链表
- head 是外部请求输入的buffer
- tail 是获取的之前的buffer,解析的时候从tail开始。解析后会更新pos位置
- wordpointer是指向bsspace的指针
- decodeMP3_clipchoice中每次计算出头的大小,side info的大小,data的大小,都会复制到这个指针的内存里面,使用copy_mp来复制,复制的源是tail中的数据
- 消费者在commong.c中的一系列的getbits函数,这些函数会更新bitindex以及wordpointer的指向getbitsgetbits_fastget_leq_8_bitsget_leq_16_bits
- bsspace是位流的空间
decodeMP3_clipchoice是核心的入口函数
关键的流程解析:
- addbuf
- 将输入的需要解码的数据,插入到head的buffer中
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/46909.html