MIDI 實際不是聲音格式檔案,只是一連串與音效有關的指令,通過音效卡來模擬樂器的聲音
MusicXML 是一種 XML 格式,可以純文字來製作,但 MusicXML 還比 MIDI 更複雜
而且 MIDI 本身就是標準格式,因此直接使用 MIDI 來測試
MIDI 格式是由一連串 十六進制 內容組成,因此不能單純以純文字製作,但通過如 printf '\x41' 這種方式輸出內容勉強都能以純文字方式建立
MIDI 由兩部分組成
一個 MIDI Header Chunk 及 一個或以上 MIDI Track Chunk 組成
可以用 MIDI = MIDI Header Chunk + MIDI Track Chunk [+ MIDI Track Chunk ...] 表達
MIDI Header Chunk 由五部分組成
MIDI Header Chunk = "MThd" + 資料長度 + MIDI格式 + 音軌數量 + Ticks Per Quarter Note
以下表單是概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | 4D 54 68 64 | 4 | 標頭資料 MThd |
2 | 00 00 00 06 | 4 | 資料長度為 6 ,在標準MIDI格式規格中必定為 6 |
3 | 00 01 | 2 | MIDI格式 |
4 | 00 01 | 2 | 音軌數量 |
5 | 00 60 | 2 | TPQN 60 (hex) = 96 (dec) |
- MIDI Header Chunk 開首必為 4位元組 ,轉換成字元就是 MThd
- 之後是 4位元組 的 資料長度
- 之後是 2位元組 的 MIDI格式 ,共有 3種
- 0 - 單音軌
- 1 - 同步多音軌 (通常編曲軟件匯出 MIDI 的格式)
- 2 - 異步多音軌
- 之後是 2位元組 的 音軌數量
當 MIDI格式 為 0 時,音軌數量 必須是 1
當 MIDI格式 為 1 或 2 時,音軌數量 必須是 1 或以上 - 之後是 2位元組 的 Ticks Per Quarter Note (TPQN)
即是 每一拍是多少Ticks , 一拍指一個四分音符(或四分休止符)的時間長度
若 一拍(四分)是 16 Ticks , 二拍(二分)便是 32 Ticks , 半拍(八分)則是 8 Ticks
雖然一般節拍長度都是以 二指數遞增 ,但編曲時還有如 三連音 、 五連音 等 非二指數遞增 的時間長度
因此設定 TPQN 時需要考慮編曲的內容需要來調整,例如 TPQN 為 480 (01E0 hex) 便是 3, 5, 32 的倍數,編曲時便可以較多變動空間
若還需要使用如 七連音 等 質數數值的連音 時間長度,便再計算及調整
MIDI Track Chunk 由三部分組成
MIDI Track Chunk = "Mtrk" + 資料長度 + Event [+ Event ...]
以下表單為概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | 4D 54 72 6B | 4 | 音軌標頭 MTrk |
2 | 00 00 00 04 | 4 | 資料長度, 00 00 00 04 表示 資料長度 為 4 |
3 | * | * | Event |
- MIDI Track Chunk 開首必為 4位元組 ,轉換成字元就是 Mtrk
- 之後是 4位元組 的 資料長度 ,長度計算至 Track Footer
- 然後是最少一組 Event
Event 由三部分組成
Event = 相距時間長度 + (MIDI Event | Meta Event | SysEx Event) + 00 (hex)
以下表單為概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | 00 | 1 | 相距時間長度, 00 表示 與上一個 Event 的相距時間長度 為 0 |
2 | * | * | MIDI Event | Meta Event | SysEx Event |
3 | 00 | 1 | 結束 Event |
- 相距時間長度 與上一個 Event 的相距時間長度
- 當中可以使用一種或多種 Event ,次序不限定
- MIDI Event 為音訊內容
- Meta Event 為音軌或音訊資料
- SysEx Event
- 00 為十六進制資料,結束 Event
MIDI Event 由二部分組成
MIDI Event = Note On + Note Off
MIDI Event 就是觸發音效的 Event ,當中 Note On
Note On 由三部分組成,是音效開始
Note On = 音效開始 + 音調 + 音量
以下表單為概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | 90 ~ 9F | 1 | 音效開始 |
2 | 00 ~ 7F | 1 | 音調 |
3 | 00 ~ 7F | 1 | 音量 |
- 音效開始 是 1位元組 為 90 ~ 9F (hex) 即是 144 ~ 159 (dec)
- 音調 是 1位元組 範圍為 00 ~ 7F (hex) 即是 0 ~ 127 (dec) ,當音標為 3C (hex) 即是 60 (dec) 時,等同 Middle C
- 音量 是 1位元組 範圍為 00 ~ 7F ,當音量為 0 時,等同 休止符 (Rest)
Note Off 由三部分組成,是音效結束
Note Off = 音效時間長度 + 音效停止 + 音調
以下表單為概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | * 00 ~ 7F | 1 ~ 16 | 音效時間長度 |
2 | 80 ~ 8F | 1 | 音效停止 |
3 | 00 ~ 7F | 1 | 音調,與之前相同 |
- 音效時間長度 是 1至16位元組 ,當長度是 7F (hex) = 127 (dec) Ticks ,可以直接寫入
但 Ticks 超過127 便會非常複雜
例如以在下 TPQN 使用 60 (hex) = 96 (dec) ,當使用 二分音符(或二分休止符) 便會是 192 ,是不能直接寫入 C0
由於 192 除以128 商數 為 1 餘數 為 64
因為進行 1次 除以128 ,所以需要用多 1位元組 寫成 128+1 64 (dec) = 81 40 (hex)
若果 商數 仍是 超過127 ,便需要再 除以128
例如 32768 除以128 商數 為 256 超過127 ,需要再 除以128 商數 為 2 餘數 為 0
因為進行 2次 除以128 ,所以需要用多 2位元組 寫成 128+2 128+0 0 (dec) = 82 80 00 (hex)
若 商數 仍 超過127 ,繼續 除以128 - 音效停止 是 1位元組 為 80 ~ 8F (hex) 即是 128 ~ 143 (dec)
- 音調 是 1位元組 與剛才相同
當同時間寫入超過一個音調可以寫成
MIDI Event = 相距時間長度 + Note On [+ 相距時間長度 + Note on] + Note Off + 00 [+ Note Off + 00]
但這種 MIDI Event 只需要 第一個 Note Off 需要有已計算妥當的 音效時間長度
其餘的 Note Off 的 音效時間長度 為 0 即可,否則之後的 Note Off 的 音效時間長度 便會延長
例如
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
2 | 00 90 3C 7F | 4 | 相距時間長度為 0 ,音效開始,音調為 3C (hex) ,音量為 7F (hex) |
4 | 00 90 40 7F | 4 | 相距時間長度為 0 ,音效開始,音調為 40 (hex) ,音量為 7F (hex) |
5 | 60 80 3C 00 | 4 | 音效時間長度 為 60 (hex) ,停止音調為 3C (hex) 的音效,結束 Event |
7 | 00 80 40 00 | 4 | 音效時間長度 為 60+0 (hex) ,停止音調為 40 (hex) 的音效,結束 Event |
Meta Event 有多種設定形式
Meta Event = FF + 資料類型 + 資料長度 + 資料參數
以下表單為概要
部分 | 十六進制資料 | 位元組長度 | 說明 |
---|---|---|---|
1 | * | 1 | 資料類型,有指點類型設值 |
2 | * | 1 | 資料長度 |
3 | * | 1 ~ 255 | 資料參數,若參數超越 ASCII編碼 需要使用 URL編碼 寫入 |
- 00 為 編曲號碼 ,資料長度 為 2
- 01 為 描述資料
- 02 為 版權資訊
- 03 為 音軌名稱
- 04 為 樂器名稱
- 05 為 當前歌詞
- 06 未了解使用方法
- 07 未了解使用方法
- 08 未了解使用方法
- 09 未了解使用方法
- 20 未了解使用方法
- 21 未了解使用方法
- 2F 為 音軌結束 ,資料長度 為 0 ,沒有參數
- 51 為 Tempo ,資料長度 為 3 ,三個參數為 Micro Tempo
MIDI 實際並不是以 五線譜 的 Tempo 計算速度,而是使用 Beats Per Minute (BPM) 來計算
60BPM = 1秒 = 1個四分音符(或四分休止符)
將 微秒 除以 Beats 計算出 Micro Tempo
例如 60BPM , 1分鐘 = 60秒 = 60000000微秒 / 60 Beats = 1000000 Micro Tempo , 1000000 (dec) = 0F4240 (hex)
因此使用 60BPM 需要寫成 FF 51 03 0F 42 40 ,預設為 60BPM - 54 為 SMPTE偏移值 未了解使用方法
- 58 為 拍號 ,資料長度 為 4
- 第一個參數為 分子 ,表示每節有多少拍
- 第二個參數為 分母 ,以 2n 方式為一拍,例如 2 為 四分一拍, 3 為 八分一拍,如此類推
- 第三個參數為 MIDI Clock ,以 四分一拍(2) 為 24 (dec) = 18 (hex) TPQN ,八分一拍(3) 為 36 (dec) = 24 (hex) TPQN ,如此類推
資料為 0 時會自動計算,預設為 四四拍 - 第四個參數通常為 固定值 8 ,某些 編曲器 會不同
- 59 為 變調 ,資料長度 為 2
- 第一個參數為 調號 為 -7 ~ 7
0 為 沒有調號 , 1 ~ 7 為 Sharp數量 , -1 ~ -7 為 Flat數量
Sharp 是正數,沒有特殊設定,但 Flat 是負數,便需要使用 Two's Complement 來計算
十進制資料 十六進制資料 大調 小調 7 07 升C 升A 6 06 升F 升D 5 05 B 升G 4 04 E 升C 3 03 A 升F 2 02 D B 1 01 G E 0 00 C A -1 FF F D -2 FE 降B G -3 FD 降E C -4 FC 降A F -5 FB 降D 降B -6 FA 降G 降E -7 F9 降C 降A - 第二個參數為 譜號
0 為 高音譜號 , 1 為 低音譜號
預設為 高音譜號
- 第一個參數為 調號 為 -7 ~ 7
- 7F 未了解使用方法
樂器表,數值為 00 (hex) ~ 7F (hex)
十六進制 | 樂器種類 | 樂器 |
---|---|---|
00 | 鋼琴 | 平台鋼琴 |
01 | 鋼琴 | 亮音鋼琴 |
02 | 鋼琴 | 電鋼琴 |
03 | 鋼琴 | 酒吧鋼琴 |
04 | 鋼琴 | 電子鋼琴1 |
05 | 鋼琴 | 電子鋼琴2 |
06 | 鋼琴 | 大鍵琴 |
07 | 鋼琴 | 電翼琴 |
08 | 高定音敲擊樂器 | 鋼片琴 |
09 | 高定音敲擊樂器 | 鐘琴 |
0A | 高定音敲擊樂器 | 音樂盒 |
0B | 高定音敲擊樂器 | 顫音琴 |
0C | 高定音敲擊樂器 | 馬林巴琴 |
0D | 高定音敲擊樂器 | 木琴 |
0E | 高定音敲擊樂器 | 管鐘 |
0F | 高定音敲擊樂器 | 揚琴 |
10 | 風琴 | 音栓風琴 |
11 | 風琴 | 敲擊風琴 |
12 | 風琴 | 搖滾風琴 |
13 | 風琴 | 教堂管風琴 |
14 | 風琴 | 簧風琴 |
15 | 風琴 | 手風琴 |
16 | 風琴 | 口琴 |
17 | 風琴 | 探戈手風琴 |
18 | 結他 | 尼龍弦木結他 |
19 | 結他 | 鋼弦木結他 |
1A | 結他 | 爵士樂電結他 |
1B | 結他 | 原音電結他 |
1C | 結他 | 悶音電結他 |
1D | 結他 | 破音電結他 |
1E | 結他 | 失真音電結他 |
1F | 結他 | 泛音結他 |
20 | 低音結他 | 民謠低音結他 |
21 | 低音結他 | 指奏低音電結他 |
22 | 低音結他 | 撥奏低音電結他 |
23 | 低音結他 | 無格低音結他 |
24 | 低音結他 | 捶鈎低音結他1 |
25 | 低音結他 | 捶鈎低音結他2 |
26 | 低音結他 | 合成低音結他1 |
27 | 低音結他 | 合成低音結他2 |
28 | 弦樂器 | 小提琴 |
29 | 弦樂器 | 中提琴 |
2A | 弦樂器 | 大提琴 |
2B | 弦樂器 | 低音大提琴 |
2C | 弦樂器 | 顫弓弦樂 |
2D | 弦樂器 | 彈撥弦樂 |
2E | 弦樂器 | 豎琴 |
2F | 弦樂器 | 定音鼓 |
30 | 合奏 | 弦樂合奏1 |
31 | 合奏 | 弦樂合奏2 |
32 | 合奏 | 合成弦樂1 |
33 | 合奏 | 合成弦樂2 |
34 | 合奏 | 人聲「啊」 |
35 | 合奏 | 人聲「喔」 |
36 | 合奏 | 合成人聲 |
37 | 合奏 | 打擊交響樂 |
38 | 銅管樂器 | 小號 |
39 | 銅管樂器 | 長號 |
3A | 銅管樂器 | 大號 |
3B | 銅管樂器 | 悶音小號 |
3C | 銅管樂器 | 法國號 |
3D | 銅管樂器 | 銅管樂 |
3E | 銅管樂器 | 合成銅管1 |
3F | 銅管樂器 | 合成銅管2 |
40 | 簧管樂器 | 高音色士風 |
41 | 簧管樂器 | 中音色士風 |
42 | 簧管樂器 | 次中音色士風 |
43 | 簧管樂器 | 上低音色士風 |
44 | 簧管樂器 | 雙簧管 |
45 | 簧管樂器 | 英國管 |
46 | 簧管樂器 | 低音管 |
47 | 簧管樂器 | 單簧管 |
48 | 吹管樂器 | 短笛 |
49 | 吹管樂器 | 長笛 |
4A | 吹管樂器 | 直笛 |
4B | 吹管樂器 | 排笛 |
4C | 吹管樂器 | 瓶笛 |
4D | 吹管樂器 | 尺八 |
4E | 吹管樂器 | 哨子 |
4F | 吹管樂器 | 陶笛 |
50 | 合成音主旋律 | 方波 |
51 | 合成音主旋律 | 鋸齒波 |
52 | 合成音主旋律 | 汽笛風琴 |
53 | 合成音主旋律 | 合成吹管 |
54 | 合成音主旋律 | 合成電結他 |
55 | 合成音主旋律 | 人聲鍵盤 |
56 | 合成音主旋律 | 五度音 |
57 | 合成音主旋律 | 低音結他主結他合奏 |
58 | 合成音和弦 | 新世紀 |
59 | 合成音和弦 | 溫暖 |
5A | 合成音和弦 | 多重合音 |
5B | 合成音和弦 | 人聲合唱 |
5C | 合成音和弦 | 玻璃 |
5D | 合成音和弦 | 金屬 |
5E | 合成音和弦 | 光華 |
5F | 合成音和弦 | 掃掠 |
60 | 合成音效 | 下雨 |
61 | 合成音效 | 電影音效 |
62 | 合成音效 | 水晶 |
63 | 合成音效 | 氣氛 |
64 | 合成音效 | 明亮 |
65 | 合成音效 | 魅影 |
66 | 合成音效 | 回音 |
67 | 合成音效 | 科幻 |
68 | 民族樂器 | 西塔琴 |
69 | 民族樂器 | 五弦琴 |
6A | 民族樂器 | 三味線 |
6B | 民族樂器 | 古箏 |
6C | 民族樂器 | 卡林巴鐵片琴 |
6D | 民族樂器 | 蘇格蘭風笛 |
6E | 民族樂器 | 古提琴 |
6F | 民族樂器 | 獸笛 |
70 | 打擊樂器 | 叮噹鈴 |
71 | 打擊樂器 | 阿哥哥鈴 |
72 | 打擊樂器 | 鋼鼓 |
73 | 打擊樂器 | 木魚 |
74 | 打擊樂器 | 太鼓 |
75 | 打擊樂器 | 定音筒鼓 |
76 | 打擊樂器 | 合成鼓 |
77 | 打擊樂器 | 逆轉鈸聲 |
78 | 音效 | 結他滑弦雜音 |
79 | 音效 | 呼吸雜音 |
7A | 音效 | 海岸 |
7B | 音效 | 鳥鳴 |
7C | 音效 | 電話鈴聲 |
7D | 音效 | 直升機 |
7E | 音效 | 拍手 |
7F | 音效 | 槍聲 |
聲調表,數值為 00 (hex) ~ 7F (hex)
度數 | C | C# / Cb | D | D# / Eb | E | F | F# / Gb | G | G# / Ab | A | A# / Bb | B |
---|---|---|---|---|---|---|---|---|---|---|---|---|
-1 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0A | 0B |
0 | 0C | 0D | 0E | 0F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
1 | 18 | 19 | 1A | 1B | 1C | 1D | 1E | 1F | 20 | 21 | 22 | 23 |
2 | 24 | 25 | 26 | 27 | 28 | 29 | 2A | 2B | 2C | 2D | 2E | 2F |
3 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B |
4 | 3C * | 3D | 3E | 3F | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
5 | 48 | 49 | 4A | 4B | 4C | 4D | 4E | 4F | 50 | 51 | 52 | 53 |
6 | 54 | 55 | 56 | 57 | 58 | 59 | 5A | 5B | 5C | 5D | 5E | 5F |
7 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 6A | 6B |
8 | 6C | 6D | 6E | 6F | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
9 | 78 | 79 | 7A | 7B | 7C | 7D | 7E | 7F |
以下是一個利用 Bash 建立 一個擁有 Middle C 四分音符 的 MIDI檔案 示範
output='test.mid' printf '' >"${output}" for b in \ 4D 54 68 64 \ 00 00 00 06 \ 00 01 \ 00 01 \ 00 60 \ 4D 54 72 6B \ 00 00 00 0C \ 00 90 3C 7F 60 80 3C 00 \ 00 FF 2F 00 \ ; do printf "\\x${b}" >>"${output}" done便是最簡單的 MIDI 格式
沒有留言 :
張貼留言