C ++和Microsoft SAPI 5:如何列出所有可用语音并选择语音

时间:2013-07-16 11:20:58

标签: c++ visual-studio-2012 java-native-interface sapi

首先,C ++不是我的语言(我是一名java程序员)。

我见过Microsoft SAPI 5.1的示例,我需要一种方法来打印机器中所有可用的声音。我见过SAPI的Object token,我有点混淆了CComPtr如何用来迭代。谁能帮我这个。此外,如何选择特定语音而不是使用默认语音。

根据示例,您可以通过调用以下代码来获取默认语音:

ISpVoice * pVoice = NULL;

if (FAILED(::CoInitialize(NULL)))
    return FALSE;

HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

简而言之:如何列出所有可用的声音以及如何选择声音?

// PS:我需要把它放在一个组合框中(就像我见过的所有例子一样),我正在为JNI dll库实现这个,所以迭代的例子是首选。

2 个答案:

答案 0 :(得分:4)

首先,CComPtr是COM接口上的智能指针抽象,而不是枚举器。

要列出所有语音,您需要枚举SPCAT_VOICES类别中的令牌。

HRESULT hr = S_OK;
CComPtr<ISpObjectTokenCategory> cpSpCategory = NULL; 
if (SUCCEEDED(hr = SpGetCategoryFromId(SPCAT_VOICES, &cpSpCategory))) 
{ 
    CComPtr<IEnumSpObjectTokens> cpSpEnumTokens; 
    if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens))) 
   { 
        CComPtr<ISpObjectToken> pSpTok;
        while (SUCCEEDED(hr = cpSpEnumTokens->Next(1,&pSpTok, NULL)))) 
        {
            // do something with the token here; for example, set the voice
            pVoice->SetVoice(pSpTok,FALSE); 
            // NOTE:  IEnumSpObjectTokens::Next will *overwrite* the pointer; must manually release
            pSpTok.Release(); 
        }
   } 
} 

如果您想选择特定的语音,则需要指定该语音特有的属性。 EnumTokens允许您指定必需属性和可选属性。这些属性实际上是由语音的创建者定义的,但是一些常见的属性是

  • 姓名(例如“Microsoft Anna”)
  • 语言(由数字区域设置ID指定)
  • 性别(男/女)
  • 供应商(创建声音的公司名称)

因此,要指定“Microsoft Anna”而不是任何语音,您可以使用

if (SUCCEEDED(hr = cpSpCategory->EnumTokens(L"Name=Microsoft Anna", NULL, &cpSpEnumTokens))) 

而不是

if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens))) 

答案 1 :(得分:0)

enum方法确实有效,但有点笨重。最好的方法是打开注册表并浏览密钥及其属性,您可以在此处找到更多信息:

msdn: SAPI Tokens, Categories and the Registry

这又是一项工作,所以我在做其他事情的同时创建了一个界面,它可以帮助你或其他人:

Sapi interface for enumerating and searching voice tokens