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

今回からソフトウェアの話に入ります。
「ムライボックス」の特徴である「MIDI チャネル番号の書き換え」という点で、MIDI メッセージの、

  • チャネル・ボイス・メッセージおよびチャネル・モード・メッセージ
    (0x80 〜 0xEF)
  • システム・コモン・メッセージおよびシステム・リアルタイム・メッセージ
    (0xF0 〜 0xFF)

については区別する必要があります。
チャネル・メッセージにはステータス・バイト中にチャネル番号を指定するフィールドを持ち、チャネル番号書き換えの対象になります。
一方、システム・メッセージにはチャネルの概念はなく、「ブロードキャスト・メッセージ」の性格を持ち、チャネル番号書き換えの対象にはなりません。
MIDI メッセージは、b7 に「1」が立っている「ステータス・バイト」を先頭として、その後に b7 が「0」である「データ・バイト」が (もしあれば) 続く構成となっています。
MIDI メッセージの「分配先」は、先頭のステータス・バイトの出現時に決定され、その後のデータ・バイトではステータス・バイトの時に決められた値をそのまま使います。
つまり、データ・バイトに関しては、特に「処理」は必要ありません。
チャネル・メッセージのチャネル番号書き換え (リマッピング) については、書き換えチャネル番号テーブル (remap_tab[])

//
// MIDI channel remapping table in RAM
//
uint8_t remap_tab[16] = {
	0,  // ch 1 (1 origin)
	0,  // ch 2
	0,  // ch 3
	0,  // ch 4
	0,  // ch 5
	0,  // ch 6
	0,  // ch 7
	0,  // ch 8
	0,  // ch 9
	9,  // ch 10 (drum channel), no remap
	0,  // ch 11
	11, // ch 12, no remap
	12, // ch 13, no remap
	13, // ch 14, no remap
	14, // ch 15, no remap
	15  // ch 16, no remap
}; // uint8_t remap_tab[]

を用意して (常に) 書き換えます。
MIDI チャネルについては、一般的な表記では「1」から始まるものとして、1 〜 16 と表しますが、上の表では、ステータス・バイトのチャネル番号フィールドに現れる「0」始まりの 0 〜 15 で表現しています。 (配列のインデクスおよび値の両方で)
したがって、テーブルのエントリが「0」となっていれば、そのチャネル番号は一般的な表記での MIDI 1 チャネルに書き換えられることになります。
また、テーブルのエントリの値がインデクスの値と同じ場合には、「書き換え後」のチャネル番号が「書き換え前」のチャネル番号と同じということですから、結局「書き換えない」のと同じことになります。
上のテーブルの例では、チャネル 10 を除き、チャネル 1 〜 11 までをチャネル 1 に書き換えています。
チャネル 10 は、通常、ドラム・チャネルとして「決め打ち」になっていますから、チャネル番号を変更してしまうと不都合が生じます。
チャネル 12 〜 16 および 10 は「書き換えない」のと同じになります。
ステータス・バイトの出現時に決定する必要がある「分配先」について、チャネル・メッセージに対しては次のようなテーブル (mask_tab[]) を用意しています。

//
// ch. no. to port mask pattern table in RAM
// port bitmap assignment:
// b15 = port16, ... , b1 = port2, b0 = port1
//
uint16_t mask_tab[16] = {
	0x0001, // ch 1  --> port 1
	0x0002, // ch 2  --> port 2
	0x0004, // ch 3  --> port 3
	0x0008, // ch 4  --> port 4
	0x0010, // ch 5  --> port 5
	0x0020, // ch 6  --> port 6
	0x0040, // ch 7  --> port 7
	0x0080, // ch 8  --> port 8
	0x0100, // ch 9  --> port 9
	0xffff, // ch 10 --> all port (broadcast drum ch) 
	0x0200, // ch 11 --> port 11
	0x0200, // ch 12 --> port 11
	0x0200, // ch 13 --> port 11
	0x0200, // ch 14 --> port 11
	0x0200, // ch 15 --> port 11
	0x0200  // ch 16 --> port 11
}; // uint16_t mask_tab[]

これは、(書き換え前の) MIDI チャネルをインデクスとするテーブルで、その値は分配先の MIDI 出力ポートのビットマップで構成されています。
それぞれ、

  • 出力ポート 1 は b0
  • 出力ポート 2 は b1
    ...
  • 出力ポート 16 は b15

となっています。
そのビットに「1」が立っていれば、そのチャネルのチャネル・メッセージをその出力ポートへ「通過」させることを示し、そのビットが「0」ならば、そのチャネル・メッセージは「遮断」することを表しています。
上のテーブルの例では、

  • MIDI チャネル 1 〜 9 までは、それぞれ同じ番号のポートへ出力
  • MIDI チャネル 10 に関しては、すべての出力ポートに同時に出力
  • MIDI チャネル 11 〜 16 までは、すべて出力ポート 11 に出力

ということになります。
前に示したチャネル書き換えテーブル (remap_tab[]) の効果と合わせると、チャネル・メッセージは、

  • MIDI チャネル 1 〜 9 までは、同じ番号の出力ポートへチャネル番号を 1 に書き換えた上で出力 (ムライボックス仕様)
  • MIDI チャネル 10 はすべての出力ポートへ出力 (ドラム・チャネル、ブロードキャスト
  • MIDI チャネル 11 〜 16 までは、出力ポート 11 へ出力し、その際、チャネル 11 のみチャネル番号を 1 に書き換える

処理が行なわれます。
次回は、システム・リアルタイム・メッセージ / システム・コモン・メッセージについて触れます。