MIDI文件格式分析

來源:http://blog.163.com/waft_xu/blog/static/4381529420081241836248/

 

 

MIDI文件屬於二進制文件,這種文件一般都有如下基本結構: 文件頭+數據描述

    文件頭一般包括文件的類型,因爲Midi文件僅以.mid爲擴展名的就有0類和1類兩種,而大家熟悉的位圖文件的格式就更多了,所以纔會出現文件頭這種東西。

    而數據描述部份是主體,我們現在來一起分析它的結構:

    在每個Midi文件的開頭都有如下內容,它們的十六進制代碼爲:4d 54 68 64 00 00 00 06 ff ff nn nn dd dd”。

    前四個是ASCII字符“MThd”是用來鑑別是否Midi文件,而隨後的四個字節是指明文件頭描述部分的字節數,它總是6,所以一定是“00 00 00 06”,以下是剩餘部分的含義:

ff ff

指定Midi的格式

00 00

單音軌

00 01

多音軌,且同步。這是最常見的

00 02

多音軌,但不同步

nn nn

指定軌道數

實際音軌數加上一個全局的音軌

dd dd

指定基本時間

一般爲120(00 78),即一個四分音符的tick數,tickMIDI中的最小時間單位

    以上就是MIDI文件頭了,後面的所有內容都是真正做事的,我們先來看看它的構成。

    MIDI的數據是由若干個格式相同的子數據構成的,這些子數據在多音軌的格式中記錄了一個軌道的所有信息。多加一個音軌,就簡單地把數據追加在前一音軌的後面就可以了,不過不要忘記更改文件頭中的nn nn(軌道數)

    先看全局音軌。全局音軌包括歌曲的附加信息(比如標題和版權)、歌曲速度和系統碼(Sysx)等內容。

    不管是全局音軌還是含有音符的音軌,都以“4D 54 72 6B”開頭,它其實是ASCII字符“MTrk”,其後跟着一個4個字節的整數,它標誌了該軌道的字節數,這不包括前面的4個字節和本身的4個字節。這一點,我們可以在後面的例子中去理解。

    接着就是記錄數據的地方了,每一個數據有着相同的結構:時間差+事件。

    所謂時間差,指的是前一個事件到該事件的時間數,它的單位是tick(MIDI的最小時間單位)。它的構成比較特殊,這裏要用二進制來說明。

    一個字節有8位,如果僅使用7位,它可以表示0~127128個數,而剩下的一位,則用來作爲標誌。如果要表示的數在以上範圍,則這個標誌爲0,這時,一個7位的字節可以表示0~127tick。如果要表示的數超出了這個範圍(比如240),則把標誌設置成1,然後記錄下高7位,剩下的留給下一個字節,在該例中240可以分解成128*1+112,這裏的1就是第一個字節要記錄的,加上標誌位,應該爲10000001,即十六進制的81;而112是下一個字節記錄的,它的十六進制爲70:所以要表示240這個時間,要寫成81 70。同理,如果要表示65535tick,則可以先計算出65535=1282*3+1281*127+1280*127,然後得出結果:83 FF 7F。由此,我們反過來也可以知道如何確定時間差:只要標誌位爲0,則表示結束讀取時間差。比如82 C0 03表示1282*2+1281*64+1280*3=40963,如果基本時間爲120,則有341:043個四分音符。

    以這種方式記錄整數的字節稱爲動態字節,它根據記錄的整數改變自身的長度,這在後面還要用到,所以必須熟練計算。

    看完了這麼麻煩的東西,我們再來看個更麻煩的東西:事件。在這些標準的解釋後面,我們會通過一些例子來進一步掌握這些內容。

    事件大體上可以分爲音符、控制器和系統信息這幾個種類。對於這些事件,都有統一的表達結構:種類+參數。

    對於一個音符,由於它的有效範圍是0~127,所以直接用00~7F作爲“種類”,可以認爲是個音符,比如3C表示中央C。而一個音符的最重要的參數是力度(也叫速度:velocity)。比如,3C 64 表示一個力度爲十進制100的中央C音符。

    因爲一個字節有8位,所以剩餘的一位如果置1,再聯合其他的7位,則可以表示各種信息。我們暫且無視一個音軌到底是全局的還是用於記錄音符的。它們歸根結底都是用來記錄各種事件的,只不過有些應出現在全局音軌比較合乎邏輯而已。既然這樣,我們就可以從下面的表來看事件:

    下表中,x表示音軌0~F,比如81表示鬆開第二軌的音符。

種類

參數(十六進制)

字節

含義

8x

鬆開音符

音符(00~7F):鬆開的音符

力度:00~7F

9x

按下音符

音符(00~7F):按下的音符

力度:00~7F

Ax

觸後音符

(Key After Touch)

音符:00~7F

力度:00~7F

Bx

控制器

控制器號碼:00~7F

控制器參數:00~7F

Cx

改變樂器

樂器號碼:00~7F

Dx

觸後通道

:00~7F

Ex

滑音

音高(Pitch)低位:Pitch mod 128

音高高位:Pitch div 128

F0

系統碼

系統碼字節數:動態字節

系統碼:不含開頭的F0,但包括結尾的F7

FF

其他格式

程式種類:00~FF

數據佔用的字節數:動態字節

數據:個數由上一參數確定

00~7F

上次激活格式的參數(8x9xAxBxCxDxEx)

    下表詳細地列出了FF的詳細情況,對於字節數由數據決定的情況,表中以“--”表示。

種類

字節數

數據

字節

含義

00

設置軌道音序

02

音序號 00 00~ FF FF

01

歌曲備註

--

文本信息

音軌文本

文本信息

02

歌曲版權

--

版權信息

03

歌曲標題

--

歌曲標題:用於全局音軌,第一次使用表示主標題,第二次表示副標題

音軌名稱

--

音軌名

04

樂器名稱

--

音軌文本(01/2)

05

歌詞

--

歌詞

06

標記

--

用文本標記(Marker)

07

開始點

--

用文本記錄開始點(01/2)

2F

音軌結束標誌

00

51

速度

03

3字節整數,1個四分音符的微秒數

58

節拍

04

分子

分母:00(1),01(2),02(4),03(8)

節拍器時鐘

一個四分音符包含的三十二分音符的個數

59

調號

02

升降號數:-7~-1(降號),0(C),1~7(升號)

大小調:0(大調)1(小調)

7F

音序特定信息

--

音序特定信息

    這些就是MIDI結構的全部內容

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