I need to change the voice of the Text To Speech engine. When a menu is selected (ID_SPEAK_PLAY), I get the text of an edit box and simply read it.
My situation can be solved in two ways :
- insert the XML code at the begining of
ptrDatawithout usingstrncator other functions that involve creating otherwchar_t*buffers (memory issues ).StringCchPrintfis not working. - change the voice in some other way that i don't know.
Here is my code :
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;
That is because you ignored the warning in the documentation:
You are specifying
ptrDataas bothpszDestand an argument string, so your code has undefined behavior. You must use separate buffers when usingStringCchPrintf():Alternatively, just skip
StringCchPrintf()and letWM_GETTEXTpopulate your single buffer directly:Instead of inserting XML in front of your text, you can call the
ISpVoice::SetVoice()method before callingISpVoice::Speak(). UseSpEnumTokens()to know which voices are installed, or useSpFindBestToken()to search for a voice that matches the criteria you need.