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

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

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

## Open JTalkのセットアップ
`apt-get`にて open-jtalk (1.07)をインストールします。

```bash:Terminal
$ 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あります。

```bash:Terminal
$ 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`ファイルを抽出

```bash:Terminal
$ unzip MMDAgent_Example-1.6.zip MMDAgent_Example-1.6/Voice/*
```

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

```bash:Terminal
$ sudo cp -r MMDAgent_Example-1.6/Voice/mei/ /usr/share/hts-voice
```

## Pythonによる再生

http://raspi.seesaa.net/article/415530289.html
を参考にさせていただきました。

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

```py: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()

```

実行テストでは、

```bash:Terminal
$ python jtalk.py
```

うまくいけば、現在の時刻を発話します
他のモジュールから利用する場合には、

```py:from_module_1.py
#coding: utf-8
import jtalk

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

# Windows で Open JTalkを設定する

Ubuntu では、`apt-get`すれば、すんなりインストールできましたが、
Windowsでは自分でビルドします。

## ソースコードの入手

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

- http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.09.tar.gz

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

- http://downloads.sourceforge.net/hts-engine/hts_engine_API-1.10.tar.gz

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

## VisualStudioでのコンパイル

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

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

```bat:cmd
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 のコンパイルをします。

```bat:cmd
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 に作成したとして

```bat:cmd
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 に保存しておきます。

``` py:jtalk.py
#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 をインストールしているので、

```bat:cmd
python jtalk.py
```

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

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

`jtalk.py` は、utf-8 エンコーディングで保存しています。
pythonをコマンドプロンプトから実行する場合には、日本語文字列がShift-JISのままになっていたり、統一されていません。

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

```py:from_module_2.py
import jtalk

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