我需要改变Text To Speech引擎的声音。当选择一个菜单(ID_SPEAK_PLAY
)时,我会得到一个编辑框的文本并简单地阅读它。
我的情况可以通过两种方式解决:
ptrData
缓冲区的函数(内存问题)。 strncat
不工作。这是我的代码:
wchar_t*
StringCchPrintf不起作用。
那是因为您忽略了文档中的警告:
如果pszDest,pszFormat或任何参数字符串指向的字符串重叠,则行为未定义。
您将StringCchPrintf
指定为 case ID_SPEAK_PLAY:
text_size = SendMessage(h_edit, WM_GETTEXTLENGTH, 0, 0);
text_size += 100;
ptrData = new wchar_t[text_size];
SendMessage(h_edit, WM_GETTEXT, text_size, (LPARAM)ptrData);
StringCchPrintf(ptrData, text_size, L"<voice required = \"Gender=Female;Age=Teen\"> %s", ptrData);
pVoice->Speak(ptrData, SPF_ASYNC | SPF_IS_XML, NULL);
delete [] ptrData;
break;
和参数字符串,因此您的代码具有未定义的行为。使用ptrData
时必须使用单独的缓冲区:
pszDest
或者,只需跳过StringCchPrintf()
并让case ID_SPEAK_PLAY:
text_size = SendMessage(h_edit, WM_GETTEXTLENGTHW, 0, 0) + 1;
ptrData = new wchar_t[text_size];
SendMessage(h_edit, WM_GETTEXTW, text_size, (LPARAM)ptrData);
speak_size = text_size + 100;
speakData = new wchar_t[speak_size];
StringCchPrintf(speakData, speak_size, L"<voice required = \"Gender=Female;Age=Teen\"> %s", ptrData);
pVoice->Speak(speakData, SPF_ASYNC | SPF_IS_XML, NULL);
delete [] speakData;
delete [] ptrData;
break;
直接填充您的单个缓冲区:
StringCchPrintf()
以我不知道的其他方式改变声音。
您可以在调用WM_GETTEXT
之前调用case ID_SPEAK_PLAY:
{
const wchar_t *xml = L"<voice required = \"Gender=Female;Age=Teen\"> ";
const int xml_size = lstrlenW(xml);
text_size = SendMessage(h_edit, WM_GETTEXTLENGTHW, 0, 0);
ptrData = new wchar_t[text_size + xml_size + 1];
lstrcpyW(ptrData, xml);
SendMessage(h_edit, WM_GETTEXTW, text_size+1, (LPARAM)(ptrData+xml_size));
pVoice->Speak(ptrData, SPF_ASYNC | SPF_IS_XML, NULL);
delete [] ptrData;
break;
}
方法,而不是在文本前插入XML。使用ISpVoice::SetVoice()
知道安装了哪些语音,或使用ISpVoice::Speak()
搜索符合您所需条件的语音。