如何将文本更改为语音以及如何将字符插入字符数组

how to change Text to Speech voice and how to insert characters into char array

我需要更改 Text To Speech 引擎的声音。选择菜单时 (ID_SPEAK_PLAY),我会得到一个编辑框的文本并简单地阅读它。

我的情况可以通过两种方式解决:

  1. ptrData 的开头插入 XML 代码,而不使用 strncat 或涉及创建其他 [=14= 的其他函数] 缓冲区(内存问题)。 StringCchPrintf 不工作。
  2. 以我不知道的其他方式改变声音。

这是我的代码:

    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;

StringCchPrintf is not working.

那是因为你忽略了文档中的警告:

Behavior is undefined if the strings pointed to by pszDest, pszFormat, or any argument strings overlap.

您将 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;
}

change the voice in some other way that i don't know.

无需在文本前插入 XML,您可以调用 ISpVoice::SetVoice() method before calling ISpVoice::Speak(). Use SpEnumTokens() to know which voices are installed, or use SpFindBestToken() 来搜索符合您需要的条件的语音。