UbuntuやRaspberry Piでも利用可能な音声合成エンジンEdge-TTSの導入方法

先日来使用しているVOICEVOXですが、PCであればかなり高速に処理をすることができるとはいえ、リアルタイム性?というところではやはり処理時間がかかるため会話というところには使用が難しいと思いました。そこで、他にもなにかないかなと思い探してみることにしました。結果的にOpenJTalk一択かもしれないのですが、それ意外の可能性も捨てたくないですよね。

今回はEdge-TTSを使用してみることにします。EdgeというとWindowsの標準ブラウザというイメージがあるので、Windows意外では使用できないのでは?と思われる方もいるかと思いますが、今回使用するEdge-TTSはWindowsでの使用はもちろん、EdgeブラウザのインストールされていないLinux環境RaspberryPiでも使用できる点は非常に便利かなと思います。あとは、電子工作なでと状況に合わせた使用できるかという観点についても調べてみたいと思います。

【参考】

github.com

pypi.org

今回試してみた環境

今回試してみたのはUbuntu Desktop 22.04 LTSRaspberryPi OS最新版となります。

【RaspberryPi OSの実行環境】

Edge-TTSの導入方法

edge-ttsのインストールはPythonの開発環境があれば非常に簡単です。

Pythonのライブラリを含めて使用する場合にはpipコマンドから以下のようにすればOKです。

$ pip install edge-tts

また、プログラミングを行わないで単にコマンド実行で行うこともできるので、この利用法であれば、以下のコマンドでインストールができます。

$ pipx install edge-tts

ちなみにpipxとは

pipxは、Pythonで書かれたエンドユーザーアプリケーションのインストールと実行を支援するツールです。Pythonパッケージの実行バイナリを分離された仮想環境にインストールします。

実行できるコマンドを持ったPythonライブラリの実行をpipx用の仮想環境を作成することで、環境に影響させずにインストールができるものと認識しています。

# pipxインストール
$ pip install pipx

# CLIコマンドをインストール(例えばmypy)
$ pipx install mypy

インストール後の確認

今回はライブラリを含めた形でのインストールを行っています。

# インストール
$ pip install edge-tts

# 実行 -hオプションあり想定
$ edge-tts 
usage: edge-tts [-h] [-t TEXT] [-f FILE] [-v VOICE] [-l] [--rate RATE]
                [--volume VOLUME] [--pitch PITCH]
                [--words-in-cue WORDS_IN_CUE] [--write-media WRITE_MEDIA]
                [--write-subtitles WRITE_SUBTITLES] [--proxy PROXY]
edge-tts: error: one of the arguments -t/--text -f/--file -l/--list-voices is required

コマンドライン上からedge-ttsを起動し、音声合成に必要なパラメータをオプションスイッチで指定するだけで、音声合成を行うことができます。ちなみにedge-ttsマルチリンガルになっているので、ボイスモデルを変更することで日本語にも対応しています。

# ボイスモデルのリスト出力
$ edge-tts --list-voices
Name: af-ZA-AdriNeural
Gender: Female

(中略)

Name: ja-JP-KeitaNeural
Gender: Male

Name: ja-JP-NanamiNeural
Gender: Female

(以下略)

日本語に対応しているのは以下の2つです。

  • ja-JP-KeitaNeural(男性モデル)
  • ja-JP-NanamiNeural(女性モデル)

コマンドラインからは以下の様に実行を行います。この実行では--textオプションで指定した文字列をデフォルトの音声モデルでよみあげ、--write-mediaで指定したファイルに保存するとともに、--write-subtitleで指定したファイルに字幕ファイルも保存しています。

# 音声合成したファイルをmp3形式で保存し、vttの字幕ファイルも同時に生成する
$ edge-tts --text "Hello, world!" --write-media hello.mp3 --write-subtitles hello.vtt

# 日本語 の音声モデルを使用した場合
$ edge-tts --text "こんにちは、世界" -v ja-JP-NanamiNeural --write-media jhello.mp3 --write-subtitles jhello.vtt

Hello, world!

こんにちは、世界

vttファイルyoutubeなどでも使用可能な字幕ファイル形式となります。

生成されたvtt形式の字幕ファイル

$ cat hello.vtt
WEBVTT

00:00:00.100 --> 00:00:01.275
Hello world

$ cat jhello.vtt
WEBVTT

00:00:00.100 --> 00:00:01.500
こんにち は 世界

また、edge-ttsのインストールと同時に導入されたedge-playbackコマンドを使用すれば、/tmpにデータを作成してから、音声の再生まで行ってくれます。

# edge-playbackで音声合成したファイルを再生も可能
$ sudo apt install mpv # 再生するにはmpvが必要なので事前にインストール
$ edge-playback --text "Hello, world!"
$ edge-playback --text "こんにちは、世界" -v ja-JP-NanamiNeural

pythonのプログラムを行ってみる

基本的にはコマンドライン上から使用する方法と大きくはかわりません。ただし、テキストの場合には改行コードなどのエスケープ系の文字などはなくすため、スペース(SP)などに置換するほうがよいでしょう。また、このコードはasync/awaitの非同期処理を行っているので、その点はご注意ください。

吾輩はねこである(夏目漱石青空文庫より引用

import asyncio
import edge_tts
 
TEXT = """
吾輩は猫である。名前はまだ無い。
どこで生れたかとんと見当がつかぬ。
何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。
吾輩はここで始めて人間というものを見た。
しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。
""".replace("\n"," ")
 
VOICE = "ja-JP-KeitaNeural"
RATE = "-5%"
OUTPUT_FILE = "sample_Japanese_male.mp3"
 
async def amain() -> None:
    """Main function"""
    communicate = edge_tts.Communicate(TEXT, VOICE, rate=RATE)
    await communicate.save(OUTPUT_FILE)

if __name__ == "__main__":
    loop = asyncio.get_event_loop_policy().get_event_loop()
    try:
        loop.run_until_complete(amain())
    finally:
        loop.close()

生成されたデータは以下となります。

走れメロス太宰治青空文庫より引用

import asyncio
import edge_tts
 
TEXT = """
メロスは激怒した。
必ず、かの邪智暴虐の王を除かなければならぬと決意した。
メロスには政治がわからぬ。
メロスは、村の牧人である。笛を吹き、羊と遊んで暮して来た。
けれども邪悪に対しては、人一倍に敏感であった。
""".replace("\n"," ")
 
VOICE = "ja-JP-NanamiNeural"
RATE = "-10%"
OUTPUT_FILE = "sample_Japanese_female.mp3"

async def amain() -> None:
    """Main function"""
    communicate = edge_tts.Communicate(TEXT, VOICE, rate=RATE)
    await communicate.save(OUTPUT_FILE)

if __name__ == "__main__":
    loop = asyncio.get_event_loop_policy().get_event_loop()
    try:
        loop.run_until_complete(amain())
    finally:
        loop.close()

生成されたデータは以下となります。

生成時間は数秒はかかっているようですが、概ねリアルタイムに近い形でコミュニケーションを取ることはできそうです。 ただ、抑揚に関して言えばそこまでうまく音声合成ができるというわけではないので、品質それなりかなとは思います。

おわりに

今回はEdge-TTSという音声合成をしようしてみました。名称にEdgeとついてはいましたが、Windows、Edgeが入っていない処理系に限らず音声合成ができるという点では使いやすいなという印象でした。とはいえ、Wordなどで音声読み上げをする音声モデルと同じレベルのものが手軽に使えるのは本当にラッキーだなと思います。

参考

github.com

pypi.org

/* -----codeの行番号----- */