Publish 2021.03.05
arudinoとか電子ドラム関連の情報を公開してると、「こういうことができないか?」ってメールが来たりします。今回はESP32でBLEMIDIを使ってMIDI信号受信したいんだけどサンプルも見つからないから助けてくれないかってメールでした。
言われてみるとMIDI信号の送信ばっかりやってたけど受信ってどんな感じで扱うのかなーと気になってきたので実際に試してみました。
使うのは以前も使ったArduino-BLE-MIDIライブラリです。このライブラリ、定番のArduino MIDIライブラリとほぼ同じコードでBLEMIDIを扱うことが出来て最高なんですが、あまり使用例を見かけません。そもそもMIDIってそんなに需要ないのかな...
とにかく、Arduino-BLE-MIDIライブラリの使用例が見つからなくても普通にMIDIライブラリで使用している例があれば、そのままBLEMIDIで使えるという訳です。MIDI信号の受信についてはMIDIライブラリのサンプルコードが参考になります。
void loop(){
if (MIDI.read()){ // MIDI信号を受信したかどうかチェック
switch(MIDI.getType()){// MIDI信号の種類をチェック
case midi::ProgramChange: //MIDI信号がProgram Changeかどうかチェック
doSomething(); // ここにやりたいことをいれる
break;
}
}
}
ちょっと変えてますが、loop内のみ抜粋してます。
このコードにあるように、loop内のMIDI.read()でMIDI信号が来たかどうか判別出来ます。
もちろん来たかどうかだけでなく、MIDI信号の内容で場合分けが出来ます。MIDI.getType()でswitch
case文を作ることでnoteOnやPitchBendなどの判別をします。noteOnの場合はcase midi::NoteOn:とします。
もちろん、ベロシティなどの値も読めます。
void loop() {
uint8_t data1;
uint8_t data2;
if (MIDI.read()) { //MIDI信号を受信したかどうかチェック
switch (MIDI.getType()) {
case midi::NoteOn://MIDI信号がNoteOnの場合
data1 = MIDI.getData1(); //ノート番号を取得
data2 = MIDI.getData2(); //ベロシティを取得
Serial.print(NoteNum :);
Serial.print(data1);
Serial.print(, Velocity :);
Serial.println(data2);
break;
}
}
}
getData1()、getData2()を使うことでMIDI信号の値を取得出来ます。簡単だし便利ですね。
さて、本題のBLEMIDIです。
上のコードはMIDIライブラリ用のサンプルコードを改変したものですが、前述のようにBLE-MIDIライブラリでもそのまま使用出来ます。LEDを光らせるサンプルコードを作ってみました。
ノートオンを受け取って、ノート番号が60より大きければ12番ピンをHIGH、60以下なら14番ピンをHIGHにするだけのシンプルなコードです。
載せるようなもんじゃないですが回路はこんな感じで試しました。本当はLEDに抵抗かませた方が良いでしょう。
動作動画はこちら。
めちゃくちゃあっさり動いてくれました。そして反応速い。
便利なライブラリを公開してくれてる人に感謝します。
初めてMIDIの受信をやってみましたが、BLEでもコードは短いし詰まることなく難なく実装出来ました。そして遅延の少なさにはびっくりです。無線で通信したい時って、普通はOSCとか使うんでしょうけど少ない情報量で済むならBLEMIDIもありかもしれませんね。