MP3文件格式解析

轉自:http://blog.163.com/waft_xu/blog/static/438152942008139330707/


1, MP3簡介

MP3是今天一種常見的音樂格式,但恐怕除了工作要求之外,有興趣對此進行研究的人恐怕不多。所以,當我打算做MP3解碼方面的工作時,在找資料時也頗費了一番周折,同時也覺得很有趣。所以想在這裏分享一下自己的心得,做一個總結性的介紹。這樣有興趣的同志也可以對此有一個大概瞭解,儘快入門。

MP3
MPEG-1 Audio Layer 3的簡稱,是當今比較流行的一種數字音頻編碼和有損壓縮格式(有Layer 3,也必然有Layer1Layer2,也就是MP1MP2,但不在本文討論範圍之內)。MP3技術的應該可以用來大幅度的降低音頻文件存儲所需要的空間。它丟掉脈衝編碼調製(PCM)音頻數據中對人類聽覺不重要得數據,從而達到了較高的壓縮比(高達121101)。簡單地說,MP3在編碼時先對音頻文件進行頻譜分析,然後用過濾器濾掉噪音電平,接着通過量化的方式將剩下的每一位打散排列,最後形成有較高壓縮比的MP3文件,並使壓縮後的文件在回放時也能夠達到比較接近原音源的效果。

MP3
的音頻質量取決於它的BitrateSampling frequency,以及編碼器質量。MP3的典型速度介於每秒128320kb之間。採樣頻率也有44.14832 kHz三種頻率,比較常見的是採用CD採樣頻率——44.1kHz。常用的編碼器是LAME,它完全遵循LGPLMP3編碼器,有着良好的速度和音質。

2,      MP3文件格式

用一個二進制查看器(比如Ultra-Edit)打開一個MP3文件,就能看到一大堆看似雜亂無序的數據。但只要用心瞭解就會知道,其實,這一切都是有規律可循的。

MP3
文件是由幀(frame)構成,幀是MP3文件的最小組成單位。每幀都包含幀頭,並可以計算幀的長度。根據幀的性質不同,文件主要分爲三個部分,ID3v2標籤幀,數據幀和ID3v1標籤幀。並非每個MP3文件都有ID3v2,但是數據幀和ID3v1幀是必須的。ID3v2在文件頭,以字符串“ID3爲標誌,包含了演唱者,作曲,專輯等信息,長度不固定,擴展了ID3V1的信息量。ID3v1在文件結尾,以字符串“TAG”爲標記,其長度是固定的128個字節,包含了演唱者、歌名、專輯、年份等信息。

I, ID3V2

ID3V2到現在一共有四個版本,但流行的播放軟件一般只支持第三版,既ID3V2.3每個ID3V2.3 的標籤都一個標籤頭和若干個標籤幀或一個擴展標籤頭組成。關於曲目的信息如標題、作者等都存放在不同的標籤幀中,擴展標籤頭和標籤幀並不是必要的,但每個標籤至少要有一個標籤幀。標籤頭和標籤幀一起順序存放在MP3 文件的首部。

標籤頭

長度爲10個字節,位於文件首部,其數據結構如下:

char Header[3]; /* 字符串 "ID3" */

char Ver;       /* 版本號ID3V2.3 就記錄3 */

char Revision; /* 副版本號此版本記錄爲0 */

char Flag;     /* 存放標誌的字節,這個版本只定義了三位,很少用到,可以忽略 */

char Size[4]; /* 標籤大小,除了標籤頭的10 個字節的標籤幀的大小 */

標籤大小爲四個字節,但每個字節只用低7位,最高位不使用,恆爲0,其格式如下:
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

計算公式如下:

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


標籤幀

每個標籤幀都有一個10字節的幀頭和至少一個字節的不固定長度的內容組成。它們是順序存放在文件中,由各自特定的標籤頭來標記幀的開始。其幀的結構如下:

char FrameID[4];   /*用四個字符標識一個幀,說明其內容 */

char Size[4];      /* 幀內容的大小,不包括幀頭,不得小於1 */

char Flags[2];     /* 存放標誌,只定義了6 位,此處不再說明 */

常用幀標識:

TIT2:標題
TPE1
:作者
TALB
:專輯
TRCK
: 音軌,格式:N/MN表示專輯中第幾首,M爲專輯中歌曲總數
TYER
:年份
TCON
:類型
COMM
:備註,格式:“eng\0備註內容”,其中eng表示所使用的語言
幀大小爲四個字節所表示的整數大小。


II, ID3V1

其數據結構如下:

char Header[3];    /* 標籤頭必須是"TAG"否則認爲沒有標籤 */
char Title[30];    /*
標題 */
char Artist[30];   /*
作者 */
char Album[30];    /*
專集 */
char Year[4];      /*
出品年代 */
char Comment[28]; /*
備註 */
char reserve;      /*
保留 */
char track;;       /*
音軌 */
char Genre;        /*
類型 */

其實,關於最後31個字節還存在另外一個版本,就是30個字節的Comment和一個字節的Genre.

有了上述的這些信息,我們就可以自己寫代碼,從MP3文件中抓取信息以及修改文件名了。但是,如果真的想寫一個播放軟件,還是需要讀它的數據幀,並進行解碼。


III,
數據幀

數據幀往往有多個,至於有多少,由文件大小和幀大小來決定。每個幀都有一個四字節長的幀頭,接下來可能有兩個字節的CRC校驗,其存在由幀頭中的具體信息決定。接着就是幀的實體數據,也就是MAIN_DATA了。

A,幀頭結構如下:

位置     長度     描述
BIT  BITS
————————————————————————————
31
19   12       Frame sync(0xFFF)
18/17    2        Layer, 00 – reserved, 01 – Layer III
                         10 – Layer II, 11
Layer I
16       1         protection_bit, 0
意味着受CRC保護,幀頭後面跟16位的CRC
15-12    4        bitrate_index,
比特率
11-10    2        sampling_frequency,    00 – 44.1KHz, 01 – 48KHz
                                         10 – 32 KHz,  11 –
保留
9        1        padding_bit,1
意味着幀裏包含padding位,僅當採樣頻率爲44.1KHz時發生。
8        1        private_bit
7
6     2        mode,    00stereo,        01-joint stereo(intensity stereo and/or ms_stereo)
                           
11- dual_channel, 11 – single_channel
5-4      2        mode_extension,
Layer III中表示使用了哪一種joint stereo編碼方式。
                            Intensity_stereo   ms_stereo
                   00            off                off
                   01            on                 off
                   10            off                on
                   11            on                 on
3        1        copyright,1
表示受版權保護。
2        1        original
0表示該bitstream是一個copy1表示是original.
1-0      2        emphasis
,表示會使用哪一種de-emphasis
                   00
no emphasis,     01 – 50/15 microsec. Emphasis
                   
10 – reserved,        11 – CCITT J.17

1)      無論幀長是多少,每幀的播放時間都是26ms

2)      數據幀大小:

FrameSize = 144 * Bitrate / SamplingRate + PaddingBit
144 * Bitrate / SamplingRate不能被8整除,則加上相應的paddingBit.

B,MAIN_DATA:

MP3granule包含18 * 32subband採樣。每個數據幀含有兩個granule的數據,其內容結如下:
       - main_data_end pointer
       - side info for both granules (scfsi)
       - side info granule 1
       - side info granule 2
       - scalefactors and Huffman code data granule 1
       - scalefactors and Huffman code data granule 2

主要數據裏包含了scalefactors, Huffman encoded dataancillary information。其內容不再詳敘,可以參考MP3 SPECIS0 11172-3 AUDIO PART。我們一般用的都是立體聲,scfsi的長度爲32個字節。

這裏要解釋的一個概念就是位流――bitstream。我們平常接觸到的數據都是整數,最小的單位就是byte後者char。雖然我們也會用一個字節裏的不同位來表示不同的含義,但總的來說,我們在出來數據的時候還是把它當作一個個字節看待。但對MP3這種數據格式來說,這是行不通的。在解碼時,它的數據輸入就是一個個比特流。其中一個或幾個比特會是你的採樣數據或者信息編碼。你需要從整個MAIN_DATA裏提取你所需要的以BIT爲單位的參數和輸入信號,從而進行解碼。所以我們需要一個子程序,getbit(n),也就是從緩衝中提取所需要的位,並形成一個新的整數,作爲我們的輸出。

C,LAME標籤幀

可是,當你真的打開一個MP3文件的時候,你會發現,很奇怪,很多時候第一個數據幀的幀頭後面的32個字節居然都爲0,這是爲什麼呢,這麼奇怪的解碼信息該如何解釋?找到MP3 INFO TAG REV SPECIFICATION的網站,我才明白,原來第一幀並不是真正的數據幀,而是LAME編碼的標誌幀。

這裏又要牽涉到兩個概念:CBRVBRCBR表示比特率不變,也就是每幀的長度是一致的,它以字符串“INFO”爲標記。VBRVariable BitRate的簡稱,也就是每幀的比特率和幀的長度是變化的,它以字符串“Xing”爲標記。同時,它還存放了MP3文件裏幀的總個數,和100個字節的播放總時間分段的幀的INDEX,還有其他一些參數,這被稱爲Zone A,傳統Xing VBR標籤數據,共120個字節。

在二進制文本編輯器裏我們還可看到一個字符串“LAME”,並且後面清楚地跟着版本號。這就是20個字節的Zone B初始LAME信息,表示該文件是用LAME編碼技術。接下來一直到該幀結束就是Zone CLAME標籤。

3,      相關資料

× Mp3 Info Tag rev 1 specifications - draft 0

× MP3 文件格式

× MP3 SPECIS0 11172-3 AUDIO PART
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章