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
ptrData
without usingstrncat
or other functions that involve creating otherwchar_t*
buffers (memory issues ).StringCchPrintf
is 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
ptrData
as bothpszDest
and an argument string, so your code has undefined behavior. You must use separate buffers when usingStringCchPrintf()
:Alternatively, just skip
StringCchPrintf()
and letWM_GETTEXT
populate 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.