#作りたかったもの
ESP32でWifiをSniffingして、それを音(MIDI)に変換してみたい。
音はBLEで飛ばしてみたい。
イメージ
#ESP32の環境構築
まずはESP32のセットアップから。
今回、Arduinoもidfも使用したので、それぞれ下記を参考にさせていただき、セットアップしました。
Arduino
ESP32(ESP-WROOM-32)でLチカ (WindowsでArduino IDE使用)
https://qiita.com/rukihena/items/6a904368700eb1c7d2a3
idf
ESP32(ESP-WROOM-32)でLチカ (WindowsでESP-IDF使用)
https://qiita.com/rukihena/items/d226972972a360fc2648
#ESP32でBLE MIDI
構成としては下記のようなイメージ。
ESP32-----------MIDI device(今回はスマホ)
Peripheral-------Central
MIDI out-------MIDI in
スマホのアプリには、下記を利用。
BLE MIDI Sample App
https://play.google.com/store/apps/details?id=jp.kshoji.blemidi.sample
ESP32でBLE MIDIの先駆者を調査したところ、Arduino環境ですでに挑戦している方がいました。
BLE_MIDI example for the ESP32 Arduino core
https://github.com/neilbags/arduino-esp32-BLE-MIDI
ここで利用するBLEのライブラリの導入は下記を参考にさせていただきました。
Arduino IDEでESP32 BLEライブラリを導入
https://qiita.com/tomorrow56/items/afa06e206eec9fafcc7a
そのままソースを落として試しましたが。。なぜか音鳴らず。。
いろいろ試しましたが上記をベースにしても駄目だったので別の参考に出来るソースを探してみることに。
結果、以下を参考にできそうでした。
WiFiBoy32 + WB32-SFX BLE-MIDI 數位音源實驗成功!
https://wifiboy.club/topic/12/wifiboy32-wb32-sfx-ble-midi-%E6%95%B8%E4%BD%8D%E9%9F%B3%E6%BA%90%E5%AF%A6%E9%A9%97%E6%88%90%E5%8A%9F
ちょっとソース見た感じ、idfのライブラリをArduino環境に移して実現しているようでした。
このままのソースだとWiFiBoy32のライブラリがないのでビルド通らず。
それっぽいものをコメントアウトし、最終的にこうなりました。
https://github.com/hidekazu3284/ble_midi
スマホで音が鳴ることも確認しました。
#ESP32でWifi Sniffing
すでにソースはあるので、これをidf環境でビルドします。
ESP32-WiFi sniffer
http://blog.podkalicki.com/esp32-wifi-sniffer/
https://github.com/lpodkalicki/blog/tree/master/esp32/016_wifi_sniffer
#BLE MIDIとWifi Sniffingを合わせてみる
環境として、idf環境に統一します。なので、BLE MIDIのソースをidf環境に移行します。
→Wifi Sniffingがidf環境であること、BLE MIDIがidfのライブラリを利用していたのでそのようにしました。
BLE MIDIを移植する
BLE MIDIのソースは基本的にidf環境のライブラリをArduinoに移植したソースになっていたので、
大きな変更は不要かと思いましたが、2点だけ注意必要でした。
①sdkconfigファイルの修正
BLE関連の記載が必要だったので、以下のようにしました。
#
# Bluetooth
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0
CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y
CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4=
CONFIG_BLUEDROID_ENABLED=y
CONFIG_BLUEDROID_PINNED_TO_CORE=0
CONFIG_BTC_TASK_STACK_SIZE=3072
CONFIG_BLUEDROID_MEM_DEBUG=
CONFIG_CLASSIC_BT_ENABLED=
CONFIG_GATTS_ENABLE=y
CONFIG_GATTC_ENABLE=y
CONFIG_BLE_SMP_ENABLE=y
CONFIG_BT_STACK_NO_LOG=
CONFIG_BT_ACL_CONNECTIONS=4
CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=
CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=
CONFIG_SMP_ENABLE=y
CONFIG_BT_RESERVE_DRAM=0x10000
②btStart()の代替
BLE MIDIのソースの中で1箇所、Arduinoの処理を利用している箇所がありました。
btStart()
いろいろ調べた結果、以下のように代替することでidf環境に移行できました。
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
これで移植は完了です。
あとはWifi Sniffingの結果をどのようにBLE MIDIに反映させるかです。
ひとまず、MIDIのパケットの中のVelocityにWifi Sniffingで取得したRSSIの数値をそのまま突っ込んでみます。
毎度鳴らすと目まぐるしく音が変わるかなと思い、wifi_sniffer_packet_handlerの呼び出しの3回に一回鳴らすようにしました。
また、前回と同じ音が鳴っても面白くないかなと思い、同じ数値だった場合は+1してみます。
この辺は思いつきで実装してます。
変数の定義は下記。
uint8_t midi_count=0;
uint8_t pre_vel=0;
Wifi Sniffingの結果をBLE MIDIに反映させる処理は下記。
if (midi_count == 2){
mididata1[4]=ppkt->rx_ctrl.rssi;
if(mididata1[4]==pre_vel)
{
mididata1[4]++;
}
pre_vel=mididata1[4];
esp_ble_gatts_send_indicate(test_profile.gatts_if, test_profile.conn_id,
test_profile.chars[0].char_handle, sizeof(mididata1), mididata1, false);
midi_count = 0;
}
midi_count++;
完成したソースはgitにアップしてます。
https://github.com/hidekazu3284/wifi_sniffer_BLE_midi
#動作確認
ビロビロと不気味な音が鳴りました。
https://twitter.com/x_tsukumo/status/992240371458428928?s=19
#まとめ
・idf環境、Arduino環境の両方でBLE MIDI を実現しました。
・Wifi Sniffingの結果を使い、MIDIの音を出力しました。
・今後、BLEを安定させるための処理整形と
より音楽っぽくするためのsniffing結果のMIDI情報への変換の調整が必要。