First of all, C++ is not my language (I'm a java programmer).
I've seen examples of Microsoft SAPI 5.1, and I need a way to print all the available voices in a machine. I've seen the Object token of SAPI, and I'm kinda confuse of how CComPtr is use to iterate through. Can anyone help me with this. Additionally, how can I pick a specific voice instead of using the default.
Based from the examples, you can get the default voice by invoking this codes:
ISpVoice * pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
So in short: How can I list all the voices available and how can I choose the voice?
//PS: I don't need to put it in a combo box (just like all examples that I've seen), I'm implementing this for a JNI dll library so an example of iteration is much preferred.
First off, CComPtr is a smart pointer abstraction over COM interfaces, not an enumerator.
To list all the voices, you need to enumerate the tokens in the SPCAT_VOICES category.
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();
}
}
}
If you want to pick a specific voice, you need to specify an attribute that's unique to that voice. EnumTokens allows you to specify required and optional attributes. The attributes are actually defined by the creator of the voice, but some common attributes are
So to specify "Microsoft Anna" instead of any voice, you would use
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(L"Name=Microsoft Anna", NULL, &cpSpEnumTokens)))
instead of
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens)))