コンピューター好きのブログ

主にコンピューター・ラズパイと電子工作・オーディオ関連の記事を書いています。

Raspberry Pi Zero WでGoogle Assistantのpushtotalkをウェイクワード対応にする方法

以前、以下の記事に書きましたが、Raspberry Pi Zero Wは”OK Google”などの「ウェイクワード(Wake Word)」に対応していません。

www.toomath.net

 

そこで下記のようにpushtotalkを使ってGoogle Assistantを使ってみましたが、やはりウェイクワードが使えないのは辛い。。

www.toomath.net

 

このため、Juliusでウェイクワードを拾い、Google Assistant の pushtotalk に通知することを考えましたが、Juliusの認識が遅すぎる&Juliusと Google Assistant で音声デバイスを取り合う(?)ため諦めました。

 

なんとかならないかとネットを彷徨ったところ、以下のサイトを見つけました。

AlexaとGoogle Assistantの同時待ち受けを可能にする方法を公開されているページですが、この中に pushtotalk をウェイクワードで起動する方法が記載されています。

Snowboyというアプリでウェイクワードを認識し、pushtotalkを起こしているようです。

https://qiita.com/Dimeiza/items/1a77191a5febd57e98c4

早速参考にさせていただき、Snowboyを組み込んでみました。

 

Snowboyを導入する

ダウンロード

以下のページに「Raspberry Pi with Raspbian 8.0, all versions (1/2/3/Zero)」という行があり、"1/2/3/Zero"の部分をクリックするとダウンロードできます。

Snowboy, a Customizable Hotword Detection Engine — Snowboy 1.0.0 documentation

展開

ダウンロードしたファイルをWinSCPなどでRaspberry Pi Zero Wに持っていき、下記のコマンドで展開します。ダウンロードしたファイルは /home/pi/tmp に置いたとします。

cd /home/pi/tmp

bunzip2 rpi-arm-raspbian-8.0-1.1.1.tar.bz2

tar xvf rpi-arm-raspbian-8.0-1.1.1.tar

 

必須パッケージの適用

Snowboyを使用する上で必要になるパッケージをインストールします。

sudo apt-get install python-pyaudio python3-pyaudio sox

sudo apt-get install libatlas-base-dev

sudo apt-get install swig

pip install pyaudio

 

Snowboyの共有ライブラリをPython3用に置換

初めから入っているSnowboyの共有ライブラリ(_snowboydetect.so)はPython3には対応していないようだったので、以下の方法でPython3用を作成し、元のファイルと置換しました。

cd /home/pi/tmp

git clone https://github.com/Kitt-AI/snowboy.git

cd /home/pi/tmp/snowboy/swig/Python3

make clean

make

cp _snowboydetect.so /home/pi/tmp/rpi-arm-raspbian-8.0-1.1.1 

 

Snowboyを動かしてみる

以下のコマンドを実行すると、画面になにやら色々出てきて「Listening... Press Ctrl+C to exit」で止まります。

python demo.py  rources/snowboy.umdl

そこですかさず「Snowboy」と声をかけると、チン!という音がして「INFO:snowboy:Keyword 1 detected at time: 2019-xx-xx xx:xx:xx」と表示されました。

 うまく認識できたようです。

 

SnowboyからGoogle Assistantにイベントを通知する

Snowboyでウェイクワード認識ができましたので、認識したことを pudhtotalk に通知する方法を考えます。

pushtotalk はキー入力を待ちますので、まずこの部分をSnowboyからイベント待ちするように書き換えます。今回は手っ取り早くソケットを使ってイベントを送るようにしました。

pushtotalk.pyというソースコードの「click.pause(info='Press Enter to send a new request...')」の部分でキー入力を待っていますので、以下のように書き換えました。

赤字が変更箇所です。

wait_for_user_trigger = not once
wait_init()
while True:
    if wait_for_user_trigger:
        #click.pause(info='Press Enter to send a new request...')
        wait_snowboy()
    continue_conversation = assistant.assist()
    # wait for user trigger if there is no follow-up turn in
    # the conversation.
    wait_for_user_trigger = not continue_conversation

    # If we only want one conversation, break.
    if once and (not continue_conversation):
        break
wait_close()

wait_init、wait_snowboy、wait_closeは下記のようにしました。

def wait_init():
    global sock
    host = '127.0.0.1'
    port = 36363

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((host, port))

def wait_close():
    global sock
    sock.close()

def wait_snowboy():
    global sock
    backlog = 10
    bufsize = 1024
    sock.listen(backlog)
    conn, address = sock.accept()
    while True:
        msg = conn.recv(bufsize)
        if not msg:
            continue
        else:
            conn.send(msg)
            break
    conn.close()
return

以下のimportも pushtotalk.py に追記します。

import socket

 

次にSnowboyのソースコード(snowboydecoder.py)を書き換えます。

play_audio_fileというメソッドでウェイクワード認識後の処理を行っているので、ここに下記のイベント送信処理を入れ込みます。チン!という音を出した後に送信するようにしました。

host = '127.0.0.1'
port = 36363
backlog = 10
bufsize = 1024
smsg = b"SNOWBOY"

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(smsg)
rmsg = sock.recv(bufsize)
sock.close()

 

以上でできるようになりました!と言いたいところでしたが、問題発生。。

pushtotalkを起動してからSnowboyを起動すると「PortAudioError」というエラーが。。

Webを検索すると以下のページを見つけたため、pulseaudioをインストールして設定したところ解決しました。助かった~。

願いごとを叶えてくれる「かみさま」をRaspberry Piに実装する - 現ア集のブログ

 

なお、私のRaspberry Pi Zero WはUSB接続のサウンドカードを使っているのですが、オンボードサウンド(bcm2835)が有効になっているとpulseaudioがうまく動かなかったので /boot/config.txt を下記のように編集して再起動しました。

dtparam=audio=off

 

ちなみにこのページにはSnowboyのウェイクワードを自分の好きなものに変える方法も記載されています。いずれに参考にさせていただこうと思っています。

 

(c) 2018 toomath