windows:使用微软的TTS(文本转语音)进行文本播报

目录

说明

使用示例

代码


说明

函数使用说明

TTS的API原来支持的字符串类型是LPCWSTR,我这边有做一个字符串转换的处理,使其支持QString 和 std::string两种类型的字符串。

注意:

1、如果需要更换函数形参的类型,需要函数形参类型更换,以及函数里的字符串转换部分进行一个调整。

2、如果机器比较老,可能因为windows上没有TTS语音环境而导致播放失败的,可以参考下面的环境配置流程

配置环境(安装SDK):
Windows Speech SDK 下载地址:http://www.microsoft.com/download/en/details.aspx?id=10121
下载完成后,先安装语音引擎SpeechSDK51.exe,再安装中文语音库SpeechSDK51LangPach.exe。

  • SpeechSDK51.exe:                        语音合成引擎
  • SpeechSDK51LangPach.exe:       语音库,支持日语和简体中文需要这个支持。
  • sapi.chm:                                       帮助文档
  • speechsdk51MSM.exe:                 语音引擎
  • Sp5TTintXP.exe:                            XP下Mike和Mary语音。

 

题外说明

还有一种播放固定文本语音的方式,通过执行vbs脚本实现语音播报

1、写入txt(保存编码为ASCII编码): CreateObject("SAPI.SpVoice").Speak"这是一条语音播放测试"
2、更改后缀 .vbs
3、直接运行

 

 

使用示例

#include 
#include "sapi.h"
#include "sphelper.h"

int main(int argc, char* argv[])
{
	std::string str = "这是一个测试语句: hello world!";
	TextToSpeak(str);
	return 0;
}

 

代码

#include "sapi.h"
#include "sphelper.h"

int TextToSpeak(std::string str)
{
	/************************************** 字符串类型转换 ******************************************/

	//string 转 LPCWSTR			方法一:使用 (std::string) 参数,将函数形参str的类型换成std::string
	std::wstring wstr;
	//获取缓冲区大小,并申请空间,缓冲区大小按字符计算
	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
	TCHAR* buffer = new TCHAR[len + 1];
	//多字节编码转换成宽字节编码
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
	buffer[len] = '\0';				//添加字符串结尾
	//删除缓冲区并返回值
	wstr.append(buffer);
	delete[] buffer;
	LPCWSTR speakStr = wstr.c_str();


	//QString 转 LPCWSTR			方法二:使用 (QString) 参数,将函数形参str的类型换成QString
	//std::wstring wstr = str.toStdWString();
	//LPCWSTR speakStr = wstr.c_str();



	/************************************** tts语音部分 ******************************************/

	CoInitialize(NULL); //COM初始化
	CLSID CLSID_SpVoice;
	CLSIDFromProgID(_T("SAPI.SpVoice"), &CLSID_SpVoice);
	ISpVoice *pSpVoice = NULL;
	IEnumSpObjectTokens *pSpEnumTokens = NULL;

	// 获取ISpVoice接口
	if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void**)&pSpVoice)))
	{
		return -1;
	}
	// 列举所有的语音token,可以通过pSpEnumTokens指向的接口得到
	if (SUCCEEDED(SpEnumTokens(SPCAT_VOICES, NULL, NULL, &pSpEnumTokens)))
	{
		ISpObjectToken *pSpToken = NULL;
		// 获取token并朗读字符串
		if (SUCCEEDED(pSpEnumTokens->Next(1, &pSpToken, NULL)) && pSpToken != NULL)
		{
			pSpVoice->SetVoice(pSpToken); //设置当前语音token为pSpToken
			pSpVoice->SetRate(-1);        //声音速率  -10 ~ 10
			/*pSpVoice->SetVolume(100);*/
			pSpVoice->Speak(speakStr, SPF_DEFAULT, NULL); // 朗读中文和英文的混合字符串
			pSpToken->Release();   // 释放token
		}

		pSpEnumTokens->Release(); // 释放pSpEnumTokens接口
	}
	pSpVoice->Release();   // 释放voice
	::CoUninitialize();

	return 0;
}

 

你可能感兴趣的:(封装好的功能函数)