MMDAgentについてまとめる 音声認識・音声合成編

# この記事ついて
MMDAgentを利用する・開発する上でのあれこれをまとめた記事．前回記事からの続きになっているのでそちらも参照されたし．
前回：[MMDAgentについてまとめる 概要編](https://qiita.com/m-masaki72/items/6f72a76da03a52b63b0b)
次回：まだです

# MMDAgentの音声認識機・音声合成機
MMDAgentの音声認識機・音声合成機はそれぞれ，JuliusとOpenJTalkが採用されている．どちらも独立したアプリケーションでもあり，単体でも動作する．MMDAgent内ではそれらはdllとして紐付けられており，スレッド形式で動作するようになっている．

今回はJuliusとOpenJTalkのそれぞれを説明しつつ，MMDAgentとしてどのようなことができるのかをまとめる．特に音声対話コンテンツとしてこれらを見た時にどのような使い方ができるのかをチュートリアル的にまとめたい．

# Julius
[大語彙連続音声認識エンジン Julius - OSDN](http://julius.osdn.jp/)
[Julius - github](https://github.com/julius-speech/julius)

公式HPより引用
>Julius は，音声認識システムの開発・研究のためのオープンソースの高性能な汎用大語彙連続音声認識エンジンです． 数万語彙の連続音声認識を一般のPCやスマートフォン上でほぼ実時間で実行できる軽量さとコンパクトさを持っています．

Julisuは以下の特徴を持っている．

* Cで書かれていること改造やプラットフォームの移植しやすいこと
* リアルタイムな大語彙連続音声認識
* オープンソース
* カスタマイズが容易

またJuliusを動作させるためには以下のものが必要である．

* 音響モデル（音素HMM）
* 言語モデル（単語N-gram）
* 単語辞書

これらはJuliusにデフォルトで添付されているものがあるので，基本的にそれらを使えば良い．これらを入れ替えることで音声認識をカスタマイズできる．

各プラットフォームのビルドやチュートリアルをまとめた記事があったのでここにリンクを貼っておく．
[Julius/音声認識関連 超入門用自分用まとめ - Qiita](https://qiita.com/hiroyuki_hon/items/9e37d5e1fa8c6dff508d)

# OpenJTalk
[OpenJTalk公式サイト](http://open-jtalk.sourceforge.net/)
日本語の音声合成エンジン， 入力されたテキストをHMM音声合成によって自由に音声へと変換してくれる．入力パラメータを以下に示す．パラメータを変更することでより柔軟に音声をカスタムできる．

* 「a: all-pass constant」（オールパス値）
* 「b: postfiltering coefficient」（ポストフィルター係数）
* 「r: speech speed rate<strong」（スピーチ速度係数）
* 「fm :additional half-tone」（追加ハーフトーン）
* 「u: voiced/unvoiced threshold」（有声/無声境界値）
* 「jm: weight of GV for spectrum」（スペクトラム系列内変動の重み）
* 「jf: weight of GV for log F0」（F0系列内変動の重み）

Linux版はapt-getコマンドなどでインストールできる．windows版はVisual Studioを用いてビルドすれば実行できる．

# チュートリアル
ここでは実際にMMDAgentに組み込まれたこれらアプリケーションをカスタマイズする手順を説明する．より実践に即した形でどのファイルをどのようにいじるかを紹介したい．

## Juliusの音響モデル・言語モデルを変更したい
ここではJuliusの音響モデル・言語モデルを変更してみたい．Julius公式サイトではデフォルトのモデルだけでなく話し言葉モデル，英語モデルなどが配布されているのでそのあたりのものと変更してみたい．

[Juliusの音声認識パッケージ](http://julius.osdn.jp/index.php?q=dictation-kit.html)
上記リンクから話し言葉モデルキット (ssr-kit)をDLする．ファイル内は以下のようになっている．

* models/(言語モデルや音響モデルのファイル)
* *.exe(Juliusなどのツールバイナリ)
* main.jconf（HMM形式の設定ファイル）
* main.dnnconf (DNN形式の設定ファイル)

重要なのはmain.jconfである．これはJuliusのコンフィグファイルと音響・言語モデルパス指定ファイルである．MMDAgent内でもJuliusが動いているのでこのファイルを読みこませればMMDAgentでも同様に動作する．

さて次にMMDAgent側の設定である．MMDAgent側では次のように音響モデル・言語モデルが指定されている．デフォルトの言語モデル・音響モデルのファイルを以下のソースファイルで指定している．

```C:MMDAgent/Plugin_Julius/Plugin_Julius.cpp
//60行目あたりの記述
#difine PLUGINJULIUS_DEFAULTCONF "jconf_ja_JP.txt"
```

この「jconf_ja_JP.txt」は拡張子こそ違いはするものの先ほどのjuliusのコンフィグファイルであることに違いはない．

さてこの「jconf_ja_JP.txt」はその場所にあるかというと，「MMDAgent/Release/AppData/Julius」の中にある．MMDAgentではこのAppData以下にプラグインの設定ファイルをおいておく決まりがあるようだ．
ここに先ほどの音響モデル・言語モデルを置いておくと良いだろう．

では以上の手順をまとめる．

* 公式サイトなどからJulius対応の言語モデル・音響モデルを持ってくる．
* モデル一式+jconfファイルをMMDAgent/Relase/AppData/Julius以下にコピーする
* デフォルトにしておきたいjconfファイルを「jconf_ja_JP.txt」に李ネームする
* もしくはMMDAgent/Plugin_Julius/Plugin_Julius.cppにおいて，デフォルトのファイル名を指定しておく．

## Juliusに新たな単語を登録したい
[公式の解説](https://mmdagent.wordpress.com/2013/01/18/adding-recognition-words/)

MMDAgentではユーザの単語辞書を作成することで未知語への対応が可能である．例えば，「ラーメン鶴舞」とかいう架空のラーメン屋を辞書に登録することでjuliusはその単語を認識してくれるようになる．

登録に必要なのは以下の情報である．

1. その単語と似た単語 わからない場合は unk（アンノウンでいい）
1. 認識補正値 0~9(数が大きいほど認識しやすい)
1. 登録情報 基本的には1番目と同じ形式
1. システム出力値
1. 単語の読み

これらの情報を空白区切りで記述していくとそのように表示される．

以下にその例を示す．

```MMDAgent_Example.dic
 東京:トーキョー:東京:515 @1.0 鶴舞:ツルマイ:鶴舞:515 [鶴舞]   ts u r u m a i
    花子:ハナコ:花子:513     @2.0 メイ:メイ:メイ:513    [メイ]   m e i
    花子:ハナコ:花子:513     @2.0 メイ:メー:メイ:513    [メイ]   m e:
    <unk>                 @0.0 <unk>              [ヘロー]  h e r o:
```

このような単語辞書はMMDAgent/Release/MMDAgent.exeと同ファイルに設置する．MMDAgent.mdfの実行ファイルと同じ名前の.dicファイルが起動時に読み込まれるのでそのようにリネームしたものを設置する．

では手順をまとめる．

* 単語辞書作成に従い，任意の単語辞書を作成する
* 単語辞書を「*.dic」にリネームし，MMDAgent/Release以下に設置する
* 注意点として.dicファイルと.mdfは同じ名前であること．


## OpenJTalkの音響モデルを差し替えたい
ここのチュートリアルを参考にした．
[MMDAgentをミクの声にしてみよう！～僕を呼ぶ君の声～](http://d.hatena.ne.jp/sakurairo_nigawarai/20120331/1333180338)


# 参考文献
[萌え声を探せ！Open JTalkのパラメータをいろいろ変化させてみた！](http://moblog.absgexp.net/openjtalk/)
[Kana-to-phone mapping in recognition dictionary](https://mmdagent.wordpress.com/2013/02/01/kana-to-phone-mapping-in-recognition-dictionary/)