Rapiroをブラウザで動かしてみた 【おしゃべり編】

Rapiroの機能を一画面にまとめたインターフェイスを作成して、ブラウザから操作できるようにした。

「Rapiroをブラウザで動かしてみた 【準備編】」の記事はこちら

Rapiroをブラウザで動かしてみた 【準備編】
WebIOPiを使ってRapiroをブラウザから操作するためのWebサーバーを立てる方法を解説。

「Rapiroをブラウザで動かしてみた 【全体構成】」の記事はこちら

Rapiroをブラウザで動かしてみた 【全体構成】
Rapiroをブラウザから操作するための全体構成を解説したまとめ記事。ソースコード一式と各機能の実装解説記事リンクも掲載。

インターフェイスの作成

入力欄とボタンを用意する。

<input type="text" class="talk_text" id="talk_text">
<button type="button" class="talk_btn" id="talk_btn">話す</button>

制御処理の実装

JavaScript側の実装

ボタンのイベントハンドラで、マクロ名と値(テキスト)を取得して処理を呼び出す。
pointerupは、マウスを離したタイミングやタッチを離したタイミングで発火する。

document.getElementById('talk_btn').addEventListener('pointerup', function() {
	change_rapiro('talk', document.getElementById('talk_text').value);
	document.getElementById('talk_text').value = '';
	status = 'stop';
});

Python側の実装

渡された値を受け取り、Open JTalkを使用してしゃべってもらう。
ボタン押下後、なかなかなタイムラグがあるので、直接標準出力する方法も試してみたが、そちらでも速度は出なかった。メモリの問題なのか、むしろwavに出力したほうが早かった。
Raspberry Pi model B+の限界と思われる。

Open JTalkの詳細についてはこちら

Rapiroをしゃべらせてみた
Rapiroは耳の部分にスピーカーを取り付けられるように設計されている。せっかくなのでOpen JTalkを使ってRapiroをしゃべらせることにした。
@webiopi.macro
def talk(value):
    wav = "/home/panda/py_code/rapiro_talk.wav"

    cmd = [
        "open_jtalk",
        "-x", "/var/lib/mecab/dic/open-jtalk/naist-jdic",
        "-m", "/usr/share/hts-voice/mei/mei_normal.htsvoice",
        "-a", "0.4",
        "-r", "0.7",
        "-ow", wav
    ]

    proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
    proc.stdin.write(urllib.parse.unquote(value).encode("utf-8"))
    proc.stdin.close()
    proc.wait()

    subprocess.Popen(["aplay", "-q", wav])
@webiopi.macro
def talk(value):
    cmd = [
        "open_jtalk",
        "-x", "/var/lib/mecab/dic/open-jtalk/naist-jdic",
        "-m", "/usr/share/hts-voice/mei/mei_normal.htsvoice",
        "-a", "0.4",
        "-r", "0.7",
        "-ow", "/dev/stdout"
    ]

    proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    subprocess.Popen(["aplay", "-q"], stdin=proc.stdout)

    proc.stdin.write(urllib.parse.unquote(value).encode("utf-8"))
    proc.stdin.close()