はじめに
Raspberry Piにマイクを接続して、話しかけた音声を認識させてみます。
音声認識には国産ツールの「Julius」を使用します。
用意するもの
- Raspberry Pi 3
- USBマイク
USBマイクは、マイク付きWebカメラでも利用できます。
ということで、今回はLogicool C300というUSB接続のWebカメラを使います。
https://www.amazon.co.jp/%E3%83%AD%E3%82%B8%E3%82%AF%E3%83%BC%E3%83%AB-C300-%E3%82%A6%E3%82%A7%E3%83%96%E3%82%AB%E3%83%A0/dp/B002J4UAG4
手順
Raspberry Piで音声認識をするにはJuliusの導入のほか、マイク関連の設定が必要にです。大まかな手順は下記の通りです。
- USBマイクをRaspberry Piで使う準備をする
- 録音のテスト
- Juliusをインストールする
- Julius音声認識パッケージを取得する
- 動作確認
USBマイクをRaspberry Piで使う準備をする
Raspberry PiにUSBマイクを認識させる
Raspberry Pi3と現在(3/28時点)でのRaspbianであれば、Logicool C300はUSBに接続するだけでデバイスを認識します。正しく認識されているかは、下記コマンドで確認できます。
lsusb
Bus 001 Device 004: ID 046d:0805 Logitech, Inc. Webcam C300
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
上記の実行結果では、「Bus 001 Device 004」で「Logitech, Inc. Webcam C300」と表示されているため、WebカメラがUSBデバイスとして認識されていることがわかります。
USBマイクの優先順位をあげる
Raspberry Pi 3には、Φ3.5オーディオ出力端子が搭載されています。USBにスピーカー/マイクを接続しても、標準のオーディオ出力端子が優先されるため、USB側のスピーカー/マイクを認識してくれません。
これを解決するためには、オーディオデバイスの優先順位を変更する必要があります。
現在の優先順位を確認するには、下記のコマンドを実行します。
cat /proc/asound/modules
0 snd_bcm2835
1 snd_usb_audio
実行結果は、左から「優先順位(数値が低いほうが優先順位が高い)」、「デバイス名」の順で表示されます。上記の結果では、USBスピーカー/マイク(snd_usb_audio)がΦ3.5オーディオ出力端子(snd_bcm2835)よりも下であることがわかります。
これを変更するには、/lib/modprobe.d/aliases.conf
に記載の設定を変更します。
viなどのテキストエディタでファイルをしましょう。(root権限の付与を忘れずに)
sudo vim /lib/modprobe.d/aliases.conf
ファイル内のoptions snd-usb-audio index=-2
という箇所がUSBスピーカー/マイクの設定ですので、こちらの設定を「-2」から「0」を変更します。
# prevent unusual drivers from appearing as the first sound device ###########
options snd-pcsp index=-2
# options snd-usb-audio index=-2 # USB audio before
options snd-usb-audio index=0 # USB audio after
options cx88_alsa index=-2
options snd-atiixp-modem index=-2
options snd-intel8x0m index=-2
options snd-via82xx-modem index=-2
設定ファイルを保存したら、Raspberry Piを再起動します。再起動後、再度cat /proc/asound/modules
を実行し、下記のように優先順位が変わっていれば、設定変更が有効になっています。
0 snd_usb_audio
1 snd_bcm2835
録音のテスト
Raspberry PiとUSBマイクが正しく動作することを確認するため、USBマイクから音声を録音し、ファイルに保存してみます。
音声の録音はarecordコマンドで実現できますが、arecordコマンドで録音するにはUSBマイクに割り当てられている「カードNo.」と「デバイスNo.」を知る必要があります。それぞれの確認は、arecordコマンドの-lオプションで確認できます。
arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: U0x46d0x805 [USB Device 0x46d:0x805], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
上記の場合、「card 0」「device 0」と表示されているため、カードNo.、デバイスNo.ともに「0」で認識されているということがわかります。
カードNo.、デバイスNo.がわかったところで、arecordを使って録音した音声をファイルに保存します。録音するコマンドは下記のとおりです。
arecord -D plughw:0,0 test.wav
コマンド実行後、録音待ちの状態になります。マイクに向かって話しかけ、完了したらCtrl+Cを押下して終了します。終了時に、下記のようなメッセージが表示されますが、中断した際に表示されるメッセージですので、問題ありません。
Aborted by signal Interrupt...
arecord: pcm_read:2103: read error: Interrupted system call
録音されたファイル(test.wav)を再生してみましょう。音楽プレイヤーなどのソフトで話しかけた音声を聞くことができれば、成功です。
Juliusのインストール
Juliusは、GitHubよりソースコードを取得し、ビルドすることでバイナリファイルを作成します。
公式ドキュメントにはバイナリパッケージを取得してインストールできるという記載がありますが、Githubで公開されているバイナリパッケージはWindows用のみで、Linuxなどで使用する場合は、ソースコードからコンパイルする必要があります。いずれMac/Linux環境用のバイナリパッケージも配布してほしいですね。
Juliusのソースコードの取得する
GithubのJuliusのサイトからソースコードを取得しましょう。下記のコマンドで取得できます。
mkdir julius
cd julius
wget https://github.com/julius-speech/julius/archive/v4.4.2.1.tar.gz
ソースコードをコンパイルする
下記のコマンドを実行し、ソースコードからバイナリパッケージをコンパイルします。コンパイルには時間がかかりますので、少し待ちましょう。
tar xvzf v4.4.2.1.tar.gz
cd julius-4.4.2.1
./configure
make
Julius音声認識パッケージを取得する
Juliusで音声認識をするためには、音声認識パッケージをインストールする必要があります。音声認識パッケージは公式サイトより取得します。
公式サイトでは用途に応じて複数のパッケージを提供していますが、今回は、一般的な日本語の音声認識であるディクテーションキット(dictation-kit)を使用します。
ディクテーションキットの取得は、下記コマンドで行います。
mkdir ~/julius/julius-kit
cd ~/julius/julius-kit
wget https://osdn.net/dl/julius/dictation-kit-v4.4.zip
unzip dictation-kit-v4.4.zip
その他環境設定
ALSADEV設定でデバイスを固定にする
Juliusを実行する際にもカードNo.、デバイスNo.の情報が必要です。Juliusが常に同じ設定を使用できるように、環境変数として設定しておくと便利です。
Raspberry Piの場合、~/.profileに下記の一文を追加します。
export ALSADEV="plughw:0,0"
変更を有効にするには、Raspberry Piを再起動、または「source ~/.profile」を実行します。
※この後の手順でRaspberry Piを再起動するため、ここでの再起動上記コマンドの実行は不要です。
/dev/dspを有効にする
JuliusではALSAサウンドドライバのデバイスファイル/dev/dspを使用します。標準では使用できるようになっていないため、下記のコマンドで利用できるようにします。(有効にするために再起動をしています)
sudo modprobe snd-pcm-oss
sudo sh -c "echo snd-pcm-oss >> /etc/modules"
sudo reboot
ここまでで、Juliusの環境構築は完了です。
動作確認
ディクテーションキットの解凍が完了したら、いよいよJuliusを動かします。起動のコマンドは下記のとおりです。
~/julius/julius-4.4.2.1/julius/julius -C ~/julius/julius-kit/dictation-kit-v4.4/main.jconf -C ~/julius/julius-kit/dictation-kit-v4.4/am-gmm.jconf -nostrip
Juliusの起動が成功すると<<< please speak >>>
と表示されます。
試しに「こんにちは」とマイクに向かって話しかけてみましょう。
音声認識が成功すると、下記のように表示されます。
pass1_best: こんにちは 。
pass1_best_wordseq: <s> こんにちは+感動詞 </s>
pass1_best_phonemeseq: silB | k o N n i ch i w a | silE
pass1_best_score: -4168.268555
### Recognition: 2nd pass (RL heuristic best-first)
STAT: 00 _default: 21946 generated, 1540 pushed, 319 nodes popped in 159
sentence1: こんにちは 。
wseq1: <s> こんにちは+感動詞 </s>
phseq1: silB | k o N n i ch i w a | silE
cmscore1: 0.351 0.416 1.000
score1: -4188.954102
おわりに
Juliusの導入は想像以上に簡単にできました。どちらかというと、USBマイクを認識するためにOS側の設定変更のほうが大変でした。
それと、今回使用しているディクテーションキットの認識率ですが、Google Cloud Speech API等に比べると精度は劣るように思います(辞書の精度に大きな差があるのでしょうね)。その分、通信のオーバーヘッドがない分応答速度は早いので、用途に応じて使い分けるということになりそうです。