ESPnetの日本語TTSモデルで簡易的にアクセント指定できるスクリプトを作ってみた。

# はじめに
この記事では、ESPnetの環境構築を終えている前提で使い方の説明をします。
ESPNetの環境構築については「[ESPnet2で始めるEnd-to-End音声処理](https://kan-bayashi.github.io/asj-espnet2-tutorial/#%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89)」や「[ESPnet document](https://espnet.github.io/espnet/installation.html)」を参考にしてください。

また、アクセント入力に対応しているのは**g2pにpyopenjtalk_accent_with_pauseが指定されているモデルのみ**となります。
平文入力はaccent_with_pauseでなくても動作します。

# 使い方
まず、google driveにおいてあるzipファイルを[こちら](https://drive.google.com/file/d/1sicMarckeNt2htOBOfvFUV18pjaDtStD/view?usp=sharing)からダウンロードしてください。
ダウンロードしたzipファイルを展開すると「Prosodic_text_tts」というフォルダができると思います。
このフォルダをttsレシピのフォルダに置いてください。
例：

```sas
$ espnet/egs2/jsut/tts1/Prosodic_text_tts
```

ターミナルを起動し、Prosodic_text_ttsまで移動して、
フォルダ内にあるシェルスクリプト「TTS_inference.sh」に実行権限を付与します。

```sas
/$ cd espnet/egs2/jsut/tts1/Prosodic_text_tts
/Prosodic_text_tts$ chmod +x TTS_inference.sh
```

引数に何も指定せずに「TTS_inference.sh」を実行すると、平文入力モードになります。

```sas
/Prosodic_text_tts$ ./TTS_inference.sh
python tts_inference_with_accent.py --model_tag "espnet/kan-bayashi_jsut_vits_accent_with_pause" --vocoder_tag "parallel_wavegan/jsut_hifigan.v1" 


download model =  kan-bayashi/jsut_tacotron2_accent_with_pause  

download vocoder =  parallel_wavegan/jsut_hifigan.v1 

モデルを読み込んでいます...

セリフを入力してください
漢字を含む日本語の文章が入力できます。

pyopenjtalk_accent_with_pauseによる解析結果：
かんじを^ ふく^む にほんごの^ ぶ^んしょーが にゅーりょく^ できま^す 

RTF = 0.043671
サンプリングレート 24000 で出力します。

```
生成された音声は、ttsフォルダの「generated_wav」に保存されます。
上記の実行で生成された音声がこちらです。

https://drive.google.com/file/d/1Q5TdfFWKaRRbqEAb6Q_8biQW3ekZfp__/preview

引数に「--prosodic true」と指定すると、アクセント入力モードになります。

```sas
/Prosodic_text_tts$ ./TTS_inference.sh --prosodic true
python tts_inference_with_accent.py --model_tag "espnet/kan-bayashi_jsut_vits_accent_with_pause" --vocoder_tag "parallel_wavegan/jsut_hifigan.v1" -p


download model =  kan-bayashi/jsut_tacotron2_accent_with_pause 

download vocoder =  parallel_wavegan/jsut_hifigan.v1 

モデルを読み込んでいます...

アクセント句がスペースで区切られた韻律記号(^)付きのセリフをすべてひらがなで入力してください。(スペースや記号もすべて全角で)

あくせんとを＾　こ＾のように　し＾てい　で＾きます
アクセント句分割：
['あくせんとを＾', 'こ＾のように', 'し＾てい', 'で＾きます']


モーラ分割：
['ア', 'ク', 'セ', 'ン', 'ト', 'ヲ']


音素 , アクセント核の位置(モーラ単位) , アクセント核からの距離(モーラ単位)：
a , [ 6 -5]
k , [ 6 -4]
U , [ 6 -4]
s , [ 6 -3]
e , [ 6 -3]
N , [ 6 -2]
t , [ 6 -1]
o , [ 6 -1]
o , [6 0]


モーラ分割：
['コ', 'ノ', 'ヨ', 'ウ', 'ニ']


音素 , アクセント核の位置(モーラ単位) , アクセント核からの距離(モーラ単位)：
k , [1 0]
o , [1 0]
n , [1 1]
o , [1 1]
y , [1 2]
o , [1 2]
o , [1 3]
n , [1 4]
i , [1 4]


モーラ分割：
['シ', 'テ', 'イ']


音素 , アクセント核の位置(モーラ単位) , アクセント核からの距離(モーラ単位)：
sh , [1 0]
I , [1 0]
t , [1 1]
e , [1 1]
i , [1 2]


モーラ分割：
['デ', 'キ', 'マ', 'ス']


音素 , アクセント核の位置(モーラ単位) , アクセント核からの距離(モーラ単位)：
d , [1 0]
e , [1 0]
k , [1 1]
i , [1 1]
m , [1 2]
a , [1 2]
s , [1 3]
U , [1 3]


RTF = 0.040864
サンプリングレート 24000 で出力します。


```
上記の実行で生成された音声がこちらです。

https://drive.google.com/file/d/1ytb_Nl1-DAwstEqRVqR0_VEaalCG7CeC/preview


# アクセントの指定方法
アクセントを指定する際は、

- すべて全角ひらがなで入力する
- アクセント句をスペースで区切る
- アクセント核の位置を'＾'で指定する

という規則に従って書きます。
アクセント句は、発音の音の高さの上下が一回だけ含まれる範囲です。
アクセント核は、発音の音の高さが低くなる位置(モーラ単位)です。
例：
湖が綺麗に見えます。

↓

みずうみがきれいにみえます
\_／￣＼＿\__＼＿＿＿____／￣\

↓

みずうみが　きれいに　みえます
\_／￣＼＿_　　＼＿＿＿　__／￣\

↓

みずう＾みが　き＾れいに　みえま＾す
\_／￣￣＼＿＿ 　＼＿＿＿　　__／￣\

入力：**みずう＾みが　き＾れいに　みえま＾す**

#終了コマンド
セリフの入力から音声ファイル生成までがwhileループとなっています。
終了したい場合は``exit``と入力してください。

#VITSモデルでの推論
``TTS_inference.sh``のオプション引数``--model_tag "espnet/kan-bayashi_jsut_vits_accent_with_pause"``
を指定すると、JSUTで学習したVITSモデルが試せます。VITSモデルではボコーダを必要としないので``--vocoder_tag``を指定する必要はありません。

#その他オプション
``--model_tag　<使いたいモデルのタグ>``

これは[espnet_model_zoo](https://github.com/espnet/espnet_model_zoo)の機能で、[Zenodo](https://zenodo.org/communities/espnet/)や[huggingface](https://huggingface.co/models?filter=espnet)で公開されているモデルをダウンロードして使う際に指定します。

デフォルトで``kan-bayashi/jsut_tacotron2_accent_with_pause``が指定されています

***

``--vocoder_tag <使いたいモデルのタグ>``

これも同様に、[espnet_model_zoo](https://github.com/espnet/espnet_model_zoo)でボコーダをダウンロードして使う際に指定します。

デフォルトで``parallel_wavegan/jsut_hifigan.v1``が指定されています。

***

``--train_config <使用するモデルのconfig.yamlのPath>``

ローカルで学習させたモデルを試したい場合に指定します。
``--model_file``と同時に指定してください。
相対で指定する場合は、ttsフォルダからの相対パスにしてください。

***

``--model_file <使用するモデルのPath>``

ローカルで学習させたモデルを試したい場合に指定します。
``--train_config``と同時に指定してください。
相対で指定する場合は、ttsフォルダからの相対パスにしてください。

***

``--vocoder_config <使用するモデルのconfig.yamlのPath>``

ローカルで学習させたモデルを試したい場合に指定します。
相対で指定する場合は、ttsフォルダからの相対パスにしてください。

***

``--vocoder_file <使用するモデルのPath>``

ローカルで学習させたモデルを試したい場合に指定します。
相対で指定する場合は、ttsフォルダからの相対パスにしてください。

***

``--fs <サンプリングレート>``

使用するモデルが対応しているサンプリングレートを指定してください。

デフォルトでは24000に設定されています。

# 最後に
pyopenjtalkの音素変換が優秀なので、ひらがなを漢字に直したり、カタカナにすることで調整できたりします。
なのでアクセント指定なんて使う場面ないかもしれませんが、あった方がマシだと思うので使えたら使っていただけると幸いです。