USB-MIDI (13)

今回は USB-MIDI コンバータの MIDI IN 側の処理の話です。
MIDI OUT 側に比べて処理は複雑になります。 それは、

  • ランニング・ステータスに必ず対応する必要がある
  • 入力される MIDI メッセージに対応して MIDI パケットを組み立てる必要がある
  • USB ホスト側から要求がある場合にしかデバイス側からホスト側にデータを送れない

という特性によるものです。
ケーブル・ナンバー処理を除き、MIDI 入力から IN エンドポイントまでの処理のブロック・ダイアグラムを下に示します。

メインの処理の流れではランニング・ステータス処理をして 1 〜 3 バイトの「完全」な MIDI メッセージに戻してから 4 バイトの MIDI パケットを組み立てるように書いてありますが、必ずしもそうする必要はありません。
図で破線で囲った部分をひとつのステート・マシンで実現し、入力 MIDI メッセージを「不完全」なまま扱って MIDI パケットを組み立てるようにしても構いません。
以前にも述べたように、ステータス・バイトが 0xF8 〜 0xFF の 1 バイトからなる「システム・リアルタイム・メッセージ」が入力された場合、バイパス処理というか、エスケープ処理というか、割り込み処理というか、現在組み立て処理中の MIDI パケットを一時保留しておいて、CIN = 0x0F の MIDI パケットを作成し、先に IN エンドポイントへ送りだします。
ステータス・バイト 0xF0 に始まり 0xF7 に終わるシステム・エクスクルーシブ・メッセージについては、いつ終端の 0xF7 が来るかわからないので、0xF0 のステータス・バイトが来たら「エクスクルーシブ処理モード」に入り、始端 / 中間部を表す CIN = 0x04 を付加して、続くデータ・バイトのエンコードおよび完成したバケットの送出を繰り返します。
終端である 0xF7 を見つけたら、パケット内の位置により CIN = 0x05、0x06、0x07 のいずれかに「看板」を掛け替えて MIDI パケットを完成させ IN エンドポイント側に送出し、エクスクルーシブ・モードから抜けます。
USB-MIDI イベント・パケットの定義では、格納される MIDI メッセージにエラーがないことが前提となっています。 エラーを含む MIDI メッセージを伝達することは意図していません。
実際の MIDI 信号ではエラーが存在することが考えられるので、その対策に関して考慮しておく必要があります。
固定長の 2 〜 3 バイトの MIDI メッセージに対しては、特に対策しなくてもエラーのあるデータに対しては MIDI パケットが送出されることはありません。
たとえば、ランニング・ステータスが許される 3 バイトのシーケンスで、ステータス・バイトが省略されていて、第 1 データ・バイトまで受信した後で、第 2 データ・バイトではなく別のステータス・バイトを受信した場合、第 2 データ・バイトが不明となるので、これはエラーになります。
MIDI パケット組み立てのプロセスでは、完成したパケットが送出されるのは第 2 データ・バイトを受信した後であり、別のステータス・バイトを受信した時点ではまだパケットの送出はありません。
別のステータス・バイトの受信により、別のメッセージ・シーケンスが開始されるので、組み立て途中の不完全なパケットの上に新しいメッセージ・シーケンスのデータが上書きされ、実質的には捨てられることになるので、エラーのあるパケットが送出されることはありません。
また、ランニング・ステータスが許されないメッセージ・シーケンスで、ステータス・バイトなしでデータ・バイトが続く場合には、単にそれらのデータ・バイトは有効なステータス・バイトが現れるまで読み飛ばされるので、エラーのある MIDI パケットとしてエンコードされることはありません。
唯一問題となるのが、終端の 0xF7 が欠けたシステム・エクスクルーシブ・メッセージです。
この「終端の 0xF7 が欠けている」ということが判明するのは、データ・バイトの連続の後に、システム・リアルタイム・メッセージ (0xF8 〜 0xFF) を除く、他のステータス・バイトが出現した場合です。
MIDI 規格上は、これはエラーではないのですが、現在の MIDI 機器では 0xF0 - 0xF7 の対応が取れていないシステム・エクスクルーシブ・メッセージはエラーと見なして無視するようになっています。
MIDI パケットのエンコーディングでは終端の 0xF7 を見つけて CIN を変化させるので、対策をしないと終端のない CIN = 0x04 のパケットしか送出されないことになります。
終端が欠けるということは、途中のデータも欠けている可能性があり、メッセージ全体として正しくない可能性がありますが、少なくとも 0xF0 - 0xF7 の対応を付けるという意味で、欠けた 0xF7 を補って終端の MIDI パケットを完成させることも考えられます。
このパケットを受け取るホスト PC のアプリケーション側の振る舞いを調べていないので分かりませんが、終端のパケットなしでもシステム・エクスクルーシブ・メッセージのエラーと認識して破棄してくれて、他のメッセージに影響がなければ、デバイス側では対策しなくて済みます。