Python
C
AquesTalk

[C][python]LinuxでAquesTalkで棒読みする

Windows環境ではsoftalkなどで手軽に読み上げできますが、Linux環境ではwineなどで頑張らないと実行できません。
しかたないのでsoftalkが呼び出しているAquesTalkを直接呼び出してみます。

音声合成するだけならGoogle Translateのtext-to-speech APIをgTTSで呼び出すほうがお手軽です。
open-jtalkはインストールしようとすると私の環境ではコンフリクトするので解決が面倒で試していません。

やること

AquesTalk2のライブラリをcとpythonのコードから使用して音声合成します。

実行環境

  • Arch Linux
  • python3.6.5
  • AquesTalk2 Linux 2.3.0

AquesTalkのインストール

ダウンロード

ダウンロード | 株式会社アクエスト から評価版をダウンロードします。
本記事ではAquesTalk2を使用します。 AquesTalk, AquesTalk10での動作は未確認です。

なお、評価版では「ナ行、マ行」の音韻がすべて「ヌ」になるとのことです。

インストール

ダウンロードしたファイルに含まれるマニュアルの通りにライブラリをインストールします。
ライブラリのバージョンやlibとlib64どちらを使うかは適宜読み替えてください。

$ cd aqtk2-lnx-eva/lib64
$ cp libAquesTalk2Eva.so.2.3 /usr/lib
$ sudo ln -sf /usr/lib/libAquesTalk2Eva.so.2.3 /usr/lib/libAquesTalk2Eva.so.2
$ sudo ln -sf /usr/lib/libAquesTalk2Eva.so.2 /usr/lib/libAquesTalk2Eva.so
$ sudo /sbin/ldconfig -n /usr/lib 

AquesTalkのサンプルを実行

aqtk2-lnx-eva/samples/SampleTalk.c をコンパイルして実行します。
大体付属のマニュアルの通りで良いです。

エンコードに合わせてサンプルを修正

エンコードごとに音声合成関数が用意されているので、terminalなどのエンコードに合わせてSampleTalk.cを修正します。
ここではUTF-8を使います。
エンコードにあった関数が呼ばれていないと、正しく動作しません。

//  unsigned char *wav = AquesTalk2_Synthe_Euc(str, 100, &size, NULL);
    unsigned char *wav = AquesTalk2_Synthe_Utf8(str, 100, &size, NULL);

コンパイル

ライブラリとヘッダパスを指定してコンパイルします。

$ g++ -o SampleTalk samples/SampleTalk.c -lAquesTalk2Eva -Ilib64

実行

サンプルは標準入力からテキストを受け取って、標準出力にwav形式データを出力します。
「ゆっくりしていって」と読み上げてくれます。

$ echo "ゆっくりしていってね" | ./SampleTalk > sample.wav

pythonから実行

ctypesでライブラリを読み込んで実行します。
評価版付属のphontファイルを指定することで声質を変えることができます。
指定がないとデフォルトで動作します。デフォルトが結構聞き取りやすい。

from ctypes import *


def synthe_utf8(text, speed=100, file_phont=None):
    if file_phont is not None:
        with open(file_phont, 'rb') as f:
            phont = f.read()
    else:
        phont = None

    aqtk = cdll.LoadLibrary("libAquesTalk2Eva.so")
    aqtk.AquesTalk2_Synthe_Utf8.restype = POINTER(ARRAY(c_ubyte, 0))
    size=c_int(0)
    wav_p = aqtk.AquesTalk2_Synthe_Utf8(text.encode('utf-8'), speed, byref(size), phont)
    if not bool(wav_p):
        print("ERR:", size.value)
        return None
    wav_p = cast(wav_p, POINTER(ARRAY(c_ubyte, size.value)))
    wav = bytearray(wav_p.contents)
    aqtk.AquesTalk2_FreeWave(wav_p)
    return wav


if __name__ == '__main__':
    with open('./default.wav', 'wb') as f:
        wav = synthe_utf8(u"ゆっくりしていってね", speed=100)
        f.write(wav)
    with open('./yukkuri.wav', 'wb') as f:
        wav = synthe_utf8(u"ゆっくりしていってね", speed=100, file_phont='aqtk2-lnx-eva/phont/aq_yukkuri.phont')
        f.write(wav)

評価版では「ナ行、マ行」が「ぬ」になりますが、正しく読ませるにはライセンスの取得が必要のようです。
個人利用の場合は開発ライセンスを2000円弱で取得できます。(2018/6/9 現在)
頒布の規定など詳細は下記参照。
個人利用 ライセンス | 株式会社アクエスト