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://www.506064.com/zh-tw/n/216529.html