4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenSiv3DでVOICEVOX

Last updated at Posted at 2023-07-20

OpenSiv3DからVOICEVOXを簡単に利用できる関数GetAudioFromVOICEVOXを作成しました。
https://voicevox.hiroshiba.jp/

# include <Siv3D.hpp>



std::string URLEncode(const std::string& str) {
	std::ostringstream os;
	for (char c : str) {
		if (std::isalnum(static_cast<unsigned char>(c)) || (c == '-') || (c == '_') || (c == '.') || (c == '~')) {
			os << c;
		}
		else {
			os << '%' << std::setw(2) << std::setfill('0') << std::uppercase << std::hex << (static_cast<int>(static_cast<unsigned char>(c)) & 0xff);
		}
	}
	return os.str();
}

JSON getAudioQuery(const String& text, int32 speakerID) {
	const URL audioQueryURL = U"http://localhost:50021/audio_query";
	const String encodedText = Unicode::Widen(URLEncode(text.toUTF8()));
	const std::string data = JSON{}.formatUTF8();
	const FilePath jsonFilePath = U"audio_query_result.json";
	if (auto response = SimpleHTTP::Post(audioQueryURL + U"?text=" + encodedText + U"&speaker=" + Format(speakerID), {}, data.data(), data.size(), jsonFilePath)) {
		if (!response.isOK()) {
			throw std::runtime_error("Failed to get audio query.");
		}
		const JSON json = JSON::Load(jsonFilePath);
		if (!json) {
			throw std::runtime_error("Failed to parse JSON.");
		}
		return json;
	}
	throw std::runtime_error("Failed to get response from audio_query API.");
}

Audio synthesizeVoice(const JSON& audioQuery, int32 speakerID) {
	const URL synthesisURL = U"http://localhost:50021/synthesis?speaker=" + Format(speakerID);
	const HashTable<String, String> headers = { { U"Content-Type", U"application/json" } };
	const std::string data = audioQuery.formatUTF8Minimum();
	MemoryWriter memoryWriter;
	if (auto response = SimpleHTTP::Post(synthesisURL, headers, data.data(), data.size(), memoryWriter)) {
		if (!response.isOK()) {
			throw std::runtime_error("Failed to get voice data.");
		}
		const Audio audio{ MemoryReader{memoryWriter.getBlob()} };
		if (!audio) {
			throw std::runtime_error("Failed to load audio.");
		}
		return audio;
	}
	throw std::runtime_error("Failed to get response from synthesis API.");
}

Optional<Audio> GetAudioFromVOICEVOX(const String& originalText, int32 speakerID = 1, double intonationScale = 1.0, double speedScale = 1.0, double volumeScale = 2.0) {
	try {
		JSON audioQuery = getAudioQuery(originalText, speakerID);
		audioQuery[U"intonationScale"] = intonationScale;
		audioQuery[U"speedScale"] = speedScale;
		audioQuery[U"volumeScale"] = volumeScale;
		Audio audio = synthesizeVoice(audioQuery, speakerID);
		return audio;
	}
	catch (const std::exception& e) {
		Print << Unicode::Widen(e.what());
		return std::nullopt;
	}
}

void Main()
{
	auto voice = GetAudioFromVOICEVOX(U"これはボイスボックスのテストです。", 1);

	if (voice.has_value())
	{
		voice.value().play();
	}
	else
	{
		return;
	}

	while (System::Update())
	{		

	}
}

OpenSiv3Dと合成音声

OpenSiv3Dは、C++でのゲームやグラフィック開発を目指したライブラリで、さまざまな機能が用意されています。その中には、Text to Speech(テキスト読み上げ)機能も含まれ、以下のようにして使用します:

// 必要に応じて読み上げ言語を設定(OS に読み上げエンジンがインストールされていない場合は使えない)
TextToSpeech::SetDefaultLanguage(LanguageCode::EnglishUS);
//TextToSpeech::SetDefaultLanguage(LanguageCode::Japanese);

// 音声読み上げ出力
Say << U"Hello, Say!";

しかし、この機能はシステムにインストールされている読み上げエンジンに依存しています。そのため、読み上げの品質は使用しているエンジンの能力に大きく左右されます。この点でVOICEVOXは、高品質でマルチプラットフォームに対応した合成音声を提供しています。

利用方法

VOICEVOXをOpenSiv3Dで利用するためには、まずVOICEVOXをインストールし、エンジンを起動しておく必要があります。
https://voicevox.hiroshiba.jp/

そして、前述したGetAudioFromVOICEVOX関数を利用して、VOICEVOXのエンジンを活用した音声を生成できます。今後もOpenSiv3DやVOICEVOXの最新の機能を活用し、ユニークで魅力的なアプリケーションを開発していきましょう。

参考

https://voicevox.hiroshiba.jp/
https://github.com/VOICEVOX/voicevox_engine
https://qiita.com/A_T_B/items/1531d78944d8b796b9fa

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?