store a variable that holds user input data in sapi5 speak function

谁说胖子不能爱 提交于 2019-12-11 08:34:35

问题


I am developing an application that uses the Microsoft SAPI5 speech engine. However, I have hit a wall. I've been trying to use the data from the variable that stores the input from the user so the TTS engine can repeat it. But the sapi5 speech function does not allow strings, wstrings or other types except from LPCWSTR which from my research is a pointer to a wide character string, so shouldn't it accept wstrings?

Here's some example code from 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;
}

So lets say for example i have this piece of code :

...
wstring text;
if( SUCCEEDED( hr ) )
    {
        wcin >> text;
        hr = pVoice->Speak(text, SPF_IS_XML, NULL);
        pVoice->Release();
        pVoice = NULL;
    }
...

But this does not work. How would I go about storing a variable that allows a LPCWSTR type? I'm kind of new to c++ and this is the first time I've had this sort of problem, so it's very new to me.

I saw that the OP on this topic has the exact same problem : https://stackoverflow.com/questions/12292790/how-do-i-use-variables-in-sapi-tts


回答1:


After around 2 hours of solid research, i found an article on msdn on converting a string to LPCWSTR format. The code is below :

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

I then included this code into my project, and then created a function parameter called LPCWSTR Repeat for the TTS engine initialization function ( So that the converted string can be used in the TTS function, and the engine would say the contents of the converted string ) .

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

Then i created another function to manage the conversion and manage the user input so that the TTS engine can repeat it.

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);
}

I hope my answer helps people who are having the same problem as I had.

I would have explained my answer in more detail but I'm in need of some sleep, so please accept my sincere apologies :-) .



来源:https://stackoverflow.com/questions/15573246/store-a-variable-that-holds-user-input-data-in-sapi5-speak-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!