C++ sapi:用户输入,编辑语音输出

Posted

技术标签:

【中文标题】C++ sapi:用户输入,编辑语音输出【英文标题】:C++ sapi: User input, edit voice out 【发布时间】:2015-05-31 20:57:03 【问题描述】:
#include <sapi.h>
#include <string>
#include <iostream>

//User inputs what is to be said//
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))
    
        std::wstring input;
        while (true)
        
            std::cout << "Enter text:\n";
            std::getline(std::wcin, input);

            hr = pVoice->Speak(input.c_str(), 0, NULL);
        
    
    pVoice->Release();
    pVoice = NULL;
    ::CoUninitialize();
    return 0;

上面的代码允许用户输入他们想要说的内容并完美运行。

以下是 MSDN 改变音高的方法,任何其他类似的操作都以相同的方式完成。

hr = pVoice->Speak(L"This sounds normal <pitch middle = '-10'/> but the pitch drops half way through", SPF_IS_XML, NULL );

我想改变音高,但不知道如何使用我拥有的代码执行相同的操作。

【问题讨论】:

所以问题不在于 SAPI,而在于字符串操作。 我认为它与 sapi 更相关。 MSDN 中的方法使用 &lt;pitch middle = '-10'/&gt; 方法处理音频输出,这严格来说是一个 sapi 方法。如果该操作正在操作字符串,我现在不知道它是如何完成的。 根据您的问题,更改音高意味着将元信息添加到字符串的某些部分。那里唯一与 SAPI 相关的东西是添加的块的内容。不过,要回答这个问题,添加的内容可以是任何内容,并且其工作方式相同。 在用户输入字符串之前不会知道该字符串,然后立即执行代码。所以我可以编写一个在用户输入信息后运行的函数,打开input,添加音高变化,然后继续音频输出?我问这个问题是因为我不知道是否“打开”这样的字符串,然后编辑它是可能的。 是的,您可以更改字符串。这是字符串操作的一部分,与其他一些语言不同,C++ 允许在创建字符串后直接修改字符串,这意味着您不必创建新字符串来操作它们。您可能想查看std::string 的一些示例,看看您可以用它们做什么。使用std::wstring 可以完成相同的操作,但使用wchar_t 而不是char 【参考方案1】:

你必须像那样集中 XML 指令

std::wstring input;
std::getline(std::wcin, input);
pVoice->Speak(std::wstring(L"<pitch middle = '+10'>"+input).c_str(), 0, 0);

祝你好运!

【讨论】:

【参考方案2】:

我知道这篇文章大约有 22-23 天的历史,但我决定试一试。我无法让所有的声音随时改变音高,但 MS Anna 绝对可以。

#include <sapi.h>
#include <sphelper.h>
#include <string>
#include <conio.h>

void SetVoice(CComPtr<ISpVoice>  _cpVoice, std::wstring _voiceName)

    IEnumSpObjectTokens *pProfileEnum;
    SpEnumTokens(SPCAT_VOICES, NULL, NULL, &pProfileEnum);

    unsigned long l;
    pProfileEnum->GetCount(&l);

    for(unsigned long i = 0; i < l; ++i) 
       CComPtr<ISpObjectToken> IT;
       pProfileEnum->Item(i, &IT);
       WCHAR *wptr;
       IT->GetId(&wptr);
       CSpDynamicString dstrDefaultName;
       SpGetDescription(IT, &dstrDefaultName);
       if(wcsncmp(dstrDefaultName, _voiceName.c_str(), _voiceName.size()) == 0)
            _cpVoice->SetVoice(IT);
       
   


int main(int argc, char* argv[])

    CoInitialize(0);
    CComPtr<ISpVoice>   cpVoice;
    CComPtr<ISpAudio>   cpOutAudio;

    HRESULT hr = cpVoice.CoCreateInstance(CLSID_SpVoice);

    SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOOUT, &cpOutAudio);

    if(nullptr != cpVoice) 
        hr = cpVoice->SetOutput(cpOutAudio, FALSE);
    

    SetVoice(cpVoice, L"Microsoft Anna - English (United States)");
    if(cpVoice) 
        cpVoice->Speak(L"<pitch absmiddle=\"+10\">This is a really high pitched voice</pitch> <pitch absmiddle=\"-10\"> but the pitch drops half way through</pitch>", SVSFIsXML | SVSFPurgeBeforeSpeak, NULL);
    
    puts("Press any key to continue...");
    getch();
    return 0;

【讨论】:

以上是关于C++ sapi:用户输入,编辑语音输出的主要内容,如果未能解决你的问题,请参考以下文章

应用程序重新启动 C++ Visual Studio 时保存编辑控件用户输入和恢复的有效方法

python 语音输入

当用户输入除整数以外的任何内容时,为啥我的程序会无限循环输出? C++ [重复]

C++ Win32api 从用户输入输出 Unicode

小白学习C++ 教程三C++用户输入判断语句和switch

Microsoft Speech API (SAPI) UserTraining 语法