Arduino で音認識プロジェクト12010/05/24 00:00

Arduinoで音認識を行う。

■プロジェクト概要
Arduinoで音を取得し、FFTで周波数解析する。事前に学習しておいた周波数成分を満たす場合は特定の音が発生したと評価し、シリアル経由でアラート信号を出す。
シリアル信号はXbee経由で別のArduino (FIO)へ連携される。FIO側はアラート信号を受けたら一定期間ブザーを鳴らし、LEDを点灯させる。比較用の周波数成分は学習する事ができる。

■具体的な使用想定
 2階でペットや赤ちゃんが鳴いたら(泣いたら)1階に居る人に知らせる
PJ概要図

■スケッチ
 以下の処理概要を考慮して作成したスケッチはこちら
■処理概要(Arduino 親機)
(1) 音データの取得
256個のサンプリング値をdelayなしで取得する。analogReadには約 100 μsの時間を要するので、これで間接的に10khzまでの音をサンプリングでき、約5khzまで周波数解析できる。周波数の分解能は39hzとなる。(100μs間隔はArduinoの性能の限界)
(2) 音データ解析
サンプリングした音のFFT結果を取得し、これを256個の変数として保持する。
※1回のFFTに要する処理時間は約13 ms
(3) 解析値の蓄積
(1)(2)の処理を10回行う。約0.5秒間に発生した音の解析ができる。
(25.6ms+13ms)×10 = 38.6 ms
(4) 学習モードの場合
 スイッチが押されたら学習モードにする。
 (3)の解析結果について、閾値を超えた周波数成分のみ学習対象とする。
 学習対象となった周波数成分のみEEPROMにライブラリとして書き込む。
 ※256個のint型数値の格納→1725.6msかかる
(5)評価モードの場合
 (3)の解析結果について、ライブラリと比較する。ライブラリの周波数成の50%を満たしていたら該当有りと評価する。→(6)へ進む
(6)アラート出力
 別途設定したxbeeを経由して、アラート値をシリアル出力する。
■処理概要(Arduino 子機)
(1)アラート受信
 シリアル信号の受信有無をチェックする。有れば(2)へ進む
(2)アラート表示
 ブザー音を一定間隔で鳴らす。同時にLED点滅を行う。
以前作成したアラート受信用機能を使用する。下記参照
→ http://isa.asablo.jp/blog/2010/05/13/5083318

■ハードウェア仕様
※カッコ内はスイッチサイエンス商品コードor共立エレショップ商品コード
(1)Arduino親機
 Arduino Duemilanove × 1
 xbee shield (ArduinoXBeeShield) ×1
 xbee series2(XB24-Z7CIT-004) ×1
 3線式コンデンサマイク(77K311)×1
 低電圧オーディオパワーアンプ LM386(72E132)×1
 10ufと1ufのコンデンサ、抵抗(10kΩ、2.2kΩ)、タクトスイッチ

親機の回路図
                         親機の回路図(xbeeは省略) 
親機の内部画像
                         実際の親機の状態。
           Arduino+XbeeShieldの状態をスペーサでケースに固定すると
           それなりの高さが必要で、用意したケースに収まらなかった。
           回路部分は昔のPCのライザーカードのような感じで横に詰めた。

(2)Arduino子機
 Arduino FIO(SFE-DEV-09712) ×1
 リチウムイオンポリマー電池860mAh(SFE-PRT-003411) ×1
 xbee series 2(XB24-Z7CIT-004) ×1
 LED(36K13F)
 ブザー(100円均一のキッチンタイマーより取得)×1

■実験
親機の機能がメインなので、親機に対して以下のような簡易実験を行う。
(1) 学習機能により、Arduino親機に音を学習させる。学習させる音は無料のiPhoneアプリで出した基準音であるA (440hz)。学習時に単発で鳴らした音を学習するのは難しいため、Aを連打する状態で学習させる。
(2) Arduino 親機の認識結果がokの場合は"H"、それ以外の場合は"L"をシリアルプリントする事とする。何もしない状態であれば"L"が出力され続ける事を確認する。
(3) マイクの前でいろいろ音を鳴らし、"A"の音を鳴らした時だけ、"H"がxbee経由でシリアル出力される事を確認する。

■実験結果
・確かに音を周波数成分として学習させる事はできた。そして"A"の音を学習させた時は、それ以外の音を鳴らしても反応しない結果となった。
・ただし非常にシビアな認識精度で、例えば同じAの音でも、鳴らし方によっては認識しなかったり、別のiPodアプリである「Mini Piano」で出した「ラ」の音では認識してくれなかった。

■考察
個人認識だとかの目的であれば、認識精度がシビアな事は大歓迎であるが、普通は学習した時とまったく同じ音が出る事はありえないので、「学習した音っぽい音がなっている」かどうかが知りたい情報である。
多少違う音でも、成分的に同じと判断する所を、どこまで許容するかがチューニングのしどころだと考えているが、今回のやり方ではラブラリが1個なので、ちょっとでも学習した内容と違ったら即アウトになる結果だった。これでは実際の利用シーンでは厳しいものがある。
こうした場合、「ライブラリを増やす」というのが認識の領域の研究などでは良くある手法だが、Arduino上でそれをやるのはちょっとキビシイ。
→今回は、具体的には「赤ん坊の泣き声」とか、「ペットの鳴き声」に反応するようなものを作りたいと考えているので、そういったゆる~い範囲での認識をするなら、もっと別の方法があると考えている。もう少し工夫してみたい。

コメント

_ arduinoをはじめたい! ― 2014/10/06 14:28

こんにちはardino初心者です。サンプルスケッチ、とても勉強になりました。
音声の入力をスマホのイヤフォンジャックから取っても大丈夫でしょうか?

_ aki ― 2014/10/23 01:22

音をイヤフォンから出すための電位差が得られるので、信号としても使えると思います。出力を最大にしても1V程度の電圧なので、arduinoでなんとか拾える?というレベルと思いますが、やってみないとわかりませんね。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://isa.asablo.jp/blog/2010/05/12/5080661/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。