我最近刚刚下载了 Visual Studio 2015(社区),以便我可以使用 Microsoft SAPI TTS 开发应用程序。我安装了 5.1 SDK,然后安装了 5.4 SDK for Speech,并安装了 Runtime Languages for SAPI。
到目前为止,我可以通过使用我希望 SAPI 通过直接参数和读取 SSML .XML 文件说出的短语来设法让应用程序工作。SAPI 和 SSML 的所有功能都可以工作,除了与更改语音令牌有关的任何事情。(例如,<voice xml:lang="pl-PL">
......<voice required="Gender:Female">
等)
我阅读了一些有关如何设置语言/语音令牌的论坛,并尝试了以下代码:
if(FAILED(::CoInitialized(NULL))
return false;
HRESULT hr = S_OK;
CComPtr<ISpVoice> cpVoice;
CComPtr<ISpObjectTokenCategory> cpObjectCat;
CComPtr<ISpObjectToken> cpObjectToken;
CComPtr<IEnumSpObjectTokens> cpEnum;
hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&cpVoice);
if(SUCCEEDED(hr))
{
hr = SpGetDefaultTokenFromCategoryId(SPCAT_VOICES, &cpObjectToken);
}
if(SUCCEEDED(hr))
{
hr = SpGetCategoryFromId(SPCAT_VOICES, &cpObjectCat);
}
if(SUCCEEDED(hr))
{
hr = cpObjectCat->EnumTokens(NULL, NULL, &cpEnum);
}
if(SUCCEEDED(hr))
{
hr = cpEnum->Next(1, &cpObjectToken, NULL);
//Currently only concerned with making 1 token assign without
//throwing exception
}
if(SUCCEEDED(hr))
{
hr = cpVoice->SetVoice(cpObjectToken);
}
if(SUCCEEDED(hr))
{
hr = cpVoice->Speak(L"Hello There!", NULL, NULL);
}
//... lots of commented-out code here ...
cpVoice.Release();
::CoUninitialize();
return true; // <-- Throws Exception Here
该程序构建没有错误,但在最后的返回语句中抛出错误 0xC0000005(内存访问冲突)。
由于不推荐使用的方法 ::GetVersionExW()我确实必须修改头文件<sphelper.h>
...我设法使用以下链接中的方法使其工作:http: //www.codeproject.com/Articles/678606/Part-Overcoming- Windows-s-deprecation-of-GetVe。奇迹般地(并且对系统源代码进行了一些调整,这可能是个坏主意),它奏效了。
我不知道程序为什么会在最后抛出,因为问题一定出在程序访问注册表令牌中。我知道问题通常出在指针上,那么我需要做些什么来完成这项工作?
请注意,我正在尝试使该cpVoice
对象使用波兰标记“Paulina”。有没有办法以某种方式手动将注册表令牌值分配给对象?