MIDI の基礎
MIDI(Musical Instrument Digital Interface)は、音そのものではなく演奏を記述するための言語です。MIDI メッセージは「いまノート 60 をやや強めに鳴らせ」「ノート 60 を離せ」と伝えるだけで、音声は一切運びません。下流にある何か(シンセサイザー、SoundFont プレイヤー、あるいはハードウェア)がその指示を読み、音を生成します。
この分離は強力です。同じ MIDI 演奏を、行き先の楽器を差し替えるだけでピアノ音・ギター音・オーケストラとして再生できます。下のピアノロールはそれを具体的に示します。音符はそのままで、楽器を切り替えると、まったく同じ MIDI が別の内蔵音色で鳴り直します。
MIDI は構造化された音楽情報なので、同じ音符はグリッドと同じくらい自然に楽譜としても読めます。下の譜面はエンジンが鳴らす MIDI からそのまま起こしたもので、音符も楽器切り替えもテンポも同一、各音符は鳴った瞬間に光ります。ピアノロールと楽譜は、ひとつの演奏を映す 2 つのビューです。
本ページでは、MIDI を読み書きするのに必要な語彙を説明します。概念のみで、コードはありません。
音声ではなく演奏
MIDI ファイルは波形ではなく指示を保存するため、サイズはキロバイト単位と非常に小さくなります。代償として、どの楽器でレンダリングするかで音が変わります。音声ファイルは常に同じ音で鳴りますが、手軽に音色を差し替えたり移調したりはできません。
ノート: ノートオン・ノートオフ・番号・ベロシティ
中心となる 2 つのメッセージは、ノートオン(鍵が押された)とノートオフ(鍵が離された)です。それぞれが次を運びます。
- ノート番号 0〜127。1 ステップが半音です。中央ハ(ミドル C) = 60、A4(440 Hz の基準音) = 69。1 オクターブ上げるには 12 を足します(オクターブの呼び名は製品ごとに異なり、ノート 60 を「C4」と呼ぶものも「C3」と呼ぶものもあるので、番号で判断してください)。
- ベロシティ 0〜127:鍵をどれだけ強く叩いたか。楽器は通常ベロシティを音量と明るさに割り当てるので、高いベロシティほど大きく押し出しの強い音になります(MIDI 1.0 ではベロシティ 0 のノートオンはノートオフとして扱われます。MIDI 2.0 では本物のノートオンです)。
チャンネル
1 本の MIDI ストリームは 16 のチャンネルに分かれます。1 本のケーブルを共有する 16 人の奏者のようなものです。各チャンネルは独自の楽器を持てるので、チャンネル 1 がピアノ、チャンネル 2 がベース、といった具合です。慣習上 1 つのチャンネルが特別で、General MIDI(後述)ではチャンネル 10 がドラムチャンネルとなり、各ノート番号がピッチではなく異なる打楽器音を鳴らします。
コントロールチェンジ(CC)
CC
コントロールチェンジメッセージは、番号付きのつまみ(0〜127)を、ある値(0〜127)に回します。表現・ペダル・連続コントローラーを送る仕組みです。
代表的なコントローラー:
| CC | 名称 | 役割 |
|---|---|---|
| CC1 | モッドホイール | 汎用のモジュレーション(多くはビブラートの深さ) |
| CC7 | チャンネルボリューム | チャンネルのメイン音量。ミキサーのフェーダーに相当 |
| CC10 | パン | 定位。0 = 左いっぱい、64 = 中央、127 = 右いっぱい |
| CC11 | エクスプレッション | メイン音量に加えてフレーズ内で抑揚を付ける |
| CC64 | サステインペダル | 0〜63 = 離す、64〜127 = 踏む。鍵を離した後もノートを保持 |
7 ビット(0〜127)はフェーダーを滑らかに動かすには粗いため、コントローラー 0〜31 にはそれぞれ 32 大きい番号の相方があります(CC0 と CC32、CC7 と CC39、CC10 と CC42)。前者が MSB(上位 7 ビット)、相方が LSB(下位 7 ビット)を運び、ペアで送ると 0〜16383 の 1 つの 14 ビット値になります。粗い制御で足りる機器は MSB だけを送ります。
音色を選ぶ: プログラムチェンジとバンクセレクト
プログラムチェンジメッセージは、チャンネルがどの楽器を鳴らすかを、プログラム番号 0〜127 で選びます。128 音色では足りないことが多いため、バンクセレクトでアドレスを広げます。CC0 がバンク MSB(上位バイト)、CC32 がバンク LSB(下位バイト)で、プログラムチェンジの直前に送って、128 プログラムからなる別のバンクを選びます。
GM(General MIDI)
General MIDI は、各プログラム番号の意味を固定する標準です。プログラム 0 は必ずアコースティックグランドピアノ、24 はナイロン弦ギター、という具合に 128 楽器のマップ全体を定め、さらにチャンネル 10 に標準のドラムマップを置きます。GM があるおかげで、ある機器で作った MIDI ファイルが、別の機器でも正しい種類の楽器で鳴ります。
GM2
General MIDI 2(GM2) は GM の後継の改訂版です。128 プログラムのマップはそのままに、バンクセレクトでバリエーションバンクを加えます。MSB 121 が通常の音色セット、MSB 120 がドラムセットを選び、LSB でその中のバリエーションを選びます。
0 から数えるか、1 から数えるか
信号線上のバイトは 0 から数えますが、多くのマニュアル、音色表、DAW は 1 から数えます。同じ値に 2 通りの呼び方があるので、取り違えると別の楽器が選ばれます。
| 値 | メッセージと libsonare の API | 多くのマニュアルと DAW | 例 |
|---|---|---|---|
| チャンネル | 0〜15 | 1〜16 | GM のドラムチャンネルは「チャンネル 10」で、API には 9 を渡す |
| プログラム | 0〜127 | 1〜128 | バイオリンはここではプログラム 40、1 始まりの表では「41」 |
| ノート番号 | 0〜127 | 0〜127 | どちらも同じ。中央ハは 60 |
このドキュメントは、プログラムと API のチャンネルを 0 始まりで書きます。本文で「チャンネル 10」と書くときはマニュアルと同じ呼び方で、横のコードでは 9 を渡しています。
ピッチベンド・RPN・NRPN
ピッチベンドは独自の高分解能メッセージ(CC ではありません)で、ノートのピッチを連続的に上下へスライドさせます。ギターのチョーキング、ビブラート、アームの効果などに使います。フルベンドがどこまで届くか、すなわちピッチベンドレンジは、ピッチベンドメッセージ自体には含まれず、後述の RPN メッセージで別に設定します。
RPN / NRPN
RPN(Registered Parameter Number)は、CC メッセージ経由でアドレス指定する標準化された設定です。RPN 0 はピッチベンドレンジで、フルベンドが何半音をカバーするかです。NRPN(Non-Registered Parameter Number)は同じ仕組みを、標準外の機器固有パラメータに使います。
RPN の設定は、そのチャンネルへ送る短いコントロールチェンジの列です。CC101(RPN MSB)と CC100(RPN LSB)でパラメータを選び、CC6(データエントリー MSB)と CC38(データエントリー LSB)で値を書きます。ピッチベンドレンジを ±12 半音にする例は次のとおりです。
| 手順 | メッセージ | 意味 |
|---|---|---|
| 1 | CC101 = 0 | RPN の MSB 0 を選ぶ |
| 2 | CC100 = 0 | RPN の LSB 0(ピッチベンドレンジ)を選ぶ |
| 3 | CC6 = 12 | 12 半音 |
| 4 | CC38 = 0 | 端数は 0 セント |
| 5 | CC101 = 127、CC100 = 127 | 選択を解除する(「ヌル」RPN)。あとで紛れ込んだデータエントリーがレンジを変えないようにするため |
NRPN も同じ手順で選びます。CC101 と CC100 の代わりに CC99(MSB)と CC98(LSB)を使います。
タイミング: ティックと PPQ
MIDI メッセージは何が起きるかを伝えますが、ファイルにはいつ起きるかも必要です。Standard MIDI File は時間をティックで数えます。ティックは整数のステップで、秒での長さは決まっていません。PPQ(pulses per quarter note。PPQN や division とも書きます)は、4 分音符 1 つが何ティックかを表し、480 がよく使われます。480 PPQ なら 4 分音符は 480 ティック、8 分音符は 240、16 分音符は 120 です。
ティックが秒になるのはテンポを通してだけです。1 分間に 4 分音符 120 拍なら 4 分音符は 0.5 秒で、480 PPQ の 1 ティックは約 1.04 ms です。テンポマップ(指定ティックでのテンポ変更)があれば 1 つのファイルの中で速くも遅くもなり、同じティック数でも到達する時刻が変わります。
libsonare の ppq は分解能ではなく位置です
アレンジメント API の ppq 引数は 4 分音符を単位とした位置(浮動小数)です。1 は 4 分音符 1 つ分、0.5 は 8 分音符 1 つ分で、ファイル形式でいう「pulses per quarter」ではありません。ファイルから変換するときは、先にティック数をそのファイルの PPQ で割ってください(480 PPQ のティック 960 は ppq 2)。SMF エクスポートは 4 分音符あたり 480 ティックで書き出します。
MIDI ファイルと MIDI 2.0
UMP
MIDI 2.0 はプロトコルの現代的な改訂版です。UMP(Universal MIDI Packet)形式を用い、はるかに高い分解能(16 ビットのベロシティ、より細かいコントローラー)と双方向通信を加えつつ、上記の MIDI 1.0 の考え方との互換性を保ちます。
UMP のストリームはチャンネルの数も広げます。16 のグループがあり、グループごとに 16 チャンネルを持つので、1 本の接続で 256 チャンネルを指定できます。group 引数を取る API は、このグループのどれかを選んでいます。普通の MIDI 1.0 の構成ではグループ 0 を使います。
MPE(MIDI Polyphonic Expression)
MIDI 1.0 では、ピッチベンドとプレッシャー(アフタータッチ。押さえた鍵をさらにどれだけ強く押し込むか)はチャンネル全体にかかります。和音の 1 音だけをベンドすると、全部の音がベンドされます。MPE は、鳴っているノートごとに別のチャンネルを割り当てることでこれを回避します。ゾーンはそのために用意したチャンネルのまとまりです。1 つのマネージャーチャンネル(下側ゾーンはチャンネル 1、上側ゾーンは 16)がサステインペダルのようなゾーン全体向けのメッセージを運び、各メンバーチャンネルが 1 つのノートと、そのノート自身のベンド、プレッシャー、音色(CC74)を運びます。MIDI 2.0 ではノート単位のメッセージでノートを直接指定できるので、ノートごとにチャンネルを使わなくても同じことができます。
SMF(Standard MIDI File、拡張子 .mid)は演奏全体(すべてのノートオン/オフ、CC、プログラムチェンジを、そのタイミングごと)を保存するため、保存・共有し、任意の楽器で再生できます。
全体像
MIDI が演奏と音を切り分けている様子は、一本道のパイプラインとして表れます。ソースがノートとコントローラーのメッセージを送り出し、楽器がそれを解釈し、最後の段階だけが音声を生成します。
libsonare での実装
libsonare のリアルタイムエンジンは、ノートを pushMidiNoteOn(destinationId, group, channel, note, velocity) と pushMidiNoteOff(...) で、コントロールチェンジを pushMidiCc(destinationId, group, channel, controller, value) で受け取ります。destinationId は送出先(デスティネーション)、つまりどの読み込み済み楽器がイベントを受けるかを選び、channel は 0〜15 の MIDI チャンネルです。ブラウザでは Web MIDI ブリッジ(bindWebMidi)が、物理 MIDI 鍵盤のイベントをそれらのエンジン入力へ直接つなぎ、ハードウェアコントローラーで NativeSynth や読み込んだ SoundFont をライブ演奏できます。同じノート/CC の語彙は、ライブエンジンとオフラインのアレンジメントバウンスの両方で使われます。