Я занимаюсь разработкой приложения, которое использует речевой движок Microsoft SAPI5. Тем не менее, я ударил стену. Я пытался использовать данные из переменной, которая хранит ввод от пользователя, чтобы механизм TTS мог повторить это. Но речевая функция sapi5 не допускает строки, строки wstring и другие типы, кроме как из LPCWSTR, который, по моим исследованиям, является указателем на строку широких символов, поэтому не должен ли он принимать строки wstrings?
Вот пример кода из msdn:
#include <stdafx.h>
#include <sapi.h>
int main(int argc, char* argv[])
{
ISpVoice * pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice;);
if( SUCCEEDED( hr ) )
{
hr = pVoice->Speak(L"Hello world", 0, NULL);
pVoice->Release();
pVoice = NULL;
}
::CoUninitialize();
return TRUE;
}
Так скажем, например, у меня есть этот кусок кода:
...
wstring text;
if( SUCCEEDED( hr ) )
{
wcin >> text;
hr = pVoice->Speak(text, SPF_IS_XML, NULL);
pVoice->Release();
pVoice = NULL;
}
...
Но это не работает. Как мне сохранить переменную, которая допускает тип LPCWSTR?
Я немного новичок в c ++, и это первый раз, когда у меня возникают проблемы такого рода, так что это очень ново для меня.
Я видел, что у ОП по этой теме точно такая же проблема: https://stackoverflow.com/questions/12292790/how-do-i-use-variables-in-sapi-tts
Примерно после 2 часов тщательного исследования я нашел статью на MSDN о преобразовании строки в формат LPCWSTR. Код ниже:
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
Затем я включил этот код в свой проект, а затем создал параметр функции LPCWSTR Repeat для функции инициализации движка TTS (чтобы преобразованная строка могла использоваться в функции TTS, а движок мог бы сказать содержимое преобразованной строки) ,
static int TTS_Speak_Dialogue(LPCWSTR Repeat)
{
// Set Sapi5 voice properties
ISpVoice * pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
// Create new instance of Sapi5 once initialized in COM
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if( SUCCEEDED( hr ) )
{
hr = pVoice->Speak(Repeat, SPF_IS_XML, NULL);
pVoice->Release();
pVoice = NULL;
}
::CoUninitialize();
return TRUE;
}
Затем я создал другую функцию для управления преобразованием и управления пользовательским вводом, чтобы механизм TTS мог его повторить.
static void convert_string()
{
// Declare a string type variable
string UserInput;
// Now get input from user
cout << "Get the TTS to repeat Input : ";
cin >> UserInput;
// Convert string to LPCWSTR!
std::wstring stemp = s2ws(UserInput);
// UserInput string now converted to result
LPCWSTR result = stemp.c_str();
// Call the TTS engine function and use the converted string
TTS_Speak_Dialogue(result);
}
Я надеюсь, что мой ответ поможет людям, которые имеют ту же проблему, что и я.
Я бы объяснил свой ответ более подробно, но мне нужно немного поспать, поэтому, пожалуйста, примите мои искренние извинения :-).
Других решений пока нет …