ESP32でWifi Sniffingした値をBLE MIDIしてみる！

#作りたかったもの
ESP32でWifiをSniffingして、それを音（MIDI）に変換してみたい。
音はBLEで飛ばしてみたい。
イメージ
![BLE_MIDI.png](https://qiita-image-store.s3.amazonaws.com/0/248870/4f76c496-ed57-26b0-e157-114f72e53e75.png)


#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
構成としては下記のようなイメージ。
![BLE_MIDI_2.png](https://qiita-image-store.s3.amazonaws.com/0/248870/7a99cd80-4b7c-44d2-0b2c-54888116711a.png)

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に移植したソースになっていたので、
大きな変更は不要かと思いましたが、２点だけ注意必要でした。

**①sdkconfigファイルの修正**
BLE関連の記載が必要だったので、以下のようにしました。

```ruby:sdkconfig
#
# 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のソースの中で１箇所、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の呼び出しの３回に一回鳴らすようにしました。
また、前回と同じ音が鳴っても面白くないかなと思い、同じ数値だった場合は＋１してみます。
この辺は思いつきで実装してます。

変数の定義は下記。

```
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情報への変換の調整が必要。