音声認識でデバイスを制御する
Bluemixには、あらかじめさまざまなサービスが提供されており、これらを用いることで多様なアプリケーションを簡単に構築できます。今回はWatson Speech to Textというサービス(以降、WSTと呼びます)を用いて音声認識の機能を利用します(図1)。
mbedに対して音声で命令を伝えると、その動作を行ってくれるようにしてみましょう。今回は簡易的に「明るくして」という音声を認識したら、照明の替わりとしてLED4を点灯することにします。WSTは音声データ(flac、PCM、WAV、Ogg)を受け取って(現在は、通信方式としてHTTPとWebSocketに対応)、JSONで認識結果を返してくれます(仕様の詳細は、Watson Developer Cloudの説明を参照してください)。2016年7月現在、日本語にも対応しています。
面白いのは認識結果として複数の結果を返すことがあるという点で、それぞれに対し、Confidence(確信度)という数値が付けられて、Watsonがどの程度その結果に自信を持っているかが分かります。
デバイス側のリソースの考慮
音声データの処理には多量のメモリが必要となります。例えば2秒間の音声データを取り込むことを考えてみましょう。マイクからの信号はアナログデータですが、これをデジタルデータとして取り込みます(これを量子化といいます)。仮にマイクの最大出力が±1V(ボルト)とすると、2Vの範囲を例えば65536等分(16bit)してデジタルデータに変換します。何bitに量子化するかで音声の品質や、必要とするメモリ量が変わってきます。ここでは16bitとして計算してみましょう。次にサンプリング周波数を決定します。マイク出力は時間と共に変化するので、一定時間ごとに取り込む必要があります。例えば1秒間に8000回取り込むとすると、1/8000秒に1回取り込むことになります。このとき、取り込み間隔(1/8000秒)の逆数をサンプリング周波数と呼びます。今回の例の場合は8000Hz=8kHzとなります(図2)。
一般には、取り込みたい音声の最大周波数の2倍以上のサンプリング周波数を選択しないと満足な品質で再現することは難しいため、音声データの取り込みの場合には最低でも8kHzくらいのサンプリング周波数を用います。ここで必要となるメモリ量を計算してみましょう。仮に16bitの量子化で8kHzのサンプリング周波数を選び、2秒間の音声データを取り込むとすると、
2バイト(=16bit)×8000×2=32000バイト
連載最初の回にmbedのメモリ(RAM)が32Kバイトであることをご紹介しました。これでは音声データを取り込むだけでメモリを使い切ってしまいます。実際にはスタック領域や通信処理用のバッファなどでメモリを消費するので、この半分強くらいに抑える必要があります。実際試してみると分かりますが、2秒というのは「コマンド」を伝える場合には、割と余裕があるためmbedのメモリに収まるように様子を見つつ、長さを切り詰めていことにします。
もう一つの注意として、WSTはセキュリティのために通信にSSLを利用します。mbedにもSSL通信用のライブラリがいくつかあるのですが、問題はこれがメモリを必要とする点です。このため今回は、mbedから直接WSTにデータを送信するのはあきらめて、一度サーバを経由することにします。この中継サーバを今後はプロクシと呼びます(図3)。