Raspberry Pi


(2)OpenJtalkと+NTTdocomo音声認識・雑談会話APIをつかって 会話を楽しむ

pythonプログラムを作成し雑談対話を試す。



次のように設定しました
 ・Raspberry Pi2に「jtalk」と「WiringPi」をインストール。設定は省略します。 本ホームページの「Raspberry Piを使って、音声命令でキャタピラを操作」を参照してください。
 ・docomo Developer support からAPI key を取得。
 ・対話型python を使って、雑談対話を試す。
 ・Pythonプログラムで、雑談対話の返事を「jtalk」の「メイちゃん」の声で応答させる。



※2020年現在、使用したNTTdocomo音声認識・雑談会話APIは廃止となって いますが、作成記録として残しておきます。

  ALSAについて


1.オーディオデバイスALSAのサウンドの録音にはarecordコマンドを使用します。

2.使用するarecordコマンドのオプションについては次の通りです。
 -D device=NAME: 使用するPCM(デバイス名)を指定します。

 -d duration=#: 指定の秒数後に終了します。値が 0 の場合は無限。デフォルトはゼロなので arecordは切断されるまで動き続けます。

 -t file-type TYPE: ファイルタイプを指定します (voc, wav, raw or au)。指定がない場合は waveフォーマットで再生します。

 -f format=FORMAT: サンプルフォーマットを指定します。
 認識できるフォーマットは、S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE
 U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUB FRAME_BE
 MU_LAW A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE
  U20_3BE S18_3LE S18_3BE U18_3LE です。フォーマットが指定されない場合はU8が設定されます。

 -r rate=#: サンプリングレートの指定をします。デフォルトでは8000Hz。利用可能な値: 2000Hzから 192000Hz

3.例えば、この後のプログラムに使用した

  arecord -D plughw:1,0 -d 5 -t wav -f S16_LE -r 16000 speak.wav については

 -D plughw:1,0 → マイクのカード番号が1で、デバイス番号が0です。
 -d 5 → ディレイを5秒にしました。(5秒間でメッセージを話すようにしてあるため。)
 -t wav → ファイルタイプは、wave です。
 -f S16_LE → フォーマットを S16_LE としました。
 -r 16000 → サンプリングレートを16000Hzとしました。docomoのAPIのレートが16000Hzのためです。
 speak.wav → 録音ファイル名をspeak.wav としました。

4.「plughw:1,0」については、本ホームページ「Raspberry Piを使って音声命令でキャタピラ操作」の 「(2)Juliusの設定」タブを参照してください。

5.「plughw:1,0」について、再掲します。
(1)「LTXTerminal」で次のコマンドを実行し、音声デバイスの確認をします。

  $ arecord -l

(2)次のように表示されます。

 これにより、マイクのカード番号が1で、デバイス番号が0であることがわかります。
 したがって、「plughw:1,0」の 1,0 はマイクのカード番号が1、デバイス番号が0を表しています。




  音声回路の概略


音声回路の概略図は下図の通りです。

1.小型アンプは、秋月電子の「TA7368使用小型アンプキット」を使用。

2.4極ミニプラグは、秋月電子で「3.5mmΦ4極ミニプラグ MP-435」を購入し、 4極プラグから映像と音声右を外し、2線(音声左・GND)をアンプに接続しました。

3.小型アンプの電源として006P型9Vの電池を使用。

4.3端子レギュレータは、秋月電子の「三端子レギュレータ5V 1A」を使用。

5.スピーカーは、100均で購入したものを使用。

6.Raspberry PiのGPIO端子のGPIO7に青色LEDを接続して、点灯している間(5秒間)に メッセージを話すようにプログラムしてあります。




  pythonプログラムを作成し雑談対話を試す。


雑談対話の返答をJtalkの「メイちゃん」の声で聞くようにpythonプログラムonsei.pyを 作成します。

1.pythonプログラムonsei.pyは次のようになります。

# python onsei.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
import time
import requests
import json

PATH = '/home/pi/speak.wav'
apikey_v = '音声認識APIキー'
apikey_z = '雑談対話APIキー'
url_v = 'https://api.apigw.smt.docomo.ne.jp/amiVoice/v1/recognize?APIKEY=%s'%(apikey_v)
url_z = 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY=%s'%(apikey_z)

modeID = ""
contextID = ""

os.system("gpio -g mode 7 out")

def recognize():
  files = {"a": open(PATH, 'rb'), "v": "on"}
  r = requests.post(url_v, files=files)
  speakmessage = r.json()['text']
  print speakmessage
  return speakmessage
	
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 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("arecord -D plughw:1,0 -d 5 -t wav -f S16_LE -r 16000 speak.wav")
  os.system("gpio -g write 7 0")

  message = recognize()
    
  if message.encode('utf-8') == "":
    print "クライアントの実行を停止します"
	os.system("/home/pi/jtalk.sh 会話を終了します")
	break

  talkmessage = dialogue(message)
  os.system("/home/pi/jtalk.sh " + talkmessage.encode('utf-8'))
  time.sleep(4)
						

2.プログラムの概要
(1)PATH は、ALSA の録音ファイルspeak.wavのパスです。

(2)音声認識APIキーと雑談対話APIキーを2つに分けているのは、申請を分けたためです。
  使用した音声認識APIキーは90日間の使用になっているためです。

(3)url_v、url_z は、使用する音声認識APIと雑談対話APIのURLです。

(4)"gpio -g mode 7 out" は、GPIO7の使用宣言です。

(5)def recognize()及びdef dialogue(message)はAPIの使用指定です。
  modeID = r.json()['mode']、contextID = r.json()['context']で対話の継続指定をしています。
  また、"t": ""で、関西弁指定をやめて、デフォルトにしてあります。

(6)"/home/pi/jtalk.sh 会話を始めます" は、jtalkの「メイちゃん」の声で「会話を始めます」と 会話開始の合図です。
  「jtalk.sh」については、本ホームページの「Raspberry Piを使って、音声命令でキャタピラを操作」 を参照

(7)"gpio -g write 7 1" は、「メイちゃん」の会話開始の合図のあとに、青色LEDを点灯します。
  青色LEDが点灯している間に、こちらのメッセージを話します。

(8)"arecord -D plughw:1,0 -d 5 -t wav -f S16_LE -r 16000 speak.wav" は、ALSAの項で説明した とおりです。
  メッセージをspeak.wavに録音します。

(9)5秒後、"gpio -g write 7 0"で、青色LEDが消灯します。

(10)青色LEDが点灯している間にメッセージが無ければ、"/home/pi/jtalk.sh 会話を終了します"で 「メイちゃん」の声で会話を終了します。

(11)青色LEDが点灯している間にメッセージがあれば、"/home/pi/jtalk.sh " + talkmessage.encode('utf-8')  から「メイちゃん」の声で返答があります。

(12)time.sleep(4) は、返答があって、4秒後までにこちらのメッセージを話す間を取っています。 つまり、返答があって、4秒後に青色LEDが点灯(会話開始)します。

3.こちらのメッセージによる雑談対話の応答が、「メイちゃん」の声で聞こえればOKです。

4.「Ctrl+C」で終了します。