windows文字转语音示例

背景

微软的提供的SAPI工具包,用于语音技术开发,提供包括语音识别和语音合成两方面的内容。我们可以通过其中Voice Text API完成从文字到语音的转换。

初始化COM框架

SAPI需要用到COM框架,在程序开始和结束的地方需要分别初始化和释放COM框架

TextSpeaker::TextSpeaker() {
	CoInitializeEx(nullptr, COINIT_MULTITHREADED);
	......
}

TextSpeaker::~TextSpeaker() {
	CoUninitialize();
}

枚举音频相关资源

可以通过SpEnumTokens接口,枚举指定的对象资源。能够查询出当前支持的人声以及可以输出的设备。

#include 
#include 
#pragma warning(push)
#pragma warning(disable : 4996)
#include 
#pragma warning(pop)

static std::vector>> GetTokens(
	const wchar_t* registryKey) {
	std::vector>> ret;
	CComPtr cpEnum;
	if (!SUCCEEDED(SpEnumTokens(registryKey, nullptr, nullptr, &cpEnum))) {
		return ret;
	}
	unsigned long count = 0;
	if (!SUCCEEDED(cpEnum->GetCount(&count))) {
		return ret;
	}
	for (size_t i = 0; i < count; ++i) {
		CComPtr token;
		if (!SUCCEEDED(cpEnum->Next(1, &token, nullptr))) {
			return ret;
		}
		LPWSTR str = nullptr;
		token->GetStringValue(nullptr, &str);
		ret.push_back({ std::wstring{ str }, std::move(token) });
	}
	return ret;
}

// WIN10后新的资源注册表地址
static std::wstring NEW_WIN10_REG_KEY
		= L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices";
// 获取系统语音资源
mVoices = GetTokens(SPCAT_VOICES);
{
	// 合并WIN10后新的资源
	std::vector>>
		extraVoices = GetTokens(NEW_WIN10_REG_KEY.c_str());
	mVoices.insert(mVoices.end(), extraVoices.begin(), extraVoices.end());
}

通过获取的语音资源,可以查看系统支持的语音资源。打印出来后结果如下:

for (const std::pair>& v : mVoices) {
	wprintf(L"%zu : %s\n", i + 1, v.first.c_str());
}

1 : Microsoft Huihui Desktop - Chinese (Simplified)
2 : Microsoft Zira Desktop - English (United States)
3 : Microsoft Huihui - Chinese (Simplified, PRC)
4 : Microsoft Kangkang - Chinese (Simplified, PRC)
5 : Microsoft Yaoyao - Chinese (Simplified, PRC)

改变注册表位置,可以获取能够输出的音频设备

mDevices = GetTokens(SPCAT_AUDIOOUT);
for (const std::pair>& v : mDevices) {
	wprintf(L"%zu : %s\n", i + 1, v.first.c_str());
}

1 : 扬声器 (Jabra EVOLVE 30 II)
2 : LEN P24i-10 (英特尔(R) 显示器音频)
3 : 扬声器 (Realtek(R) Audio)

通过ISpVoice进行语音合成

通过ISpVoice接口可以设置和播放语音。

CComPtr voicePtr;
voicePtr.CoCreateInstance(CLSID_SpVoice);
// 设置音量,支持范围0~100
voicePtr->SetVolume(vol);
// 设置人声速度,支持-10~10
voicePtr->SetRate(speed);
// 设置播放的人声,可以使用GetTokens中获取的人声资源ISpObjectToken
// 如果不设置,则合成操作使用默认语音,在HKEY_CURRENT_USER\Software\Microsoft\Speech Server\v11.0\Voices\DefaultTokenId指定
voicePtr->SetVoice(selectedVoice);
// 设置播放的设备,可以使用GetTokens中获取的设备资源ISpObjectToken
// 如果不设置,则使用默认设备播放
voicePtr->SetOutput(device, TRUE);

完成ISpVoice的设置后,就可以开始播放文字

// 设置为异步播放,避免使用时阻塞
mDefaultSpeaker->Speak(sentence.c_str(), SPF_DEFAULT | SPF_ASYNC, nullptr);
// 停止播放,SPF_PURGEBEFORESPEAK可以舍弃队列中剩余要合成的数据
mDefaultSpeaker->Speak(L"", SPF_DEFAULT | SPF_PURGEBEFORESPEAK | SPF_ASYNC, nullptr);

你可能感兴趣的:(c++,windows,microsoft,语音识别)