![見出し画像](https://assets.st-note.com/production/uploads/images/145275234/rectangle_large_type_2_43f26eba88cabc5903956104cbb4847e.png?width=800)
Event PacketsさえわかればUSB-MIDIを攻略できるはず
以前、USB Hostを使ったライトを作ったとき、USB-MIDIを使ったが、駆け足すぎたので、今回、改めて、USB-MIDIのデータフォーマットの理解を深める
https://www.usb.org/ で MIDI を検索すると、1.0と2.0の資料がみつかる
Ver. 1.0と2.0があるが、直近で必要そうなのは、USB MIDI1.0だと思われるので、Universal Serial Bus Device Class Definition for MIDI Devices 1.0 Nov 1, 1999の4章のイベントパケットだけを今回は読む
本当は通して読んだ方がよいのだろうが、データフォーマットがわかれば、とりあえずやりたいことはできそうと推測して
困ったときに、資料を読み直すという戦略でいく
資料
USB-MIDI Ver.1.0の資料
今回、読んだ資料は以下
https://www.usb.org/sites/default/files/midi10.pdf
USB-MIDI Ver.2.0の資料
https://www.usb.org/sites/default/files/USB MIDI v2_0.pdf
その他
https://midi.org/ にもMIDI関連の資料がありそうだが、メンバーにならないと見れないようだ
資料の意訳
「4 USB-MIDI Event Packets」をかなり意訳する(直訳は、自動翻訳に任せた、直訳が好きな方は本記事は向いていない)
イベントパケットの構成
![](https://assets.st-note.com/img/1719395512855-0lnEgBLeee.png?width=800)
MIDI data is transferred over USB using 32-bit USB-MIDI Event Packets. These packets provide an efficient method to transfer multiple MIDI streams with fixed length messages.
MIDIデータは、32ビット(4バイト)固定長で送信される
The 32-bit USB-MIDI Event Packet allows multiple "virtual MIDI cables" routed over the same USB endpoint. This approach minimizes the number of required endpoints.
同じUSBのエンドポイントで複数の仮想MIDIケーブルを扱える仕様がある
It also makes parsing MIDI events easier by packetizing the separate bytes of a MIDI event into one parsed USB-MIDI event.
パケット化することで、MIDIイベントのパースを楽にしている(本意を把握できていないが、1つのUSB-MIDIイベントを1つのパケットにして、パースを楽にしている、と理解した)
The first byte in each 32-bit USB-MIDI Event Packet is a Packet Header contains a Cable Number (4 bits) followed by a Code Index Number (4 bits).
4バイトのうち、最初の1バイト目は、ケーブル番号(仮想MIDIのケーブル番号)とコードインデックス番号(メッセージのカテゴリのID、ノートオン、ノートオフなどを分別、と理解すればよいだろう)が含まれる
The remaining three bytes contain the actual MIDI event. Most typical parsed MIDI events are two or three bytes in length. Unused bytes must be padded with zeros (in the case of a one- or two-byte MIDI event) to preserve the 32-bit fixed length of the USB-MIDI Event Packet. They are reserved for future use. Figure 8 illustrates the layout of the packet.
残りの3バイト、実際のMIDIイベントの内容
1バイトと2バイトのデータのMIDIイベントの使わないバイトはゼロで埋める
(多くは、2バイト、もしくは3バイトのパケット)
SysExはどうなるの?と疑問に思うが、後を読むとわかる
The Cable Number (CN) is a value ranging from 0x0 to 0xF indicating the number assignment of the Embedded MIDI Jack associated with the endpoint that is transferring the data. The Code Index Number (CIN) indicates the classification of the bytes in the MIDI_x fields. The following table summarizes these classifications.
ケーブル番号(CN)は、0~15まで。
コード番号(CIN)は、クラス(カテゴリ)を表す
CINのカテゴリの分別は次に示す
「CN」と「CIN」と似てるので混同しないように注意
ケーブル1本想定の場合、CNは無視してもよいはず
CINの0~Fのみを意識すればよさそう
CINの値
![](https://assets.st-note.com/img/1719395679894-sgiR6G8vgR.png?width=800)
![](https://assets.st-note.com/img/1719395684172-JWqrn3Bt0u.png?width=800)
個人的に重要なCIN
0x2: MTC(MIDIのタイムコード)
0x4: SysEx starts or continues(システムエクスクルーシブメッセージの開始と途中)
0x5: SysEx ends with following single byte.(システムエクスクルーシブメッセージの終了)
0x6: SysEx ends with following two bytes(システムエクスクルーシブメッセージの終了)
0x7: SysEx ends with following three bytes.(システムエクスクルーシブメッセージの終了)
0x8: Note-off(ノートオフ)
0x9: Note-on(ノートオン)
0xB: Control Change(コントロールチェンジ)
0xC: Program Change(プログラムチェンジ)
0xE: PitchBend Change(ピッチベンドチェンジ)
SysExについて補足
SysExは、継続するか、終了するかでCINが変わる(パースがかなり楽!)
次のパケットに続く場合は4で、このパケットで終わる場合は、5,6,7のうちのどれか(残りのバイト数によって異なる)
実際のパケットイベントの例
ノートオン
USB-MIDI Packet
19 9n kk vv
MIDIの場合
9n kk vv
ケーブル番号:1
CIN:9(ノートオンというクラス)
9がノートオン(MIDIメッセージとしてのノートオンを示す)
nがチャンネル番号
kkがキー(音の高さ)
vvがベロシティ(音の大きさ)
システムエクスクルーシブの実際のデータの例
ケーブルはp(pは無視してよい)
SysExを4バイト送る場合
1番目でp4で開始して3バイト送る
2番目でp5で終了して1バイト送って、2バイトをゼロ埋めする
「F0 00 01 F7」は「p4 F0 00 01」「p5 F7 00 00」の2つのパケットになる
SysExを5バイト送る場合
1番目でp4で開始して3バイト送る
2番目でp5で終了して2バイト送って、1バイトをゼロ埋めする
「F0 00 01 02 F7」は「p4 F0 00 01」「p5 F7 00 00」の2つのパケットになる
SysExを6バイト送る場合
1番目でp4で開始して3バイト送る
2番目でp5で終了して3バイト送る
「F0 00 01 02 03 F7 」は「p4 F0 00 01」「p7 02 03 F7」の2つのパケットになる
SysExを2バイト送る
「F0 F7」は 「p6 F0 F7 00」の1つのパケットになる
SysExを3バイト送る
「F0 mm F7」は「p7 F0 mm F7」の1つのパケットになる
その他の例
![](https://assets.st-note.com/img/1719395908845-lkvEP6HCpA.png?width=800)
感想
4バイト固定長なのは、パースが楽だ
最初のバイトのCINだけみて、不要なパケットは簡単に除外できそうだ
MIDIのラーニングステータスは、パース泣かせな仕様と感じる
もちろん遅い転送速度を補うために、データ数を減らすという工夫だと思うのだが
ラーニングステータスという特別な仕様の存在を知ると、他にも特別な仕様があるかもしれない、と考えてしまう
つまり、すべての仕様を把握しないと安心できない感がある
4バイト固定で、先頭のバイトを見れば、データの全容が把握できるという仕様は、非常にありがたい
とはいえ、USB-MIDI Ver.2では、4バイト固定ではないようだ
大きなデータを送信するときは、非効率感が否めないかもしれない
この記事が気に入ったらサポートをしてみませんか?