2018年8月16日木曜日

Raspberry Pi に日本語を喋らせる

Alexa でルンバに掃除させる際の試行錯誤で、色々な家電を音声コマンドで動かせるようになりました。

便利にはなったものの、Alexa Home Skill は返事が毎回「はい」なので無愛想に感じてしまいます。
そこで、Raspberry Piで家電を操作する際にもう少し丁寧に喋ってもらうようにしました。

Raspberry Piから音声出力できるようにする

Raspberry Piにはスピーカーがありません。
そのため、何らかの方法で音声出力できるようにする必要があります。

今回は家電が近くにあるのでHDMI出力を使いました。
HDMIから音声出力する方法は前回の「Raspberry PiをAirPlayレシーバにする」をご参照ください。

特にHDMIにこだわらない場合は、USBスピーカーを使うのが音質が良く、動作も確実なようです。
音声設定についてはこのサイトが詳しいです。
ちなみに、今回のように音声合成の結果をHDMI出力すると次の問題があってちょっと面倒です。
  • 音声をデジタル変換する処理が追いつかず、合成音の最初の2〜3文字分の音が出ない。
  • 家電操作の対象が出力先の音声デバイスとバッティングすると厄介なことになる。
前者については、合成音の冒頭に「はい」「えーと」など無意味なセリフを入れて回避するしかなさそうです。
後者は、対象デバイスのHDMI入力を一旦Raspberry Piに切り替えてから合成音を再生し、その後で家電操作する、という流れになります。

単に「切り替えてから」と書きましたが、大抵のデバイスは音声再生程度で自動切り替えしない仕様なので、
自分で赤外線リモコンコードをコピーして操作することになると思います。
方法はルンバの掃除の際に書いたものが使えると思います。

Open JTalkをインストールする

次のようにOpen JTalkをインストールします。
$ sudo apt-get install open-jtalk
$ sudo apt-get install open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001
hts-voice-nitech-jp-atr503-m001 はおっさんの声の辞書です。
音声合成と言えば女性の声だろう、ということで女性の声の辞書を入れます。
$ wget http://downloads.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.7/MMDAgent_Example-1.7.zip
$ MMDAgent_Example-1.7.zip
$ sudo cp -r ./MMDAgent_Example-1.7/Voice/mei /usr/share/hts-voice/

Open JTalkに喋ってもらう

コマンド引数にテキストと音声辞書を指定すると合成してくれるのですが、
次のようなスクリプトを作っておくと便利です。
#!/bin/sh

msg="$1"

voice_type=/usr/share/hts-voice/mei/mei_normal.htsvoice

echo "$msg" |
open_jtalk  -m $voice_type -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow /dev/stdout |
aplay -
こんな感じで、このスクリプトの引数に日本語を渡せば再生してくれます。
$ ./voice.sh "抵抗は無意味だ"

使ってみる

open_jtalk には合成時のオプションを色々と指定できるのですが、
あまりいじっても音質が劣化して残念なことに。
よほど意味が分かっていない限りは、デフォルトのまま使うのがおすすめです。

crontab に次のようにスクリプトを仕込んでおくと、毎日7時〜22時に鳴る時報になります。
(タイムゾーンがUTCの場合は9時間引くなりなんなり)
$ crontab -e
0 7-22 * * * /home/pi/bin/tone.sh
呼び出されるスクリプトはこんな感じで適当に。
#!/bin/sh

DIR=`/usr/bin/dirname $0`

y=`/bin/date +%Y`
m=`/bin/date +%-m`
d=`/bin/date +%-d`
h=`/bin/date +%-h`

msg="$y年 $m月 $d日 h時です。"

$DIR/voice.sh "$msg"

Alexaと連携する

Alexa Home Skill と Raspberry Pi の連携については以前の説明をご参照ください。
NodeREDで家電の起動コマンドを送る前に音声合成のShell Execを挟み込めばOKです。

例えば、こんな感じです。
これでプロジェクターの起動待ちの間に「しばらくお待ちください」などのセリフを挟み込めます。


0 件のコメント:

コメントを投稿