ムライボックス (7) --- ソフトウェア (2)

ステータス・バイトの値が 0xF0 〜 0xFF の範囲の MIDI メッセージはまとめて「システム・メッセージ」と呼ばれ、「システム・リアルタイム・メッセージ」、「システム・コモン・メッセージ」、および「システム・エクスクルーシブ・メッセージ」と呼ばれる 3 つのタイプのメッセージから構成されています。
システム・メッセージには「MIDI チャネル」の概念はなく、システム全体、デバイス全体に対して影響を与えるような「ブロードキャスト」の性格を持つメッセージとなっています。
システム・リアルタイム・メッセージは、ステータス・バイトが 0xF8 〜 0xFF の範囲に割り付けられており、ステータス・バイトのみの 1 バイト構成でシステムの「タイミング」や「同期」を制御します。
例えば 0xF8 が「タイミング・クロック」で、0xFA / 0xFB / 0xFC がそれぞれ、「スタート」 / 「コンティニュー」 / 「ストップ」となっています。
「タイミング」に関わっているため、システム・リアルタイム・メッセージは優先的に扱われることが求められており、例え他のメッセージの途中であってもメッセージ終了まで待たずに、任意の場所に挿入できることになっています。
受信側は、システム・リアルタイム・メッセージを受信した時点で、まだ完結していない他のメッセージの受信途中であっても、そのメッセージに対する設定を保全したまま処理を一時保留し、システム・リアルタイム・メッセージの処理 (あるいは無視) をしなければなりません。
リアルタイム・メッセージの処理後は、もとのメッセージの処理に戻ります。
つまり、「システム・リアルタイム・メッセージ」は一種の「割り込み」あるいは「エスケーピング」として扱います。
ステータス・バイトが 0xF0 〜 0xF7 の範囲は「システム・コモン・メッセージ」です。
ステータス・バイトが 0xF0 は「システム・エクスクルーシブ・メッセージ」の始まりですが、便宜上、システム・コモン・メッセージの中に入れてしまいます。
システム・コモン・メッセージには、ステータス・バイトだけの 1 バイトで構成されるものや、1 〜 2 バイトのデータ・バイトが後に続く 2 〜 3 バイト構成のものがあります。
その点では、チャネル番号がないだけで、チャネル・メッセージと同様です。
システム・エクスクルーシブ・メッセージには任意の数のデータ・バイトを含ませることができますが、ムライボックスとしての処理については、他のシステム・コモン・メッセージと同様に扱えます。
システム・メッセージはブロードキャスト・メッセージの性格を持っているので、システム・メッセージが出現したら全ての出力ポートに同時に通過させる扱いで構わないのですが、ここでは、ステータス・バイトの下位 4 ビットの値をインデクスとする下のようなビット・マスク・テーブルを用意することにしました。

//
// system common / realtime message to port mask pattern table in RAM
// port bitmap assignment:
// b15 = port16, ... , b1 = port2, b0 = port1
//
uint16_t sysmsg_tab[16] = {
	0xffff, // 0xF0, Start of Exclusive (arbitrary)
	0xffff, // 0xF1, MTC Quater frame (2 byte)
	0xffff, // 0xF2, Song Position Pointer (3 byte)
	0xffff, // 0xF3, Song Select (2 byte)
	0x0000, // 0xF4, undefined
	0x0000, // 0xF5, undefined
	0xffff, // 0xF6, Tune Request (1 byte, obsolute)
	0xffff, // 0xF7, End of Exclusive
	0xffff, // 0xF8, MIDI Clock
	0x0000, // 0xF9, undefined
	0xffff, // 0xFA, Start
	0xffff, // 0xFB, Continue
	0xffff, // 0xFC, Stop
	0x0000, // 0xFD, undefined
	0xffff, // 0xFE, Active sensing
	0x0000  // 0xFF, System Reset (obsolute)
}; // uint16_t sysmsg_tab[]

ステータス・バイトの下位 4 ビットは、チャネル・メッセージではチャネル番号であり、システム・メッセージでは 16 種のメッセージ種別を表す部分になります。
このテーブルで出力ポートのビット・マスクに変換すると、単に全出力ポートに送出する、あるいは阻止するだけではなく、特定のシステム・メッセージを特定の出力ポートに通過/阻止することを細かく制御できます。
上の例では、単に未定義メッセージを出力に送らず、それ以外は全ポートに送っているだけですが、設定次第で、MIDI クロック・タイミング (0xF8) だけを抽出して特定のポートに送ったり、逆に、クロック・タイミングだけを阻止することもできます。