トップ > 【Unity】VOICEVOXエンジンでリアルタイム音声合成する方法を紹介します!
更新日 2023/4/17

【Unity】VOICEVOXエンジンでリアルタイム音声合成する方法を紹介します!

VOICEVOXとはフリーの音声合成ツールです。エディターとエンジンとコア部分に分けられて提供されています。今回はエンジン部分を利用して文字列から音声合成されたWAVEデータを作成しUnity上でリアルタイム再生するプログラムを実装します。VOICEVOXの詳細は本家サイトを参照してください。


VOICEVOXコアを使った音声合成する記事を書きましたのでこちらもあわせてご覧下さい。

【Unity】VOICEVOXコアでリアルタイム音声合成する方法を紹介します!2023/4/11

VOICEVOXエンジン

VOICEVOXエンジンを利用してリアルタイム音声合成をします。本家サイトのダウンロードページから最新版のZipパッケージをダウンロードして解凍します。

VoicevoxEngine_Location

run.exeをダブルクリックしてエンジンを起動させます。

VoicevoxEngine_Run

エンジンは127.0.0.1ポート番号50021にHTTPリクエストを送ることで利用できます。エンジンを起動した状態で下記アドレスからドキュメントとスピーカー(話し手)一覧を確認できます。

・ドキュメント http://127.0.0.1:50021/docs

・スピーカー http://127.0.0.1:50021/speakers


ここからはエンジンを利用して音声合成する方法を紹介していきます。HTTPリクエストにはHttpClientをシングルトン化したHttpClientManagerを利用しますので詳細は下記記事をご覧ください。

http_client_manager
【Unity】HttpClientをシングルトン化したHttpClientManagerの実装方法について紹介します!2024/3/1

audio_query

audio_queryで音声合成用のクエリデータを作成します。POSTリクエストでパラメーターにはテキストとスピーカーを渡します。受け取ったJSON形式のデータは音声合成するときに使用します。

http://127.0.0.1:50021/audio_query?text=こんにちは&speaker=0

以上を踏まえて非同期メソッドAudioQueryAsyncを実装します。

async Task<string> AudioQueryAsync(string text, int speaker)
{
string uri = "http://127.0.0.1:50021/audio_query?text=" + text + "&speaker=" + speaker;
var task = await HttpClientManager.Instance.PostAsync(uri);
return await task.Content.ReadAsStringAsync();
}

synthesis

synthesisで音声を合成します。POSTリクエストでパラメーターにはスピーカー番号を、コンテンツにはaudio_queryで作成したクエリデータを渡します 。音声合成された結果はWAV形式のバイト配列で受け取れます。そのままファイルに保存すればWAVファイルとして使用できます。

http://127.0.0.1:50021/synthesis?speaker=0

以上を踏まえて音声合成する非同期メソッドSynthesisAsyncを実装します。

async Task<byte[]> SynthesisAsync(int speaker, string data)
{
string uri = "http://127.0.0.1:50021/synthesis?speaker=" + speaker;
var content = new StringContent(data, Encoding.UTF8, "application/json");
var task = await HttpClientManager.Instance.PostAsync(uri, content);
return await task.Content.ReadAsByteArrayAsync();
}

音声合成メソッドの作成

AudioQueryAsyncとSynthesisAsyncをまとめてテキストとスピーカーからWAVバイナリを作成する非同期メソッドVoiceAsyncを実装します。

async Task<byte[]> VoiceAsync(string text, int speaker)
{
string data = await AudioQueryAsync(text, speaker);
return await SynthesisAsync(speaker, data);
}

WAVのリアルタイム再生

UnityではWAVデータのバイト配列からAudioClipをリアルタイムで作成する機能を提供していませんので、はなちるのマイノート様で紹介されている方法を利用させていただきます。ソースコードはGitHubで公開されているものをお借りします。

GitHubのパス

hanachiru/Wav2AudioClipSample/Assets/Scripts/Wav.cs

以下のコードでバイト配列からAudioClipを作成することができます。

byte[] data = ...;
AudioClip clip = Wav.ToAudioClip(data, "test");

AudioClipはAudioSourceで再生することができます。

AudioSource source = ...;
source.PlayOneShot(clip);

確認用クラスの実装

今までのコードをまとめた確認用クラスを作ります。コードを簡潔にするためにタスクをウェイトしています。エラー処理もしていません。本来ならコルーチンなどでタスクの終了を検知するようにしてメインスレッドをブロックせずに実装するのが良いでしょう。

VoicevoxTest.cs

using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class VoicevoxTest : MonoBehaviour
{
void Start()
{
string text = "こんにちは";
Task<byte[]> task = Task.Run(() => VoiceAsync(text, 0));
task.Wait();
AudioClip clip = Wav.ToAudioClip(task.Result, text);
AudioSource source = gameObject.AddComponent<AudioSource>();
source.PlayOneShot(clip);
}

async Task<string> AudioQueryAsync(string text, int speaker)
{
string uri = "http://127.0.0.1:50021/audio_query?text=" + text + "&speaker=" + speaker;
var task = await HttpClientManager.Instance.PostAsync(uri);
return await task.Content.ReadAsStringAsync();
}

async Task<byte[]> SynthesisAsync(int speaker, string data)
{
string uri = "http://127.0.0.1:50021/synthesis?speaker=" + speaker;
var content = new StringContent(data, Encoding.UTF8, "application/json");
var task = await HttpClientManager.Instance.PostAsync(uri, content);
return await task.Content.ReadAsByteArrayAsync();
}

async Task<byte[]> VoiceAsync(string text, int speaker)
{
string data = await AudioQueryAsync(text, speaker);
return await SynthesisAsync(speaker, data);
}
}

確認用シーンの作成と実行

確認用シーンを作成し、Unityを実行して動作を確認します。

用意するスクリプトの確認

用意するスクリプトは以下の画像の通りです。

Voicevox_Scripts

DontDestroyOnLoadはゲームオブジェクトを常駐化させるためのスクリプトです。

resident_object
【Unity】ゲームオブジェクトを常駐化させるための方法を紹介します!2024/3/1

HttpClientManagerはHttpClientをシングルトン化したスクリプトです。

http_client_manager
【Unity】HttpClientをシングルトン化したHttpClientManagerの実装方法について紹介します!2024/3/1

SingletonMonoBehaviourはシングルトンコンポーネントを実装するためのスクリプトです。

singleton
【Unity】シングルトンパターンを実装する方法を紹介します!2024/3/1

シーンの構成

ゲームオブジェクトを作成しインスペクターで先程作ったVoicevoxTestコンポーネントを追加します。

Voicevox_TestObject

常駐用のゲームオブジェクトを作成しインスペクターからDontDestroyOnLoadHttpClientManagerを追加します。

Voicevox_ResidentObject

Unityを実行して「こんにちは」という音声が再生されるか確認して下さい。VOICEVOXエンジンの起動をお忘れなく。

リアルタイムで音声合成するプログラムを作成することができました。
音声によるナビゲーションツールなどに利用できそうですね。


ファイルに保存する方法

リアルタイムで再生することを解説しましたがファイルに保存すればWAVファイルとして使えます。

string text = "こんにちは";
Task<byte[]> task = Task.Run(() => VoiceAsync(text, 0));
task.Wait();
File.WriteAllBytes(text+".wav", task.Result);

プライベートネットワークでエンジンを利用する方法

プライベートネットワークでVoicevoxエンジンを利用するにはエンジンを起動するパソコンのIPアドレスを固定する必要があります。

コントロールパネル > ネットワークとインターネット > ネットワーク接続

イーサネットのプロパティをクリックします。

Voicevox_FixedIP1

インターネットプロトコルバージョン4(TCP/IPv4)を選択してプロパティ(R)ボタンをクリックします。

Voicevox_FixedIP2

次のIPアドレスを使う(S)を選択して必要な情報を入力します。使用しているネットワーク環境に合わせて入力して下さい。

Voicevox_FixedIP3

これでエンジンを起動するパソコンのIPアドレスを192.168.11.100に固定できました。

続いてホストオプションを追加してエンジンを起動します。

run.exe --host 192.168.11.100

最後にエンジンを起動したパソコン以外からhttp://192.168.11.100:50021/docsにアクセスしてドキュメントが見えるか確認して下さい。

Voicevox_FixedIP4

スピーカーID一覧

VOICEVOX Ver. 0.14.5

ID名前スタイル
0四国めたんあまあま
1ずんだもんあまあま
2四国めたんノーマル
3ずんだもんノーマル
4四国めたんセクシー
5ずんだもんセクシー
6四国めたんツンツン
7ずんだもんツンツン
8春日部つむぎノーマル
9波音リツノーマル
10雨晴はうノーマル
11玄野武宏ノーマル
12白上虎太郎ふつう
13青山龍星ノーマル
14冥鳴ひまりノーマル
15九州そらあまあま
16九州そらノーマル
17九州そらセクシー
18九州そらツンツン
19九州そらささやき
20もち子さんノーマル
21剣崎雌雄ノーマル
22ずんだもんささやき
23WhiteCULノーマル
24WhiteCULたのしい
25WhiteCULかなしい
26WhiteCULびえーん
27後鬼人間ver.
28後鬼ぬいぐるみver.
29No.7ノーマル
30No.7アナウンス
31No.7読み聞かせ
32白上虎太郎わーい
33白上虎太郎びくびく
34白上虎太郎おこ
35白上虎太郎びえーん
36四国めたんささやき
37四国めたんヒソヒソ
38ずんだもんヒソヒソ
39玄野武宏喜び
40玄野武宏ツンギレ
41玄野武宏悲しみ
42ちび式じいノーマル
43櫻歌ミコノーマル
44櫻歌ミコ第二形態
45櫻歌ミコロリ
46小夜/SAYOノーマル
47ナースロボ_タイプTノーマル
48ナースロボ_タイプT楽々
49ナースロボ_タイプT恐怖
50ナースロボ_タイプT内緒話
51†聖騎士 紅桜†ノーマル
52雀松朱司ノーマル
53麒ヶ島宗麟ノーマル

関連ページ


Copyright ©2022 - 2024 うにぉらぼ