頑張らないために頑張る

ゆるく頑張ります

OpenJTalkを使って音声合成する

Posted at — Apr 28, 2022

概要

OpenJTalkとは、名古屋工業大学製の音声合成エンジンです。デモはここで実行できます。使い方は単純で、文字列を渡すと指定されたパラメータにしたがって音声合成を行ってくれます。指定できるオプションとしては話す速度や抑揚、声の高低などさまざま。サンプリングレートも指定できますが、このあたりは必要な人が限られるかも。

今回は、このOpenJTalk用の環境をDockerを使って構築しようと思います。

前提

OpenJTalkは、使用するプラットフォームによって環境構築の難易度に差が存在します。macOSやLinuxでの環境構築は比較的楽な反面、Windowsは自分自身でビルドしないといけないのがちょっと・・・いや、かなり面倒。

そんなわけで、ここではmacOSにてDockerコンテナを用いてOpenJTalkの環境を構築します。多分、WindowsでもWSLを用いるとか、Dockerコンテナ上で構築する方が楽だと思います。

ちなみに、ここではPython3のコンテナをベースに環境構築してますが、他で使っていたDockerfileを使いまわしただけで意味はありません_( _´ω`)_ペショ

環境構築

Dockerfileは、前述のとおりPythonのコンテナをベースとします。

FROM python:3.10-buster

ENV ACCEPT_EULA=Y

RUN apt-get update \
    && apt-get install -y g++ \
    apt-utils \
    apt-transport-https \
    gcc \
    build-essential \
    open-jtalk \
    open-jtalk-mecab-naist-jdic \
    && apt-get upgrade -y \
    && apt-get clean \
    && pip install --upgrade pip \
    && pip install --no-cache-dir \
    autopep8 \
    flake8 \
    && rm -rf /var/lib/apt/lists/*

ADD . /home/workdir

WORKDIR /home/workdir

COPY ./requirements.txt ${PWD}

RUN pip install -r requirements.txt

RUN 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

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

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

WORKDIR /home/workdir/src

Dockerfileを上記の内容で作成して、docker buildすれば環境はできあがりです。ね、簡単でしょ?

ちなみに、VS Codeを使っているなら「Reopen in container」を選択して、コンテナの環境構築を行ってもOK。こっちのほうが、環境構築後にコンテナへのログインをせずともVS Codeのコンソールで音声合成のコマンド発行できるので、少しだけ早いです。

flask

なお、requirements.txtは上記の内容で作成してます。作成してますっていうよりは、単純に流用してます。これは、前述のとおりFlaskを使ってサーバーを立ててた他のDockerfileを流用しているせいで、単純に音声合成だけしたいのならPythonを基準にしてDockerfileを作成する必要ないです。OSだけ指定して、環境構築すればいいわけなので。DebianならBusterかBullseye、Ubuntuあたりで環境構築しておけば特段困ることはないと思います。

コンテナのビルドが完了したら試しに音声合成を行ってみましょう。

echo こんにちは、世界。 | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic/ -m /usr/share/hts-voice/mei_normal.htsvoice -ow hello.wav

上記を実行すると、カレントフォルダにhallo.wavというファイルが生成されるはずです。これを再生すれば、合成された音声で「こんにちは、世界」と言われるはず。

これで環境構築は完了です。

解説

OpenJTalkで音声合成を行うために必要なファイルは3種類です。

前述のDockerfile中で上記のファイルをインストールしているのは、open-jtalkopen-jtalk-mecab-naist-jdicapt-getしている部分に当たります。

「あれ、3種類のファイルが必要って言ったのに2つしかなくね?」と思ったあなたは鋭い。その通りで、この2つは「OpenJTalk本体」と「辞書ファイル」に当たるものです。つまり、apt-getでは音声ファイルをインストールしていないのです。

なんでかって?

# apt-get install hts-voice-nitech-jp-atr503-m001
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package hts-voice-nitech-jp-atr503-m001 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'hts-voice-nitech-jp-atr503-m001' has no installation candidate

その理由がこのエラー。

音声ファイルであるhts-voice-nitech-jp-atr503-m001は、apt-getでインストールしようとしても現在(2022年4月末)のところなぜかエラーになります。メッセージを見ると、「なんか見つからないんだよねー。でも、他のパッケージから参照されているんだわコレ。だから、たぶん廃止されたか他のソースからじゃないと入手できないんじゃない?」と言われているようです。

ただ、音声ファイルはこの1種類だけというわけではなく、OpenJTalkに利用できるいろんな声質の音声ファイルが存在しています。実際、今回はこのファイルを利用せず後述する別の音声ファイルを導入するので、ここでhts-voice-nitech-jp-atr503-m001を導入しなくても何ら問題ありません。そのため、エラーの原因について詳しくは調査してないんだなぁ、コレが。一応パッケージの情報を見てみると、存在自体はしているらしいんですけどねぇ・・・。

じゃあ、hts-voice-nitech-jp-atr503-m001以外の音声ファイルはどうやって調達するのよ?という話になるわけです。

RUN 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

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

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

上記の3行が、その音声ファイルを導入している部分に当たります。wgetで音声ファイルを入手し、unzipで解凍・展開します。展開した音声ファイルを/usr/share/hts-voiceに格納すると、OpenJTalkを用いた音声合成が可能な環境の完成です。

なお、参考にした「合成音声「Open JTalk」でハマったこと」では-yオプションをapt-getに付与することで、音声ファイル入手時のエラーを回避しているようです。ただ、そもそもエラー内容が異なる(参考先ではE: Unable to locate package hts-voice-nitech-jp-atr503-m001)ためか今回のケースでは回避できませんでした。うーん、謎。

オプション

コマンドで音声合成を実行する際、さまざまなオプションを設定できます。オプションの一覧は、open_jtalkに引数を指定しない状態で実行すると表示されます。

# open_jtalk
The Japanese TTS System "Open JTalk"
Version 1.10 (http://open-jtalk.sourceforge.net/)
Copyright (C) 2008-2016 Nagoya Institute of Technology
All rights reserved.

The HMM-Based Speech Synthesis Engine "hts_engine API"
Version 1.10 (http://hts-engine.sourceforge.net/)
Copyright (C) 2001-2015 Nagoya Institute of Technology
              2001-2008 Tokyo Institute of Technology
All rights reserved.

Yet Another Part-of-Speech and Morphological Analyzer "Mecab"
Version 0.996 (http://mecab.sourceforge.net/)
Copyright (C) 2001-2008 Taku Kudo
              2004-2008 Nippon Telegraph and Telephone Corporation
All rights reserved.

NAIST Japanese Dictionary
Version 0.6.1-20090630 (http://naist-jdic.sourceforge.jp/)
Copyright (C) 2009 Nara Institute of Science and Technology
All rights reserved.

UniDic
Version 2.2.0 (https://unidic.ninjal.ac.jp/)
Copyright (C) 2011-2017 The UniDic Consortium
All rights reserved.

open_jtalk - The Japanese TTS system "Open JTalk"

  usage:
       open_jtalk [ options ] [ infile ] 
  options:                                                                   [  def][ min-- max]
    -x  dir        : dictionary directory                                    [  N/A]
    -m  htsvoice   : HTS voice files                                         [  N/A]
    -ow s          : filename of output wav audio (generated speech)         [  N/A]
    -ot s          : filename of output trace information                    [  N/A]
    -s  i          : sampling frequency                                      [ auto][   1--    ]
    -p  i          : frame period (point)                                    [ auto][   1--    ]
    -a  f          : all-pass constant                                       [ auto][ 0.0-- 1.0]
    -b  f          : postfiltering coefficient                               [  0.0][ 0.0-- 1.0]
    -r  f          : speech speed rate                                       [  1.0][ 0.0--    ]
    -fm f          : additional half-tone                                    [  0.0][    --    ]
    -u  f          : voiced/unvoiced threshold                               [  0.5][ 0.0-- 1.0]
    -jm f          : weight of GV for spectrum                               [  1.0][ 0.0--    ]
    -jf f          : weight of GV for log F0                                 [  1.0][ 0.0--    ]
    -g  f          : volume (dB)                                             [  0.0][    --    ]
    -z  i          : audio buffer size (if i==0, turn off)                   [    0][   0--    ]
  infile:
    text file                                                                [stdin]

たくさんオプションがありますが、基本的には設定に関するものとファイル出力に関するものだけ指定すれば良いはずです。

設定に関するオプション

オプション 内容 指定例
-x 辞書を指定する。辞書が存在するフォルダを指定する。必須。 -x /var/lib/mecab/dic/open-jtalk/naist-jdic/
-m 音声ファイルを指定する。ファイルそのものを指定する。必須。 -m /usr/share/hts-voice/mei_bashful.htsvoice

上記の2オプションは指定が必須です。

ファイル出力に関するオプション

オプション 内容 指定例
-ow 出力先Waveファイルを指定する。指定が必須のオプション。 -ow hoge.wav
-ot ログファイルの出力先を指定する。指定は任意。 -ot generate_log.log

-otのログファイル出力は、形態素解析などの結果が出力されます。どんな解析や音声合成をしているか、気になる人は見てみるといいかも。

音声合成に関するオプション

オプション 内容 指定例
-s サンプリングレートを指定する。 -s 44100
-p フレーム周期を指定する。 -p 220
-a オールパス値を指定する。値が小さくなるほどヘリウムガスを吸ったような声になる。 -a 0.5
-b ポストフィルターの値を指定する。1に近いほどなめらかな発声。 -b 0.9
-r 話す速度を指定する。数字が小さいほど遅い。 -r 1.2
-fm 追加ハーフトーンを指定する。数字が小さいほど「落ち着いた」声質。 -fm
-u 音声の有無に関する閾値を指定する。 -u
-jm スペクトラム変動の重みを指定する。声量に関係する。 -jm 1.0
-jf F0変動の重みを指定する。値が小さいほど抑揚のない声質になる。 -jf 1.0
-g 音量をデシベルで指定する。 -g 10
-z バッファサイズを指定する。 -z 0

基本的にはデフォルト値で音声合成して問題ないと思います。強いていうなら、デフォルトでは音声速度が若干遅く感じるので、-rで調整してもいいかもしれません。

reference

  1. OpenJTalkデモページ
  2. OpenJTalkのwikipediaページ
  3. 音声合成エンジン OpenJTalk のチューニング
  4. 萌え声を探せ!Open JTalkのパラメータをいろいろ変化させてみた!
  5. 合成音声「Open JTalk」でハマったこと
  6. OpenJTalk + python で日本語テキストを発話
  7. Open JTalkLinux 日本語音声合成エンジン
  8. Pythonでデバイスを制御しよう 第1回:日本語テキストを読み上げる(4) OpenJTalkを使ってオフラインで音声合成
comments powered by Disqus