複製鏈接
請複製以下鏈接發送給好友

MIDI文件格式

鎖定
MIDI文件屬於二進制文件,這種文件一般都有如下基本結構: 文件頭+數據描述 文件頭一般包括文件的類型,因為Midi文件僅以。mid為擴展名的就有0類和1類兩種,而大家熟悉的位圖文件的格式就更多了,所以才會出現文件頭這種東西。
中文名
MIDI文件格式
基本信息
MIDI文件不對音樂進行抽樣
構    成
由若干個格式相同的子數據構成的
文件結構
類型指的是"MThd"或"MTrk"

MIDI文件格式文件簡介

與波形文件不同,MIDI文件不對音樂進行抽樣,而是對音樂的每個音符記錄為一個數字,所以與波形文件相比文件要小得多,可以滿足長時間音樂的需要。MIDI標準規定了各種音調的混合及發音,通過輸出裝置可以將這些數字重新合成為音樂。
MIDI音樂的主要限制是它缺乏重現真實自然聲音的能力,因此不能用在需要語音的場合。此外,MIDI只能記錄標準所規定的有限種樂器的組合,而且回放質量受到聲音卡的合成芯片的限制。近年來,國外流行的聲音卡普遍採用波表法進行音樂合成,使MIDI的音樂質量大大提高。
MIDI文件有幾個變通格式,如RMI和CIF等。其中CMF文件(creative music format)是隨聲霸卡一起使用的音樂文件。RMI文件是Windows使用的RIFF(resource interchange file format)文件的一種子格式,稱為RMID,即包含MIDI文件的格式。

MIDI文件格式MIDI文件結構

以下是MIDI文件塊結構
類型
長度
數據
4個字節
4個字節
4個字節
類型指的是"MThd"或"MTrk",長度指的是除去類型和長度兩部分外,其他數據佔的字節數。
而數據描述部份是主體,我們現在來一起分析它的結構:
在每個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
指定基本時間格式類型
類型1:定義一個四分音符的tick數,tick是MIDI中的最小時間單位
類型2:定義每秒中SMTPE幀的數量及每個SMTPE幀的tick
以上就是MIDI文件頭了,後面的所有內容都是真正做事的,我們先來看看它的構成。

MIDI文件格式構成

MIDI的數據是由若干個格式相同的子數據構成的,這些子數據在多音軌的格式中記錄了一個軌道的所有信息。多加一個音軌,就簡單地把數據追加在前一音軌的後面就可以了,不過不要忘記更改文件頭中的nn nn(軌道數)
先看全局音軌。全局音軌包括歌曲的附加信息(比如標題和版權)、歌曲速度和系統碼(Sysx)等內容。
不管是全局音軌還是含有音符的音軌,都以“4D 54 72 6B”開頭,它其實是ASCII字符“MTrk”,其後跟着一個4個字節的整數,它標誌了該軌道的字節數,這不包括前面的4個字節和本身的4個字節。這一點,我們可以在後面的例子中去理解。
接着就是記錄數據的地方了,每一個數據有着相同的結構:時間差+事件。
所謂時間差,指的是前一個事件到該事件的時間數,它的單位是tick(MIDI的最小時間單位)。它的構成比較特殊,這裏要用二進制來説明。
一個字節有8位,如果僅使用7位,它可以表示0~127這128個數,而剩下的一位,則用來作為標誌。如果要表示的數在以上範圍,則這個標誌為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觸後音符
音符: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
上次激活格式的參數(8x、9x、Ax、Bx、Cx、Dx、Ex)
下表詳細地列出了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
59調號
02
大小調:0(大調),1(小調)
升降號數:-7~-1(降號),0(C),1~7(升號)
7F音序特定信息
--
音序特定信息
[1] 
參考資料
  • 1.    MIDI原理與開發應用 陳學煌等編著