Простой пример использования SAPI 5.x в программах на C/C++

Дата публикации:2010
Поделиться в Twitter Поделиться в F******k Поделиться в VKontakte Поделиться в Telegram Поделиться в Mastodon

На примере простого консольного приложения ниже будет описан способ использования синтеза речи по тексту для MS SAPI 5.x. В примере приведен код для SAPI 5.1, но принципиальных отличий в использовании SAPI 5.3 (MS Windows Vista) и SAPI 5.4 (MS Windows 7) нет.

Проект в среде разработки от Microsoft

Сначала рассмотрим последовательность действий , которая рекомендована в SAPI SDK для компиляции примера в среде Microsoft Visual Studio.

Для простоты возьмем за основу консольное приложение Windows. В среде разработки Visual Studio необходимо воспользоваться application wizard, чтобы создать Win32 console application. В ответ на запрос Мастера надо указать "Hello, world" В качестве шаблона. После создания проекта необходимо открыть файл STDAfx.h и после строки

"#include " 

но до строки, содержащей #endif поместить следующий код :

#define _ATL_APARTMENT_THREADED
#include 
extern CComModule _Module;
#include 

Эти строки подключают дополнительные файлы, которые необходимы для работы SAPI.

Затем в настройках проекта следует добавить путь к файлам SAPI.h и SAPI.lib. Найти эти файлы можно в соответствующих подкаталогах каталога, куда была выполнена установка SAPI SDK (по умолчанию это C:\Program Files\Microsoft Speech SDK 5.x, где x – номер субверсии SAPI).

Необходимо открыть диалог настроек проекта, выбрав пункт меню Project->Settings. В диалоге надо щелкнуть по вкладке C/C++ и выбрать элемент Preprocessor из выпадающего списка Category. Затем необходимо ввести следующий текст в поле "Additional include directories" (пример для SAPI 5.1)::

C:\Program Files\Microsoft Speech SDK 5.1\Include.

Чтобы установить путь к SAPI.lib , нужно в том же самом диалоге настроек проекта выбрать вкладку Link, на которой выбрать элемент Input из выпадающего списка Category. Затем следует добавить такой путь в поле "Additional library path" (пример для SAPI 5.1):

C:\Program Files\Microsoft Speech SDK 5.1\Lib\i386.

Кроме того, необходимо добавить "sapi.lib" в строку "Object/library modules" . Обратите внимание, что имена файлов должны быть отделены пробелами.

Исходный код примера

SAPI – это приложение, основанное на COM, поэтому поддержка COM должна быть инициализирована перед использованием SAPI и в течение всего времени, пока SAPI является активным. Инициализация COM выполняется через вызов функции CoInitialize(NULL), а обратная операция – при помощи CoUninitialize().

После того как была инициализированна поддержка COM, нужно создать "голос", то есть реализацию интерфейса ISpVoice . Голос – это простой COM-объект, создаваемый при помощи стандартного вызова CoCreateInstance(). Однако в процессе его инициализации SAPI автоматически назначает для ряда параметров значения по умолчанию. Эти значения подобраны так, чтобы голос можно было использовать непосредственно после инициализации. Значения по умолчанию берутся из свойств элемента Речь (Speech) в Панели управления (Control Panel). Все значения по умолчанию могут быть изменены либо программно, либо в элементе Речь (Speech) Панели управления (Control Panel).

Чтобы озвучить текст достаточно вызвать метод Speak(), который принимает три параметра: указатель на строку озвучиваемого текста (Unicode-строка), набор флагов, управляющих процессом озвучивания, и указатель на long, по которому будет размещено возвращаемое значение номера потока (в примере это значение не используется, поэтому в параметре передается NULL).

В приводимом примере метод Speak() вызывается дважды, чтобы показать возможность использования речевой разметки для управления параметрами голоса (на это указывает флаг SPF_IS_XML, помещенный в качестве второго параметра). Теги речевой разметки представляют собой теги XML; их можно помещать непосредственно в озвучиваемый текст и они будут оказывать влияние на чтение текста, который идет вслед за тегами.

После того как голос был использован и больше не нужен, необходимо его освободить, то есть вызвать метод Release().

Теперь воплотим все вышеописанное в исходный код..


#include 
#include 

int main(int argc, char* argv[])
{
    ISpVoice * pVoice = NULL;

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

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)pVoice;);
    if( SUCCEEDED( hr ) )
    {
        hr = pVoice->Speak(L"Hello world", 0, NULL);

        // Меняем темп речи
        hr = pVoice->Speak(L" Hello, world!",
        	SPF_IS_XML, NULL );
        pVoice->Release();
        pVoice = NULL;
    }
    ::CoUninitialize();
    return 0;
}

Другие компиляторы

Если для компиляции примера используется другой компилятор, не совместимой с форматом бинарных файлов coff (например, компилятор Borland C++ или MinGW), то нельзя будет использовать библиотеку sapi.lib из MSAPI SDK. В этой библиотеке хранятся глобальные идентификаторы COM-объектов и их интерфейсов. Чтобы восполнить отсутствие sapi.lib, эти идентификаторы придется определить вручную, поместив соответствующие определения в исходный код примера (перед функцией main()). С учетом этой особенности код примера примет вид:

#include 
#include 
#include 
#include 

/*  96749377-3391-11D2-9EE3-00C04F797396 */
const CLSID CLSID_SpVoice= {0x96749377, 0x3391, 0x11D2, {0x9E, 0xE3,0x00,0xC0,0x4F,0x79,0x73,0x96}};

/*  6C44DF74-72B9-4992-A1EC-EF996E0422D4 */
const IID IID_ISpVoice  = {0x6C44DF74, 0x72B9, 0x4992, {0xA1, 0xEC,0xEF,0x99,0x6E,0x04,0x22,0xD4}};

int main(int argc, char* argv[])
{
    ISpVoice * pVoice = NULL;

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

HRESULT hr = CoCreateInstance(CLSID_SpVoice,
NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
    if( SUCCEEDED( hr ) )
{
        hr = pVoice->Speak(L"Hello world", 0, NULL);
//   Меняем темп речи
        hr = pVoice->Speak(L" Hello, world!",
        	SPF_IS_XML, NULL );
        pVoice->Release();
        pVoice = NULL;
    }
    ::CoUninitialize();
    return 0;
}

Другие способы управления голосом

Управлять настройками речевого синтеза можно не только при помощи тегов речевой разметки. Ниже приведены некоторые методы интерфейса ISpVoice (полный перечень методов можно найти в соответствующем разделе SAPI SDK):

HRESULT SetRate( 
   long   RateAdjust 
); 

Устанавливает темп речи. В качестве параметра передается значение от -10 до 10.

HRESULT GetRate( 
   long   *pRateAdjust 
); 

Возвращает текущее значение темпа речи. В качестве параметра передается указатель на long, по которому будет записано возвращаемое значение.

HRESULT SetVolume( 
   USHORT 	usVolume 
); 
Устанавливает уровень громкости. В качестве параметра принимает значение от 0 до 100.

HRESULT GetVolume( 
   USHORT   *pusVolume 
);

Возвращает текущее значения уровня громкости. В качестве параметра принимает указатель, по которому будет записано возвращаемое значение.

HRESULT  Pause  ( void );
Приостанавливает озвучивание текста. Продолжить процесс можно, вызвав метод Resume(). Если синтезатор уже находится в состоянии паузы, то каждый последующий вызов Pause() увеличивает внутрений счётчик на единицу. Таким образом, количество вызовов Resume() должно совпадать с количеством вызовов Pause(), чтобы вывести синтезатор из состояния паузы.

HRESULT  Resume  ( void );

Уменьшает внутренний счётчик пауз. Если этот счётчик становится равным нулю, то сообщает синтезатору о необходимости продолжить озвучивание текста. Если синтезатор не находится в состоянии паузы, то вызов Resume() не имеет никакого эффекта.



Распространение материалов сайта означает, что распространитель принял условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2024