次のように設定しました
・Raspberry Pi2に「jtalk」と「WiringPi」をインストール。設定は省略します。
本ホームページの「Raspberry Piを使って、音声命令でキャタピラを操作」を参照してください。
・Google からSpeech API key を取得。
・Google音声認識API を使って、雑談対話を試す。
・雑談対話の返事を「jtalk」の「メイちゃん」の声で応答させる。
1.NTTDocomoの音声認識APIは、以下の2通りがあります。
(1)「Powered by NTTテクノクロス」・・・Androidで提供
(2)「Powered by アドバンスト・メディア」・・・REST形式で提供
前回の「OpenJtalkと+NTTdocomo音声認識・雑談会話APIをつかって会話を楽しむ(2)」
では②の音声認識「Powered by アドバンスト・メディア」を使って雑談対話を試してみましたが、
APIキーは利用期間が90日間の制限があります。
そこで、Googleの音声認識API「Speech API」を使って、NTTdocomo雑談会話を試みてみたいと
思います。
2.Googleの音声認識API「Speech API」の使用料金及び音声エンコードは次のようになっています。

前回の「OpenJtalkと+NTTdocomo音声認識・雑談会話APIをつかって会話を楽しむ(2)」では、
「.wave」ファイル形式を使っていましたので、
今回、音声ファイルは「.FLAC」ファイル形式を使用し、メタデータを格納するヘッダーが
含まれている必要があります。
そこで書籍「自然会話ロボットを作ろう!」を参考させてもらい、音声処理ライブラリ「sox」を
使うことにしました。
事前のソフト及びアンプの回路等は、前のページ「(2)Pythonプログラムを作成し雑談対話を試す」
と同じです。
1.soxライブラリをRaspberry Piにインストール。
ターミナルで次のように入力しインストールします。
$ sudo apt-get install alsa-utils sox libsox-fmt-all
2.音声入出力のカード番号等については、他のページ「Raspberry Piを使って、音声命令で
キャタピラを操作(1)」と同様ですので参照してください。
再掲しますと、
(1)音声入力カード番号は、ターミナルで、「 $ arecord -l 」と入力し確認します。
(2)音声出力のカード番号は、同様にターミナルで、「 $ aplay -l 」と入力し
確認します。
3.音声入力のテスト
(1)ターミナルで次のように入力し、5秒以内でマイクロフォンに向かって話して音声入力の
テストをします。
$ AUDIODEV=hw:1 rec -c 1 -r 11025 speak.flac trim 0 5
・AUDIODEV=hw:1 は、音声入力デバイスで、カード番号が1。
・-c は、音声チャンネル数で、1はモノラル。
・-r は、サンプリングレートで、11025は11025Hz。
・speak.flac は、出力先の音声データファイル。
・trim は、音声入力時間で、0 5は、入力時間が5秒。
(2)音声入力データの確認
ターミナルで次のように入力して、録音したデータを再生し、スピーカーから
聞こえたらOKです。
$ play speak . flac
1.「listen . py」のプログラムは、次のようにしました。
# python listen.py #!/usr/bin/env python # -*- coding: utf-8 -*-
import sys import os import time import requests import json PATH = '/home/pi/speak.flac' GOOGLE_APIKEY = 'Google Speech-APIキー' url_v ='https://www.google.com/speech-api/v2/recognize?xjerr=1&client=chromium&lang=ja-JP& maxresults=10&pfilter;=0&xjerr=1&key=' + GOOGLE_APIKEY hds = {'Content-type': 'audio/x-flac; rate=11025'} os.system("gpio -g mode 7 out") def recognize(): files = open(PATH, 'rb') voice = files.read() files.close() try: rsp = requests.post(url_v, data=voice, headers=hds).text except IOError: return '#CONN_ERR' except: return '#ERROR' objs = rsp.split(os.linesep) for obj in objs: if not obj: continue alternatives = json.loads(obj)['result'] if len(alternatives) == 0: continue return alternatives[0]['alternative'][0]['transcript'] return '' os.system("/home/pi/jtalk.sh 会話を始めます") while True: os.system("gpio -g write 7 1") os.system("AUDIODEV=hw:1 rec -c 1 -r 11025 " + PATH + " trim 0 5") os.system("gpio -g write 7 0") message = recognize().encode('utf-8') if (message == '#CONN_ERR'): print 'internet not available' message = '' elif (message == '#ERROR'): print 'voice recognizing failed' message = '' else:
print 'your word:' + message if message == "": print "クライアントの実行を停止します" os.system("/home/pi/jtalk.sh 会話を終了します") break
2.動作は、次のようになります。
(1)起動後、「メイちゃん」の声で、スピーカーから「会話を始めます」と聞こえます。
(2)それと同時に、アンプに設置している青のLEDが点灯します。青のLEDが点灯したら
マイクに向かって話します。
(3)青のLEDが消灯したら音声入力は終了です。5秒間の間に話します。
(4)画面に話した内容が表示されます。
(5)再度、青のLEDが点灯しますので、マイクに向かって話します。これの繰返しです。
(6)青のLEDが点灯しているときに、何も話さない(無音)と、画面に「クライアントの
実行を停止します」と表示され、
「メイちゃん」の声で、スピーカーから「会話を終了します」と聞こえます。
そしてプログラムは、break します。
3.「listen . py」を実行した結果が次の画面です。(Python2 IDEを使用)

Google Speech APIが何とか動いています。
プログラム中の「jtalk.sh」は、シェルスクリプトで、他のページ「Raspberry Piを使って、
音声命令でキャタピラを操作(1)」に記していますので確認してください。
1.雑談会話のプログラム「zatudan.py」は次のようにしました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import time
import requests
import json
PATH = '/home/pi/speak.flac'
DOCOMO_APIKEY= 'NTTDocomo-雑談対話APIキー'
GOOGLE_APIKEY = 'Google Speech-APIキー'
url_z = 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY=%s'%(DOCOMO_APIKEY)
url_v ='https://www.google.com/speech-api/v2/recognize?xjerr=1&client=chromium&lang=ja-JP&
maxresults=10&pfilter=0&xjerr=1&key=' + GOOGLE_APIKEY
hds = {'Content-type': 'audio/x-flac; rate=11025'}
modeID = ""
contextID = ""
os.system("gpio -g mode 7 out")
def recognize():
files = open(PATH, 'rb')
voice = files.read()
files.close()
try:
rsp = requests.post(url_v, data=voice, headers=hds).text
except IOError:
return '#CONN_ERR'
except:
return '#ERROR'
objs = rsp.split(os.linesep)
for obj in objs:
if not obj:
continue
alternatives = json.loads(obj)['result']
if len(alternatives) == 0:
continue
return alternatives[0]['alternative'][0]['transcript']
return ''
def dialogue(message):
global contextID, modeID
userload = {
"utt": message,
"context":contextID,
"nickname": "椋",
"nickname_y": "ムク",
"sex": "男",
"bloodtype": "A",
"birthdateY": "1997",
"birthdateM": "1",
"birthdateD": "16",
"age": "30",
"constellations": "水瓶座",
"place": "横浜",
"mode": modeID,
"t": ""
}
r = requests.post(url_z, data=json.dumps(userload))
print ("Mei: "),
print r.json()['utt']
modeID = r.json()['mode']
contextID = r.json()['context']
return r.json()['utt']
os.system("/home/pi/jtalk.sh 会話を始めます")
while True:
os.system("gpio -g write 7 1")
os.system("AUDIODEV=hw:1 rec -c 1 -r 11025 " + PATH + " trim 0 5")
os.system("gpio -g write 7 0")
message = recognize().encode('utf-8')
if (message == '#CONN_ERR'):
print 'internet not available'
message = ''
elif (message == '#ERROR'):
print 'voice recognizing failed'
message = ''
else:
print 'your word:' + message
if message == "":
print "クライアントの実行を停止します"
os.system("/home/pi/jtalk.sh 会話を終了します")
break
talkmessage = dialogue(message)
os.system("/home/pi/jtalk.sh " + talkmessage.encode('utf-8'))
time.sleep(5)
2.雑談会話のプログラム「zatudan.py」の実行結果は次の通りになります。
(Python2 IDEを使用)

画面だけでなくスピーカーから「Meiちゃん」の声で応答があります。
雑談対話は、こちらが質問すると話が飛んでしまい、そのうち質問ばかりに
なってきて、こちらが答える形になってしまいます。
しかたないのかな?