【问题标题】:store a variable that holds user input data in sapi5 speak function在 sapi5 speak 函数中存储一个保存用户输入数据的变量
【发布时间】:2013-03-22 14:48:07
【问题描述】:

我正在开发一个使用 Microsoft SAPI5 语音引擎的应用程序。然而,我已经碰壁了。我一直在尝试使用存储用户输入的变量中的数据,以便 TTS 引擎可以重复它。但是 sapi5 语音函数不允许字符串、wstrings 或除 LPCWSTR 之外的其他类型,根据我的研究,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++ 的新手,这是我第一次遇到这种问题,所以对我来说很新。

我看到这个主题的OP有完全相同的问题:https://stackoverflow.com/questions/12292790/how-do-i-use-variables-in-sapi-tts

【问题讨论】:

    标签: c++ sapi lpcwstr


    【解决方案1】:

    经过大约 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;
    }
    

    然后我将这段代码包含到我的项目中,然后为 TTS 引擎初始化函数创建了一个名为 LPCWSTR Repeat 的函数参数(这样转换后的字符串可以在 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);
    }
    

    希望我的回答能帮助和我遇到同样问题的人。

    我会更详细地解释我的答案,但我需要睡觉,所以请接受我诚挚的歉意:-)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      相关资源
      最近更新 更多