Visual Studio 2012 — C ++ и Microsoft SAPI 5. Как составить список всех доступных голосов и выбрать голос

Прежде всего, C ++ не мой язык (я программист Java).

Я видел примеры Microsoft SAPI 5.1, и мне нужен способ распечатать все доступные голоса на машине. Я видел Токен объекта SAPI, и я не совсем понимаю, как использовать CComPtr для итерации. Кто-нибудь может мне с этим помочь. Кроме того, как я могу выбрать определенный голос вместо использования по умолчанию.

Основываясь на примерах, вы можете получить голос по умолчанию, вызвав следующие коды:

ISpVoice * pVoice = NULL;

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

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

Итак, вкратце: Как я могу перечислить все доступные голоса и как я могу выбрать голос?

// PS: я не Мне нужно поместить его в поле со списком (как и все примеры, которые я видел), я реализую это для библиотеки DLL JNI, поэтому пример итерации гораздо предпочтительнее.

2

Решение

Прежде всего, 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 Анна»)
  • Язык (определяется числовым идентификатором локали)
  • Пол Мужской Женский)
  • Продавец (название компании, которая создала голос)

Таким образом, чтобы указать «Microsoft Anna» вместо любого голоса, вы бы использовали

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

вместо

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

Другие решения

Метод enum работает, но немного неуклюже. Лучший способ — открыть реестр и просмотреть ключи и их атрибуты. Вы можете найти больше информации здесь:

msdn: токены SAPI, категории и реестр

Опять же, это немного трудоемко, поэтому я создал интерфейс, делая что-то еще, и это может помочь вам или кому-то еще:

Интерфейс Sapi для перечисления и поиска голосовых токенов

0

По вопросам рекламы [email protected]