C++ 的 MS SAPI 5.1 问题

Posted

技术标签:

【中文标题】C++ 的 MS SAPI 5.1 问题【英文标题】:MS SAPI 5.1 issue with C++ 【发布时间】:2015-01-07 13:49:13 【问题描述】:

我正在使用带有 mingw 编译器的 MS Speech API 5.1。因此我没有 VS,但我能够用 c::b 编译代码。 代码sn-p如下:

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

当我执行时我发现

hr = pVoice->Speak(L"Hello world", 0, NULL);

返回 NULL。看了一会儿后,我从 MS SAPI 文件夹中运行了示例 TTSApp.exe。默认情况下,语音被选为“Microsoft Marry”。当我输入文本并单击“开始”时,不会产生语音,并且出现“说话错误”。当我将声音更改为“Microsoft Anna - 英语(美国)”时,它起作用了。

我不知道我的想法是否正确,但我的代码是否也因为错误/默认语音选择(“Microsoft Marry”)而失败?有什么方法可以将声音更改为“Microsoft Anna - 英语(美国)”进行测试?

我在这里需要你的帮助。你能帮我让 SAPI 在上面的代码中工作吗?

谢谢!

【问题讨论】:

GetVoices() 返回可用的声音 @AlexK。谢谢。你能给我一个示例代码来展示如何使用它吗?不仅显示声音,而且改变声音。您还认为上述问题可能是由于语音选择造成的吗?谢谢。 【参考方案1】:

因为这是一个微软特定的问题。 我在一些 system() 调用中混合使用了一些 vb,它会产生更简单的代码。 我没有清理它,但它很好用

int say(std::string s)


string part1content;
string part2content;
string word,complete;
const char * temp2="WScript.exe Scrpt.vbs";
const char * temp="Scrpt.vbs";

string pat1=(
"\'By Timbo\n\n\
Const SVSFlagsAsync = 1\n\
const SVSFPurgeBeforeSpeak =2\n\n\
Dim Speech\n\
Dim FSO\n\n\
CreateObjects\n\
Main\n\
DestroyObjects\n\
Quit\n\n\
Sub Main\n\
        Dim sText\n\n\
        sText = (\""
             );
string pat2=
(
"\")\n\
    Speech.rate = 0.05\n\
        If sText <> \"\" Then\n\
                SpeakText sText\n\n\
        End If\n\
End Sub\n\n\
Sub SpeakText(sText)\n\
        On Error Resume Next\n\
        Speech.Speak sText, SVSFlagsAsync + SVSFPurgeBeforeSpeak\n\
        Do\n\
                Sleep 200\n\
        Loop Until Speech.WaitUntilDone(10)\n\
End Sub\n\n\
Sub StopSpeaking()\n\
        On Error Resume Next\n\
        Speech.Speak vbNullString, SVSFPurgeBeforeSpeak\n\
        Set Speech = Nothing\n\
End Sub\n\n\
Sub CreateObjects\n\
        Set Speech = CreateObject(\"SAPI.SpVoice\")\n\
        Set FSO = CreateObject(\"Scripting.FileSystemObject\")\n\
End Sub\n\n\
Sub DestroyObjects\n\
        Set Speech = Nothing\n\
        Set FSO = Nothing\n\
End Sub\n\n\
Sub Sleep(nTimeout)\n\
        WScript.Sleep nTimeout\n\
End Sub\n\n\
Sub Quit\n\
        WScript.Quit\n\
End Sub\n\n\
"

);

    /*Will say string s*/

    complete=pat1+s+pat2;

    ofstream myfile;
    myfile.open (temp);
    myfile << complete;
    myfile.close();
    system(temp2);
    complete.clear();
    s.clear();

为不同的声音改变pat2用

string pat2=
(
"\")\n\
    Speech.rate = 0.05\n\
        If sText <> \"\" Then\n\
                SpeakText sText\n\n\
        End If\n\
End Sub\n\n\
Sub SpeakText(sText)\n\
        On Error Resume Next\n\
        Speech.Speak sText, SVSFlagsAsync + SVSFPurgeBeforeSpeak\n\
        Do\n\
                Sleep 200\n\
        Loop Until Speech.WaitUntilDone(10)\n\
End Sub\n\n\
Sub StopSpeaking()\n\
        On Error Resume Next\n\
        Speech.Speak vbNullString, SVSFPurgeBeforeSpeak\n\
        Set Speech = Nothing\n\
End Sub\n\n\
Sub CreateObjects\n\
        Set Speech = CreateObject(\"SAPI.SpVoice\")\n\
        with Speech \n\
            Set .voice = .getvoices.item(1)\n\
            .Volume = 100\n\
            .Rate = 4\n\
        end with\n\
        Set FSO = CreateObject(\"Scripting.FileSystemObject\")\n\
End Sub\n\n\
Sub DestroyObjects\n\
        Set Speech = Nothing\n\
        Set FSO = Nothing\n\
End Sub\n\n\
Sub Sleep(nTimeout)\n\
        WScript.Sleep nTimeout\n\
End Sub\n\n\
Sub Quit\n\
        WScript.Quit\n\
End Sub\n\n\
"
);

然后你就可以通过调用say("This is a test");来使用它

为了获得更多控制,您可以使用管道而不是 sytem() ,如果您想停止它,这将使您能够杀死 vbscript 进程。

【讨论】:

以上是关于C++ 的 MS SAPI 5.1 问题的主要内容,如果未能解决你的问题,请参考以下文章

C++ Microsoft SAPI:异步处理事件和泵消息

C++ —— 调用微软语音接口(SAPI),实现文字转语音播放

TTS C++程序只能在开发PC上运行

打印当前PATH的命令是啥(window`s API,使用c ++)[重复]

使用 SWIG (AIX 5.1) 从 Perl 调用 C++ 库时崩溃

关于sapi.h?急!