USB-MIDIデバイスを作る時に気づいたこと
USB-MIDIデバイスを作るのに一部制限があることが判明。
前回の日記『USB機器を作りたい その2』で
『Cで簡単に開発出来るようにUSBフレームワークもフルスクラッチしちゃおうかと思ってます』
と書いてましたが、以前にアセンブラで書いたUSB機器のソースを見てるととてもフルスクラッチする気になれずMicrochip Libraries for Applications(以下mla)のフレームワークを使うことにしました。
USB-MIDI機器を作りたいのでpic18f46j50のデモプロジェクトを丸1日掛けていじって18f2450を使った自前のUSB開発ボードで動かすことに成功。
一部ライブラリを書き換える必要はあったんですが、ココに書くのは面倒なので省略ということで。
さてここから本題。
パソコンからUSB-MIDIデバイスを通じてMIDI機器を鳴らしたいので、それを作ります。
MIDI-INを使う予定は無いのでMIDI-OUTのみ。
USBデバイスがどんなデバイスかを定義しているDevice DescriptorとConfiguration DescriptorはUSB-MIDIの規格書に書いてる例文から拝借します。
ただし、そのまま拝借するとMIDI-IN/OUTが1ずつある一般的なUSB-MIDI機器となるので、MIDI-OUTの1つだけになるように書き換えます。
『usb.org midi』で検索すると規格書が見つかりますが英語です。
ありがたいことに例文を日本語で細かく説明してくださっているサイトがあるのでそちらもぜひ見てください。私もお世話になりました。
まずは規格書に書いてる例文を使ってUSB-MIDIデバイスとして認識させテスト。
Linux・Android・Windowsでは問題なく動作。シーケンサーからノートナンバー0x90、0x80や0xFAや0xFCなどもPICへ送信されてることを確認。
そして例題をいじってMIDI-OUTのみ実装。
ここで問題発生。
開発環境はLinux(ディストリビューションはxubuntu)なのでLinuxでデバッグとテストをするとMIDI-OUTのみキチンと表示されノートナンバーも問題なく送信されます。
AndroidではMIDIデバイスとして認識され、シーケンサーアプリからMIDI-OUTのみ表示されるが、この項目を選択するとどのシーケンサーもフリーズしてしまい強制終了となってしまう。つまり使えない。
ロジックアナライザでUSBの通信内容をキャプチャするとUSBデバイスのエニュメレーションが終わった後はPID_OUTもINも送信されなくなることが判明。
WindowsXPでは標準MIDIデバイスとして認識されるがシーケンサーには表示されないため、
MIDI-OUTに関するディスクリプタを残したままMIDI-OUTジャック数を0にするとMIDI-OUTのみ表示される。
しかし、ノートナンバーを送信しても反応せず、ロジックアナライザでUSBの通信内容をキャプチャするとUSBホストからPID_OUT自体送信されていないことが判明。つまり使えない。
そのうえ『USB』とだけ書いたデバイスが表示されてしまう・・・。
Macは持ってないのでわからないけど、AndroidとWindowsと同じような結果になりそう・・・。
つまり、ほとんどのOSではUSB-MIDIの規格書の例文と同じDescriptorにしないと正常に動作しないっぽいのです。
一般的なOSで沢山テストしてみないと結果はわからないけど、上に書いた通りの結果になりそう。
この結果を裏付ける証拠としては、
ヤマハやローランドやコルグのMIDIキーボードのほとんどが専用ドライバが必要で、
標準ドライバで動くモノは製品的にMIDI-IN/OUTのどちらかの機能しか付いていないのに関わらず両方積んでいるような表示になっています。
もしUSB-MIDI Device Descriptorの書き方が知りたくてこのページに来た方が居たら
『ちっ、肝心のDescriptorが書いてねーじゃん』
って思われるでしょうが、
規格書の例文をいじるとまともに認識・動作しなくなる可能性が高いので例文のまま使ったほうがいいですよ☆
0コメント