ZUNDAMON ENGINE 5 爆誕（VOICEVOX Engine for UE5プラグインを公開しました）

<font color="Green">ZUNDAMON ENGINE 5　爆誕</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/f7009e21-a6a9-7d30-605b-45f352fb72a1.png)

[Unreal Engine (UE) Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ue) 1日目です。

ネタです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">アンリアルエンジンを読み上げるずんだもん<br>VOICEVOX:ずんだもん <a href="https://t.co/usfRdJGDtT">pic.twitter.com/usfRdJGDtT</a></p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/1597914299833683969?ref_src=twsrc%5Etfw">November 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

とある日、日本酒を１合ぐらいキメた後に、UEのツールチップやチュートリアルが、ずんだもんの声ならやる気出るんじゃないか、と思ってVOICEVOX COREライブラリをUE5で読み込めないか調査したら、思ったよりもすんなり出来てしまったのでプラグインとして公開します。

品質は中品質にギリ届くかぐらいです。許してください。

# 成果物

まずは成果物です。
画像ではわかりくいので、以下の動画が成果になります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ZUNDAMON ENGINE５ 爆誕 <br>まぁ、ただ単純にずんだもんにツールチップの文言を読んでもらうだけなんですけどｗ<br>これが12/1のアドカレに書くネタです。 <a href="https://twitter.com/hashtag/UE5?src=hash&amp;ref_src=twsrc%5Etfw">#UE5</a> <a href="https://t.co/xUdIAXHRXg">pic.twitter.com/xUdIAXHRXg</a></p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/1597492125884903424?ref_src=twsrc%5Etfw">November 29, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

11月上旬で思いついてノリで開発した割には動いているので、VOICEVOX COREは素晴らしいです。

プラグインはGithubに公開してます。

https://github.com/YuukiOgino/VoicevoxEngineForUE

# VoicevoxToolTipTextSpeechプラグイン

ZUNDAMON ENGINE 5　ことVoicevoxToolTipTextSpeechプラグインです。
ネタで作ったものです。そのため、大雑把に書いてます。

## 概要

Naotsunさんの[Slateのテキストに無理やり(？)アクセスする方法](https://qiita.com/Naotsun/items/5fa305cf91c3dec55c16)で公開されたサンプルコードを、一部VOICEVOX COREのAPIを実行するように修正を加えたものになります。

https://qiita.com/Naotsun/items/5fa305cf91c3dec55c16

https://github.com/Naotsun19B/SlateTextAccessor

## 対応プラットフォーム&エンジンバージョン

* Windows10(11は試してないですが、多分動きます。)
* UnrealEngine5.0

## 使い方

使い方の説明です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/e4ab9f87-b0d3-6d9b-52fd-eb7eff6c6c6f.png)
ツールチップが表示されているときにキーボードのPボタンを押すと、ずんだもんのボイスでToolTipのテキストを読み上げます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/c44c6302-17ed-b6c3-cc69-20a05b778539.png)
コンテンツブラウザ、とずんだもんの声で読み上げてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/08fe387d-901e-1d91-63c8-40939ad08561.png)
おまけに英語は読めないので、上記のようにほとんどの英単語はアルファベットの単語ごとでしゃべります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">UnrealEngineを読みあげるずんだもん。<br>かわいいですね。<br><br>VOICEVOX:ずんだもん <a href="https://t.co/NWoISUedCJ">pic.twitter.com/NWoISUedCJ</a></p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/1597914307001724930?ref_src=twsrc%5Etfw">November 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ずんだもんのボイスなら許せそうですｗ

## 注意事項

見てわかる通り非常に無駄な機能で、ジョークグッズの類です。

ソースコードですがサンプルコードの9割弱そのまま利用させていただいたため再配布の形になるのと、サンプルコードにライセンス表記がなかったため、念のため一部自分が修正を加えたソースコードのみ公開しています。

そのため、配布したVoicevoxToolTipTextSpeechプラグインは必要なソースがごっそり抜けてるためビルドが通りません。
一応公開されたサンプルコードの一部を移植し、多少修正を加えれば動くと思うので興味があれば触ってみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/edbac29d-dbd9-cd29-91e9-5ea9defbfa99.png)
上記にあるSlateTextAccessorsフォルダとUtilitiesフォルダを移植、エラーが起きている部分を修正を行えば動くはずです。

:::note alert
VoicevoxToolTipTextSpeechプラグインに関してはサポートを行いません。
:::

# VOICEVOX Engine for UE5プラグイン

本題です。
[VOICEVOX Engine for UE5プラグイン](https://github.com/YuukiOgino/VoicevoxEngineForUE)について説明です。

# 概要

VOICEVOX Engine for UE5プラグインはヒホさんが制作・公開されている、 VOICEVOX Engineの **非公式** UnrealEngine5対応版、VOICEVOX COREをUE5で使用するためのプラグインです。

とはいえ、現状ではVOICEVOX COREのAPIしかアクセスしかできませんが...、一応BlueprintノードでアクセスできるようにしたのでEngineと言い張りますｗ

## 対応プラットフォーム&エンジンバージョン

* Windows10(11は試してないですが、多分動きます。)
* UnrealEngine5.0

:::note info
VOICEVOX COREライブラリはMac及びLinux対応済みなので、動作確認はしてませんが恐らく読み込めるとは思います。
動作確認したのがWindows10のみなので、公開版ではWindows以外を非対応としています。
:::

開発中に5.1がリリースされてしまったので、こちらは勉強がてら対応します...。

# プラグイン使用準備

:::note info
最低限プラグインのビルドが自力で出来る、という前提で、他に必要なものを記載しています。
:::

## VOICEVOX CORE、Open JTalk、ONNX Runtime、の取得

VOICEVOX COREのReadMEに従って、最低限CPUモードの動作に必要なライブラリを取得します。

以下からVOICEVOXのCOREライブラリを取得してください。

https://github.com/VOICEVOX/voicevox_core

:::note info
プラグインは[VOICEVOX CORE 0.13.2](https://github.com/VOICEVOX/voicevox_core/releases/tag/0.13.2)を元に開発しました。
:::

上記からダウンロードしたコアライブラリの zip を、適当なディレクトリで展開します。

:::note info
CUDA 版、DirectML版は、必ず対応しているCOREライブラリのzipファイルをダウンロードしてください。
:::

次に[Open JTalk から配布されている辞書ファイル](https://sourceforge.net/projects/open-jtalk/files/Dictionary/open_jtalk_dic-1.11/open_jtalk_dic_utf_8-1.11.tar.gz/download?use_mirror=jaist) をダウンロードして、上記コアライブラリを展開したディレクトリに展開してください。

https://sourceforge.net/projects/open-jtalk/files/Dictionary/open_jtalk_dic-1.11/open_jtalk_dic_utf_8-1.11.tar.gz/download?use_mirror=jaist

:::note info
プラグインではopen_jtalk_dic_utf_8-1.11を使用しています。
:::

続いてONNX Runtimeは以下からダウンロードしてください。

https://github.com/microsoft/onnxruntime/releases/tag/v1.13.1

:::note info
基本的に最新版で問題ないはずです。
もし、エラーが起きる場合はv1.13.1以前のバージョンで試してみてください。
:::

~~VOICEVOX CORE Downloaderを利用してダウンロードする場合は、[こちら](https://github.com/VOICEVOX/voicevox_core/blob/main/docs/downloads/download.md#cuda)を見てください。~~

https://github.com/VOICEVOX/voicevox_core/blob/main/docs/downloads/download.md#cuda

:::note info
現状、Downloaderは正常実行できない旨のアナウンスが出ているので、リリースノートからダウンロードしてください。
https://github.com/VOICEVOX/voicevox_core/issues/271
:::

## プラグインへ展開

展開したCOREライブラリを、以下のフォルダに配置してください。

```
【プロジェクトフォルダ】\Plugins\VoicevoxEngine\Source\ThirdParty\VoicevoxCore\x64\VoicevoxCore
```

※格納例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/33be4503-896f-3d38-d27c-0ce3cab73ea4.png)

あとはUEのプラグインビルドの方法にしたがってビルドを行ってください。

:::note info
プラグインのビルドがわからない場合、[公式ドキュメント](https://docs.unrealengine.com/5.0/ja/plugins-in-unreal-engine/)を見たり、「UE5 プラグイン　ビルド」で検索してください。
:::

# 各ヘッダーファイルについて

プラグインに作成した各ヘッダーファイルの説明です。
cppファイルも公開しているので、セットで見てください。

- VoicevoxCoreUtil.h
VOICEVOX COREのAPIへ接続するためのUtilクラスを記載しています。
C++で利用する場合はUtilから各VOICEVOX CORE APIを呼ぶことを想定しています。

- VoicevoxAsyncTask.h
VOICE VOX COREのAPIを実行するBlueprint公開用ノードをまとめています。
大半のAPIが処理に時間がかかるため、ほとんどLatentノードにしています。

# 各クラスについて

各クラスの説明です。
主にC++でアクセスすることが多い、VoicevoxCoreUtilクラスを記載しています。

※実装例

```cpp:FVoicevoxToolTipTextSpeechModule.CPP
// Copyright Yuuki Ogino. All Rights Reserved.

#include "VoicevoxToolTipTextSpeech.h"

#include "VoicevoxCoreUtil.h"
#if PLATFORM_WINDOWS
#include "Windows/WindowsHWrapper.h"
#include <playsoundapi.h>
#endif


#define LOCTEXT_NAMESPACE "FVoicevoxToolTipTextSpeechModule"

void FVoicevoxToolTipTextSpeechModule::StartupModule()
{
	FVoicevoxCoreUtil::Initialize(false);
	constexpr int SpeakerId = static_cast<int64>(ESpeakerType::Zundamon);
	int OutputBinarySize = 0;
	uint8* OutputWAV = FVoicevoxCoreUtil::RunTextToSpeech(SpeakerId, TEXT("アンリアルエンジン、ファイブ"), OutputBinarySize);
#if PLATFORM_WINDOWS
	PlaySound(reinterpret_cast<LPCTSTR>(OutputWAV), nullptr, SND_MEMORY);
#endif
	FVoicevoxCoreUtil::WavFree(OutputWAV);	

}

void FVoicevoxToolTipTextSpeechModule::ShutdownModule()
{
	FVoicevoxCoreUtil::Finalize();
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FVoicevoxToolTipTextSpeechModule, VoicevoxToolTipTextSpeech)
```
モジュールクラスに組み込むと起動時にボイスを再生してくれます。

## C++でプラグインを使用する

Build.csのPublicDependencyModuleNames、もしくはPrivateDependencyModuleNamesに **VoicevoxEngine** を追加してください。

```cpp:Sample.Build.cs
PublicDependencyModuleNames.AddRange(
    new string[]
    {
        "Core",
        "InputCore",
        "CoreUObject",
        "Engine"
    }
);

PrivateDependencyModuleNames.AddRange(
    new string[]
    {
        "VoicevoxEngine"
    }
);
```

## FVoicevoxCoreUtil::Initialize
VOICEVOX COERの初期化を行います。
VOICEVOX CORE APIのiniitialize～voicevox_load_openjtalk_dictを呼び出して初期します。

```cpp:Sample.CPP

	UE::Tasks::Launch(TEXT("VoicevoxCoreTask"), [&]()
	{
		if (FVoicevoxCoreUtil::Initialize(bUseGPU, CPUNumThreads, false))
		{
			// 成功時の処理を記述
		}
		else
		{
			// 失敗時の処理を記述
		}
	});
```

bUseGPUをtrueにするとGPUモードで初期化します。
~~GPU対応版のCOREライブラリ、かつ対応するGPU（nvidia製GPUを搭載したWindows, Linux PCではCUDA、DirectX12に対応したGPUを搭載したWindows PCではDirectML）がPCに組み込まれていれば使用できます。~~

:::note alert
GPU対応のCOREライブラリを読み込んでテストしたのですが、バージョン0.13.2でエラーでクラッシュ、もしくはGPUモードに切り替わらない現象を確認したため、当面の間はGPU切り替えは非対応とします。
bUseGPUは常にfalseを設定し、CPUモードで実行してください。
:::

CPUのみのライブラリでbUseGPUをtrueにすると、エラーが返ってきます。

:::note info
メインスレッドが止まる処理のため、上記の通り非同期で処理することを推奨しています。
:::

こちらは何度も初期化処理を行って問題ないですが、text to speech実行時は最後に初期化した設定で行います。


## FVoicevoxCoreUtil::Finalize
VOICEVOX COERの終了処理を行います。
VOICEVOX CORE APIのfinalizeを呼び出して終了処理を行っています。

```cpp:Sample.CPP
FVoicevoxCoreUtil::Finalize();
```

こちらも何度も終了処理を行って問題ないですが、Finalizeを呼び出した後はtext to speechを実行しないようにしてください。

## FVoicevoxCoreUtil::LoadModel
スピーカーIDを元にモデルのロードを行います。
VOICEVOX CORE APIのis_model_loaded、およびload_modelを実行しています。

重い処理のため、スピーカーモデルがロードされていない場合のみload_modelを実行します。

```cpp:Sample.CPP
	UE::Tasks::Launch(TEXT("VoicevoxCoreTask"), [&]()
	{
		if (FVoicevoxCoreUtil::LoadModel(SpeakerId))
		{
			// 成功時の処理を記述
		}
		else
		{
			// 失敗時の処理を記述
		}
	});

```

:::note info
モデルによってはメインスレッドが止まるため、上記の通り非同期で処理することを推奨しています。
:::

## FVoicevoxCoreUtil::RunTextToSpeech
指定したSpeakerIdからtext to speechを実行します。
VOICEVOX CORE APIのvoicevox_ttsを呼び出してテキストから音声データを生成します。

```cpp:Sample.CPP
	UE::Tasks::Launch(TEXT("VoicevoxCoreTask"), [&]()
	{
		int OutputBinarySize = 0;
		if (uint8* OutputWAV = FVoicevoxCoreUtil::RunTextToSpeech(SpeakerId, *Message, OutputBinarySize);
			OutputWAV != nullptr)
		{
#if PLATFORM_WINDOWS
			PlaySound(reinterpret_cast<LPCTSTR>(OutputWAV), nullptr, SND_MEMORY);
#endif
			FVoicevoxCoreUtil::WavFree(OutputWAV);
		}
		else
		{
			// 失敗時の処理を記述
		}
	});
```
:::note info
メインスレッドが止まる処理のため、上記の通り非同期で処理することを推奨しています。
:::

指定したSpeakerIdのモデルがロードされていない場合は、load_modelも一緒に行います。

戻り値はテキストを音声データに変換した結果コードです。
戻り値はFVoicevoxCoreUtil::WavFreeに渡して破棄する必要があります。

:::note alert
破棄しない場合はメモリリークする恐れがあります。
:::

## FVoicevoxCoreUtil::RunTextToSpeechFromKana

指定したSpeakerIdからAquesTalkライクな記法なtext to speechを実行します。
VOICEVOX CORE APIのvoicevox_tts_from_kanaを呼び出してAquesTalkライクなテキストから音声データを生成します。

例
```
ボク'ワ/ズ'ンダモン/ナノ'ダ
```

以下、記載ルールを引用します。

> - 全てのカナはカタカナで記述される
> - アクセント句は/または、で区切る。、で区切った場合に限り無音区間が挿入される。
> - カナの手前に_を入れるとそのカナは無声化される
> - アクセント位置を'で指定する。全てのアクセント句にはアクセント位置を 1 つ指定する必要がある。
> - アクセント句末に？(全角)を入れることにより疑問文の発音ができる

※VOICEVOX ENGINE ReadMeより引用

:::note alert
AquesTalkライクな記法に適応していない文字を渡すとクラッシュするので注意してください。
:::

```cpp:Sample.CPP
	UE::Tasks::Launch(TEXT("VoicevoxCoreTask"), [&]()
	{
		int OutputBinarySize = 0;
		if (uint8* OutputWAV = FVoicevoxCoreUtil::RunTextToSpeechFromKana(SpeakerId, *Message, OutputBinarySize);
			OutputWAV != nullptr)
		{
#if PLATFORM_WINDOWS
			PlaySound(reinterpret_cast<LPCTSTR>(OutputWAV), nullptr, SND_MEMORY);
#endif
			FVoicevoxCoreUtil::WavFree(OutputWAV);
		}
		else
		{
			// 失敗時の処理を記述
		}
	});
```

:::note info
メインスレッドが止まる処理のため、上記の通り非同期で処理することを推奨しています。
:::

指定したSpeakerIdのモデルがロードされていない場合は、load_modelも一緒に行います。

戻り値はテキストを音声データに変換した結果コードです。
戻り値はFVoicevoxCoreUtil::WavFreeに渡して破棄する必要があります。

:::note alert
破棄しない場合はメモリリークする恐れがあります。
:::

## FVoicevoxCoreUtil::WavFree
VOICEVOX COERのvoicevox_ttsで生成した音声データを開放します。
VOICEVOX CORE APIのvoicevox_wav_freeを実行しています。

```cpp:Sample.CPP
	UE::Tasks::Launch(TEXT("VoicevoxCoreTask"), [&]()
	{
		int OutputBinarySize = 0;
        uint8* OutputWAV = RunTextToSpeech::RunTextToSpeechFromKana(SpeakerId, *Message, OutputBinarySize);
#if PLATFORM_WINDOWS
		PlaySound(reinterpret_cast<LPCTSTR>(OutputWAV), nullptr, SND_MEMORY);
#endif
        // 最後に必ず呼び出す
        FVoicevoxCoreUtil::WavFree(OutputWAV);
	});
```

FVoicevoxCoreUtil::RunTextToSpeech、およびFVoicevoxCoreUtil::RunTextToSpeechFromKanaで取得したポインタは、使用しなくなったタイミングで必ずWavFreeを実行して破棄してください。

## FVoicevoxCoreUtil::Metas()

スピーカーモデル名やスピーカーIDのリストを取得します。
文字列はJSON形式です。

```cpp:Sample.CPP
FVoicevoxCoreUtil::Metas();
```

他のJSON変換コードを利用したい場合は、こちらのメソッドを利用してください。

## FVoicevoxCoreUtil::MetaList()

スピーカーモデル名やスピーカーIDのリストを取得します。

```cpp:Sample.CPP
TArray<FVoicevoxMeta> Metas = FVoicevoxCoreUtil::MetaList();
```

内部でMetasから取得したJSON文字列を、JsonUtilitiesモジュールでStructのTArrayへ変換しています。
以下、戻り値のStructの中身です。

```cpp:VoicevoxCoreUtil.h

/**
 * @struct FVoicevoxStyle
 * @brief VOICEVOXのモデルスタイル情報構造体
 */
USTRUCT(BlueprintType)
struct FVoicevoxStyle
{
	GENERATED_USTRUCT_BODY()

	//! スタイル名
	UPROPERTY(BlueprintReadOnly)
	FString Name;

	//! スピーカーID
	UPROPERTY(BlueprintReadOnly)
	int64 Id;
};

/**
 * @struct FVoicevoxMeta
 * @brief VOICEVOXのメタ情報構造体
 */
USTRUCT(BlueprintType)
struct FVoicevoxMeta
{
	GENERATED_USTRUCT_BODY()

	//! モデル名
	UPROPERTY(BlueprintReadOnly)
	FString Name;

	//! スタイル情報リスト
	UPROPERTY(BlueprintReadOnly)
	TArray<FVoicevoxStyle> Styles;

	//! スピーカーユニークID
	UPROPERTY(BlueprintReadOnly)
	FString Speaker_uuid;

	//! バージョン情報
	UPROPERTY(BlueprintReadOnly)
	FString Version;
};

```

# 以下は、動作の確認が取れていないため正常動作は保証していません。

VOICEVOX Engineで主に使用するAPIですが、自分の理解が追い付いてなく必要最低限の確認しかとっていません。

## FVoicevoxCoreUtil::GetPhonemeLength
音素列から、音素ごとの長さを求めます。
VOICEVOX COERのyukarin_s_forwardを実行しています。

:::note warn
渡した引数でクラッシュしない以外は確認を取っていないため、正常動作の保証はしていません。
:::

## FVoicevoxCoreUtil::FindPitchEachMora
モーラごとの音素列とアクセント情報から、モーラごとの音高を求めます。
VOICEVOX COERのyukarin_sa_forwardを実行しています。

:::note warn
渡した引数でクラッシュしない以外は確認を取っていないため、正常動作の保証はしていません。
:::

## FVoicevoxCoreUtil::DecodeForward
フレームごとの音素と音高から、波形を求めます。
VOICEVOX COERのdecode_forwardを実行しています。

:::note warn
渡した引数でクラッシュしない以外は確認を取っていないため、正常動作の保証はしていません。
:::
# Blueprint公開ノード

VoicevoxAsyncTask.hにBlueprint公開ノードを一通り実装しています。
C++に比べると最低限の機能確認程度になっていますが、スピーカーIDを指定してのテキストの音声読み上げに対応してます。

:::note alert
音声生成中のクラッシュが取り切れていないので、エディタプレイでVoicevoxSimplePlayTextToSpeechノードを実行した場合は、必ず最後まで再生させてから終了するようにしてください。
:::


※実装例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/44b18625-718b-c8a4-8df7-6ee4d62a0cb6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/556a8908-5fbd-be1c-ee5d-d0a7dc06eeec.png)

# ノード説明

Blueprintに公開したノードの一通り説明を記載します。

## VoicevoxInitializeノード

VOICEVOX COERの初期化を行います。
VOICEVOX CORE APIのiniitialize～voicevox_load_openjtalk_dictを呼び出して初期します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/3f0e9aab-baca-a6d0-2f39-6a07241c851a.png)

UseGPUをtrueにするとGPUモードで初期化します。
~~GPU対応版のCOREライブラリ、かつ対応するGPU（nvidia製GPUを搭載したWindows, Linux PCではCUDA、DirectX12に対応したGPUを搭載したWindows PCではDirectML）がPCに組み込まれていれば使用できます。~~

:::note alert
GPU対応のCOREライブラリを読み込んでテストしたのですが、バージョン0.13.2でエラーでクラッシュ、もしくはGPUモードに切り替わらない現象を確認したため、当面の間はGPU切り替えは非対応とします。
UseGPUは常にfalseを設定し、CPUモードで実行してください。
:::

CPUのみのライブラリでUseGPUをtrueにすると、エラーがアウトプットログに表示されます。

こちらは何度もVoicevoxInitializeノードを行って問題ないですが、VoicevoxSimplePlayTextToSpeechノード実行時は最後に初期化した設定で行います。

## VoicevoxLoadModelノード

スピーカーIDを元にモデルのロードを行います。
必ずVoicevoxInitializeノードを実行した後に呼び出してください。

VOICEVOX CORE APIのis_model_loaded、およびload_modelを実行しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/fe4749cd-f0ac-48c7-f9e2-f7f7fde0757f.png)

VoicevoxSimplePlayTextToSpeechノード実行前にあらかじめスピーカーモデルを読み込みたい場合に使用してください。
モデルデータを読み込まないでVoicevoxSimplePlayTextToSpeechノードを実行した場合より、ちょっとだけ処理が早くなります。

## VoicevoxSimplePlayTextToSpeechノード

指定したSpeakerIdからtext to speechを実行します。
必ずVoicevoxInitializeノードを実行した後に呼び出してください。
VOICEVOX CORE APIのvoicevox_ttsを呼び出してテキストから音声データを生成し、再生を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/d551c7e6-f3d1-83f8-e383-298102dd72d4.png)

:::note warn
RunKanaにチェックを入れると、AquesTalkライクなテキストでないと変換できません。
:::

再生は簡単にWindows APIのPlaySoundを呼び出してるだけです。

```cpp:VoicevoxAsyncTask.cpp
#if PLATFORM_WINDOWS
			PlaySound(reinterpret_cast<LPCTSTR>(OutputWAV), nullptr, SND_MEMORY);
#endif
```

※C++でUEのサウンドキューに変換しようと思いましたが、わからなすぎて諦めました...

## GetVoicevoxMetasToStringノード

VOICEVOXのMetasを取得します。
必ずVoicevoxInitializeノードを実行した後に呼び出してください。
戻り値はJSON文字列です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/0cfd7bca-0239-9144-cab4-b005656175a2.png)

他のJSON変換プラグインを使用したい場合は、GetVoicevoxMetasToStringノードから文字列を取得して変換をしてください。

## GetVoicevoxMetasToListノード

VOICEVOXのMetasを取得します。
必ずVoicevoxInitializeノードを実行した後に呼び出してください。
戻り値はJSON変換済みの構造体リストです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/9a6c79e4-e76a-8b8b-180b-2671371f1e90.png)

例として以下のようにForEachLoopで配列を回して使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/6ea84d6a-6127-f896-6c06-a045f97e1f3c.png)

## VoicevoxFinalizeノード

VOICEVOX CORE APIのfinalizeを呼び出して終了処理を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/c9a3d3c8-1531-7e7e-6454-02fb53304772.png)

連続でVoicevoxFinalizeノードを行って問題ないですが、VoicevoxFinalizeノードを呼び出した後はVoicevoxInitializeノード以外はクラッシュしてしまうため、実行しないようにしてください。

# VOICEVOX Engine for UE5プラグインが利用できる点

元々ネタとして開発したので正直、UEで直に使えるようにしたところでメリットが自分には思いつきません。
VOICEVOXで生成したボイスをゲームに利用したいなら、公式で公開されているVOICEVOX Editorで編集してWavファイルを生成し、UE5にインポートしたほうが早いしクオリティも良いです。

ノベルゲームやノベルパートでまだボイスを当てていないときのプロトタイプとして、一時的にVOICEVOXのキャラボイスを使ってイメージをつかむ、というぐらいですかねぇ...
何か面白いことを思いついたら、ライセンスと利用規約の範囲内でプラグインを面白おかしく使ってもらえれば幸いです。

# 注意点

もしネットワークでVOICEVOX Engine for UE5プラグインを使用する場合、デバッグ時はワンプロセスは無効にしてください。
クラッシュすると思います。

# 現在判明している不具合

* COREのAPIを非同期で行った場合、特にRunTextToSpeechからの戻りを待たずにプレイ終了したり、続けてRunTextToSpeechを実行するとクラッシュします。
→この部分はどうしようか、現在模索中です。

* パッケージングを行うとOpen JTalkフォルダのみコピーを失敗します。
→お手数ですが、パッケージング済みのフォルダにopen_jtalk_dic_utf_8-1.11フォルダを手動でコピーしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104377/23f5f42c-a281-399f-fb57-5b6ad2b1aa74.png)

以下にコピーしてもらえれば動作します。
```
【パッケージング出力フォルダ名】\Windows\【プロジェクト名】\Binaries\Win64
```

* GPUモードに対応したCOREライブラリでGPUに切り替えるとエラー、もしくはクラッシュする
→こちら原因調査中です。

# ライセンス

VOICEVOX ENGINEのライセンスを継承し、LGPL v3と、ソースコードの公開が不要な別ライセンスのデュアルライセンスとなります。

# 利用規約

VOICEVOX Engine for UE5の利用規約は[VOICEVOXのホームページに記載された利用規約](https://voicevox.hiroshiba.jp/term)を継承するため、利用前に必ず一読してください。

各スピーカーモデルのライセンスは[VOICEVOX公式ホームページのキャラクター一覧](https://voicevox.hiroshiba.jp/)を参照してください。

:::note alert
VOCEVOXの利用規約及び各キャラクターの利用規約を厳守するようにお願いいたします
:::

# 問い合わせに関して

VOICEVOX Engine for UE5プラグインに関して質問があれば、[Twitter](https://twitter.com/YuukiOgino)、Qiitaのコメント欄で聞いてもらうか、[公開したGithubのissue](https://github.com/YuukiOgino/VoicevoxEngineForUE/issues)に記載してください。

:::note alert
間違ってもVOICEVOX CORE作者のヒホさん、VOICEVOX公式Twitterアカウント及びVOICEVOX ホームページで、VOICEVOX Engine for UE5プラグインの問い合わせをしないようにお願いいたします。
:::

# 今後について

個人では満足していますが、もしVOICEVOXのEditor部分をUEでも使えるようにしてほしい、という声が多ければEditor機能も開発するかもです。
後は非同期でCOREのAPIを実行するとクラッシュすることが多いので、安定化に繋がる方法を模索中です。

あと、VOICEVOX ENGINEの中身も移植しないとですね...。こちらはやる気があればやります。

# まとめ

せっかく公開したので利用規約とライセンスを守ってVOICEVOX Engine for UE5プラグインを色々使ってあげてください。
プルリクも大歓迎です。

あと、C++のみでサウンドキュー、というかサウンドウェーブの動的生成ってどうやるんですかね...
音声データを生成したポインタをサウンドウェーブに変換して再生したい、と思ってはいますがどうやればいいのか悩んでます。

# 参考資料一覧

VOICEVOX Engine for UE5プラグイン開発に参考にした資料は以下の通りです。

* VOICEVOX CORE

https://github.com/VOICEVOX/voicevox_core

* VOICEVOX ENGINE

https://github.com/VOICEVOX/voicevox_engine

* VOICEVOX ENGINE SHARP

https://github.com/yamachu/VoicevoxEngineSharp

* Node VOICEVOX Engine

https://github.com/y-chan/node-voicevox-engine

* Slateのテキストに無理やり(？)アクセスする方法

https://qiita.com/Naotsun/items/5fa305cf91c3dec55c16

https://github.com/Naotsun19B/SlateTextAccessor

* Tasks System

https://docs.unrealengine.com/5.0/ja/tasks-systems-in-unreal-engine/

* UE5 Task Systemでお手軽な非同期処理！ ※サンプルプロジェクト配布あり

https://unrealengine.hatenablog.com/entry/2022/07/31/224504

※上記ブログのalweiさんも同じく[1日目に記事を書いています](https://unrealengine.hatenablog.com/entry/2022/12/01/000000)ので、そちらもご覧ください。

# クレジット

VOICEVOX

https://voicevox.hiroshiba.jp/ 

VOICEVOX:ずんだもん


ずんだもん立ち絵素材

https://www.pixiv.net/artworks/92641351

https://seiga.nicovideo.jp/seiga/im10788496

（ず・ω・きょ）

--- 

明日は@koorinonakaさん、@g__skrさん、@O_Y_Gさんです。期待してます。