Edited at

OpenJTalk + python で日本語テキストを発話

Ubuntu, Windows での方法を示します。Macは環境が無いのですいません。


Ubuntu 14.04 LTS で OpenJTalk+Pythonでおしゃべりさせる


Open JTalkのセットアップ

apt-getにて open-jtalk (1.07)をインストールします。



sudo apt-get install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001

mecabの辞書は、/var/lib/mecab/dic/open-jtalk/naist-jdic/ にインストールされます。


音声ファイルのセットアップ

MMDAgentから、Voiceデータを流用します。MMDAgent_Example-1.6.zip は11MBあります。

wget https://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.6/MMDAgent_Example-1.6.zip/download -O MMDAgent_Example-1.6.zip

つぎに.htsvoiceファイルを抽出

unzip MMDAgent_Example-1.6.zip MMDAgent_Example-1.6/Voice/*

ファイルを hts-voice-nitechと同じ場所にコピーしておきます

sudo cp -r MMDAgent_Example-1.6/Voice/mei/ /usr/share/hts-voice


Pythonによる再生

http://raspi.seesaa.net/article/415530289.html

を参考にさせていただきました。

以下のコードをjtalk.py としてファイルに保存しておきます。

#coding: utf-8

import subprocess
from datetime import datetime

def jtalk(t):
open_jtalk=['open_jtalk']
mech=['-x','/var/lib/mecab/dic/open-jtalk/naist-jdic']
htsvoice=['-m','/usr/share/hts-voice/mei/mei_normal.htsvoice']
speed=['-r','1.0']
outwav=['-ow','open_jtalk.wav']
cmd=open_jtalk+mech+htsvoice+speed+outwav
c = subprocess.Popen(cmd,stdin=subprocess.PIPE)
c.stdin.write(t.encode())
c.stdin.close()
c.wait()
aplay = ['aplay','-q','open_jtalk.wav']
wr = subprocess.Popen(aplay)

def say_datetime():
d = datetime.now()
text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
jtalk(text)

if __name__ == '__main__':
say_datetime()

実行テストでは、

python jtalk.py

うまくいけば、現在の時刻を発話します

他のモジュールから利用する場合には、

#coding: utf-8

import jtalk

jtalk.jtalk('何か話してください')


Windows で Open JTalkを設定する

Ubuntu では、apt-get すれば、すんなりインストールできましたが、

Windowsでは自分でビルドします。


ソースコードの入手

OpenJTalk 1.09を入手 http://open-jtalk.sourceforge.net/ から

コンパイルに必要な音声合成用のライブラリhts_engineAPIを http://hts-engine.sourceforge.net/ からダウンロードします

open_jtalk-1.09.tar.gz を、展開して c:\temp\open_jtalk-1.09 としたら、hts_engineAPIは、c:\temp\open_jtalk-1.09\hts_engine_API-1.10 に展開しておくとコンパイルの際に問題が少なくすみます。


VisualStudioでのコンパイル

Visual Studioのコマンドツールを立ち上げます。nmake とタイプして、動作することを確認してください。

まずは、hts_engine_API-1.10からコンパイルをします。

cd c:\temp\open_jtalk-1.09\hts_engine_API-1.10

nmake /f Makefile.mak
nmake /f Makefile.mak install

問題なくコンパイルできると、c:\hts_engine_API にファイルが作成されます。

つぎに、open_jtalk のコンパイルをします。

cd c:\temp\open_jtalk-1.09

nmake /f Makefile.mak
nmake /f Makefile.mak install

最後のほうに辞書を変換する文字列が表示されるときに、文字化けしているのが

気になりますが、不安な場合には Open JTalkに prebuild された辞書があるので、

それを使うこともできます。

これにより、c:\open_jtalk\bin\open_jtalk.exe が生成されます。


Voiceデータの入手

MMDAgent から

https://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.6/

から、MMDAgent_Example-1.6.zip をダウンロードして、Voice/mei/*.htvoice を c:\open_jtalk\bin\ にコピーしておきます。


実行テスト

日本語を入力したファイルを input.txt として c:\open_jtalk\bin に作成したとして

c:\open\jtalk\bin

open_jtalk -m mei_normal.htsvoice -x ../dic -ow output.wav input.txt

を実行してみます。これで、同じフォルダに output.wav が作成されていれば、それを

エクスプローラーからダブルクリックして再生されるかどうか確認します。


WindowsでPython によりOpenJTalkを実行

ubuntuでは、aplay のコマンドを使ってファイルを再生していました。Windowsでは、

winsound モジュールを利用します。また、今回のWindowsでのコンパイルでの辞書生成ではshift-jisとなっていましたので、python の内部エンコードから、stdin に渡す際に encoding を変換する必要があります。

以下に、サンプルプログラムを jtalk.py として c:\open_jtalk\bin に保存しておきます。

#coding: utf-8

# call OpenJTalk for windows
import subprocess
import winsound
from datetime import datetime

def jtalk(t):
# depend on your install folder
OPENJTALK_BINPATH = 'c:/open_jtalk/bin'
OPENJTALK_DICPATH = 'c:/open_jtalk/dic'
OPENJTALK_VOICEPATH = 'c:/open_jtalk/bin/mei_normal.htsvoice'
open_jtalk=[OPENJTALK_BINPATH + '/open_jtalk.exe']
mech=['-x',OPENJTALK_DICPATH]
htsvoice=['-m',OPENJTALK_VOICEPATH]
speed=['-r','1.0']
outwav=['-ow','open_jtalk.wav']
cmd=open_jtalk+mech+htsvoice+speed+outwav
c = subprocess.Popen(cmd,stdin=subprocess.PIPE)

# convert text encoding from utf-8 to shitf-jis
c.stdin.write(t.encode('shift-jis'))
c.stdin.close()
c.wait()

# play wav audio file with winsound module
winsound.PlaySound('open_jtalk.wav', winsound.SND_FILENAME)

def say_datetime():
d = datetime.now()
text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
print(text)
jtalk(text)

if __name__ == '__main__':
say_datetime()

これを実行します。anaconda python をインストールしているので、

python jtalk.py

で、現在の日時を発話します。


Pythonモジュールとして利用する場合

jtalk.py は、utf-8 エンコーディングで保存しています。

pythonをコマンドプロンプトから実行する場合には、日本語文字列がShift-JISのままになっていたり、統一されていません。

そこで、日本語を入力するときに先頭に u"にほんご" と、utf-8であることを示す u をつけます。

import jtalk

jtalk.jtalk(u'日本語を話します')