Maix Bit と 6 + 1 マイクロフォンアレイで音源可視化 

#1.長めの前置き
最近とてもよさげな音源定位、可視化システムを見かけました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">[音の可視化事例] 防音パネル設置効果可視化 <a href="https://t.co/ic1ktrUiXB">https://t.co/ic1ktrUiXB</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>より</p>&mdash; AIRPOCKET＠rastaman vibration (@AirpocketRobot) <a href="https://twitter.com/AirpocketRobot/status/1339749285416472579?ref_src=twsrc%5Etfw">December 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
以前から、マイクロフォンアレイで音源定位とか可視化をやってるのは知っていましたが（昔見たのは[こんなやつ](https://www.onosokki.co.jp/HP-WK/products/application/beamforming.htm)）、いつの間にやらスマートスピーカーの[音声認識精度をあげるための音声ビームフォーミング](https://www.toshiba.co.jp/tech/review/2004/09/59_09pdf/a10.pdf)などに実用化されています。

スマートスピーカーにはあまり興味が惹かれないのですが、音源定位と可視化については興味があります。
工場の中を歩いていると聞こえてくる、高圧エアのリーク音。漏れているのはわかっても、どこから漏れているのか探すのに苦労することも。そんな時、音源が可視化できれば簡単にエア漏れ箇所を特定し修復できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/153171ac-eaca-e0bd-3431-37af984481f6.png)

これは日本音響エンジニアリング株式会社のSoundGraphyという製品で、コンパクトで使いやすそうで見た目もかわいい（見た目大事）ためついつい欲しくなったのですが、価格がかわいらしくなかったので諦めました（[豊通定価で275万円](https://engineering.ttsystems.com/wp-content/uploads/2019/06/26f80307476d5589b72a1071c9f29ee2.pdf)）。
設備保全の豆知識では[φ１の穴からエア漏れすると年間90,000円のロスになる](http://musashi-kai.jp/PDF/air01_20111104.pdf)ということで、31か所の穴をふさげば1年で元が取れる計算です。とは言え、この機械がなくても頑張って穴を探してふさぐわけなので効果としてはφ１の穴探しの時間短縮の工賃のみ。これではさすがに稟議も通りそうにありません。そもそも設備管理担当でもないので購入権もないのですが。。。

というわけで、~~死蔵~~大事に保管していたMaix Bitを引っ張り出した際に再発見した、~~買ったことすら忘れていた~~いつか活躍してもらおうと思っていたマイクロフォンアレイの登場となります。

この記事は[前回](https://qiita.com/airpocket/items/c5921195384d3f16d357)に引き続き[Seeed UG Advent Calendar 2020](https://qiita.com/advent-calendar/2020/seeed_ug)にエントリーさせていただきました。

#2やりたいことと使ったもの
##2-1.やりたいこと
Maix Bitと6+1マイクロフォンアレイで、音源の可視化を行います。

##2-2.つかったもの
###・Maix Bit
今更説明不要のマシンビジョンとマシンヒアリングがお手軽に楽しめるkendryte K210搭載の開発ボードです。
前回はまがりなりにも画像処理に用いたので、今回は音声処理に利用してみます。
写真は[前回会社に供出した](https://qiita.com/airpocket/items/c5921195384d3f16d357)あとに、新たに買いなおしてもらった新品です。
![DSC_2315.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/9f91583a-a22d-d096-e869-9182dc246fd6.jpeg)
Maix BitはMaix兄弟の中でも小柄なボードのわりに引き出されているPIN数も多く、フルサイズのOV2640が、黒光りしつついきり立ってとても~~ジャマな~~かっこいいフォルムです。弱点はアナログ入力が無いのと無線がついてないくらいですが、技適は通ってないもののmicro SDスロットにさすESP32モジュールも発売されていますので、そちらを差し込めばADCもつかえるんじゃないかな。技適通ってないけど。
![DSC_2324.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/c94d5d6d-185d-9817-1532-864c2c0ea9ce.jpeg)
###・6+1マイクロフォンアレイ
何が6+1かというとマイクロフォンアレイの数です。六角形の各頂点と中心に合計７個のmemsマイクを搭載しています。これらのマイクに入ってきた音を解析して、時間差から音源の方位を確定している様ですね。
また、RGBLEDが全周に12個配置されていて音源方向のインジケーターとして利用できます。
基板中央には0.5㎜ピッチ10PINのフラットケーブルと、背面に抜けるIOの表示があります。10PINのフラットケーブルはどこで使うんでしょう？ Maix Bit、M1N、dockにはコネクタついてないですが。。。今回はQIコネクタを使用します。
![DSC_2306_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/af1dc7cc-d361-496d-19a2-80d380ba344e.jpeg)
背面には2×5のQI2550メスコネクタが生えてますがPIN番号等の表記なし。PINのラベルはコネクタの出てない表じゃなくて裏側に印刷すべきだと思います。
あとコネクタは基板に垂直に出すと嵩張るので、できれば写真下方向あたりに90°曲げて出してほしかった。~~真鍮のスペーサネジが付属で付いてきたけど、コネクタ挿したらどう考えても長さが足りないぞ。~~（長さは足りました。ごめんなさい）

#3.さっさとコーディング
##3-1.の前にケーブル接続
ケーブル接続したいけどマニュアルが少ないので右往左往します。回路図も役に立たないとは言いませんが、それよりライブラリのドキュメントが欲しいです。
ようやく[demoっぽいもの](https://github.com/chegewara/sipeed-maixduino-test-apps/blob/master/platformIO/MaixPy/mic-array.py)を発見したので参考に結線。

このコードはMaixduino向けの様ですが、fpioで好きにfunctionを振りなおせるはずなのでノリで接続。下表の通りにつなぎます。Maix Bit側は基板のPIN番号表記です。残り8本はともかくLED_CKとLED_DAはコードからも役割が分からないんですが1/2の確率なのでエイヤでつないで正解でした。

|Maix Bit|6+1 mic|
|--------|-------|
|PIN23|MIC_D0|
|PIN22|MIC_D1|
|PIN21|MIC_D2|
|PIN20|MIC_D3|
|PIN19|MIC_WS|
|PIN18|MIC_BCK|
|PIN17|LED_CK|
|PIN15|LED_DA|
|3V3|VIN|
|GND|GND|

##3-2.Maix Bit用のコード
ファームのバージョンにより動作が変わってしまいます。
今回は2020/12/17時点で最新の[maixpy_v0.6_9_g88bfd0177.bin](https://dl.sipeed.com/MAIX/MaixPy/release/master/)で動かします。
[kflashで書き込みましょう。](http://www.pwv.co.jp/~take/TakeWiki/index.php?Arduino%E5%8B%89%E5%BC%B7%E4%BC%9A%2F30-MaixPy)

```python
from Maix import MIC_ARRAY as mic  #MIC_ARRAYのライブラリ、enにもzhにもdocが無いよー(TT)
from Maix import FPIOA
from fpioa_manager import fm       #相変わらず理解しきれていないfpioa
import lcd

from Maix import utils       #heap mem使用量確認及び設定用
utils.gc_heap_size(1000000)  #heap mem確保量の設定、絶賛増量中。3000000まではいけた。
                             #4000000ではアウトらしい、文鎮化したら復旧が面倒くさそうなので要注意。

lcd.init()
mic.init()
Fpioa = FPIOA()

# reconfigure pins after mic.init() to match your wiring
Fpioa.set_function(23, fm.fpioa.I2S0_IN_D0);
Fpioa.set_function(22, fm.fpioa.I2S0_IN_D1);
Fpioa.set_function(21, fm.fpioa.I2S0_IN_D2);
Fpioa.set_function(20, fm.fpioa.I2S0_IN_D3);
Fpioa.set_function(19, fm.fpioa.I2S0_WS);
Fpioa.set_function(18, fm.fpioa.I2S0_SCLK);
Fpioa.set_function(17, fm.fpioa.GPIOHS28);
Fpioa.set_function(15, fm.fpioa.GPIOHS27);

while True:
    imga = mic.get_map()         #mic arrayから16x16pixelの音源マップを取得してるらしい
    dir = mic.get_dir(imga)      #音源マップから音の方向を計算してるんだろう
    mic.set_led(dir,(50,50,50))  #音源方向のLEDを点灯。まぶしいので(0,0,0)でLEDオフしよう。
    imgb = imga.resize(240,240)  #16×16のマップをLCDサイズに合わせて 240×240に拡大。
    imgc = imgb.to_rainbow(1)    #グレースケールだと寂しいのでそれっぽいレインボーカラーに変換

    lcd.display(imgc)

mic.deinit()
```
発生条件が確定できていませんが、heap memoryが足りなくなる時があったので増量しています。

#4.動作確認
とりあえず動くとこまでは達成。
意外といい感じ。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Maix Bitで音源定位 <a href="https://t.co/zi8CuTeolR">pic.twitter.com/zi8CuTeolR</a></p>&mdash; AIRPOCKET＠rastaman vibration (@AirpocketRobot) <a href="https://twitter.com/AirpocketRobot/status/1339823129275711488?ref_src=twsrc%5Etfw">December 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

暗くて見にくいですがこんな構成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/7dca3331-88a7-d4b7-f446-1c5c7096eb3c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/c7d8ffda-c21d-cbbd-c8e4-a8fc4e8a5ab5.png)




##4-1.残課題
###・本当はこれにカメラ画像を重ねるのが理想
たぶんできるんじゃないかと思いますが、カメラの画像と音源位置を重ねるためには、画角と、マイクとカメラのセンター軸を合わせる必要があります。
マイクアレイの中心にもマイクがあるので、センター軸がずれるのは避けられません。近距離では位置ずれが目立つでしょう。
また、音源マップの画角はかなりの広角っぽいので、カメラ側にも広角レンズを乗せる必要があるでしょう。また微調整するためには音源マップ側の表示位置計算を調整してやる必要がありそうですが、ちょっと手に負えないかな？

###・感度調節したい
けっこう小さな音から拾っていて、ダイナミックレンジがかなり狭い印象です。これもゲインとか閾値とか調節したいところですが、ライブラリのドキュメントが無いので機能があるのかないのかさえ分からず。ファームを覗けばわかるんだろうけどこれも少々~~めんどくさい~~荷が重い。

###・周波数選択したい
K210はFFTが大得意なはずなので周波数分解して周波数識別したうえで音源特定できそうな、できなさそうな。

#5.まとめ
前回Maixpyを触ったばかりということもあって、特にハマりもせず動作までもっていけたので楽しかったです。
もう少し完成度を高めれば仕事にも役に立つ気もしなくもなくもない。。。かもしれない。
可能性は感じますが、数学及びコーディングスキルが足りないのが勿体ないです。
とりあえず、カメラ画像との重ね合わせ表示にはトライしてみます。

追記：[完成版はこちら](https://qiita.com/airpocket/items/7d91976fb3732625bf85)

###蛇足
今年はK510の年だって聞いてたし、年末にはさすがに出るだろうって聞いてたんだけどまだなのかな。
パワーアップはうれしいけど、あまり値段上げないでほしいな。遊びにくくなる。