Оглавление.Введение. Общие вопросы компьютерного распознавания и порождения речи.1. Программирование звука в Windows. 2. Основы цифровой обработки звуковых сигналов. 3. Определение параметров речевого сигнала. 4. Алгоритмы распознавания. 5. Использование Microsoft Speech API 5.1 для синтеза и распознавания речи. 6. Использование Microsoft Speech API 4.0 для синтеза речи. Ссылки. Об авторе. |
Компьютерное распознавание и порождение речиГлава 6. Использование Microsoft Speech API 4.0 для синтеза и распознавания речиТеперь рассмотрим версию SAPI 4.0, поскольку существующая на момент написания этих строк версия 5.1 не имеет русскоязычного движка (в том числе и сторонних производителей) или, по крайней мере, автору о таковом неизвестно. Для работы нужно будет скачать и установить Speech SDK 4.0 по адресу(http://www.microsoft.com/speech/download/old/sdk40a.asp). Условно-бесплатный движок (Lernout & Hauspie TTS3000 TTS Engine) для синтеза русской речи можно взять со страницы Microsoft Agent download page for end-users (http://www.microsoft.com/msagent/downloads/user.asp) . SAPI представляет собой набор компонентов, относящихся к различным логическим уровням. Группы объектов «Голосовые команды», «Голосовая диктовка» и «Голосовой текст» занимают верхний уровень. Разделяемые объекты, которые позволяют совместно использовать движки, занимают следующий уровень. «Прямое распознавание речи» и «Прямое преобразование текста в речь» занимают следующий уровень. Аудио-объекты занимают нижний уровень.
Объекты DirectSpeechRecognition и DirectTextToSpeech обеспечивают полный доступ к речевому движку. Их интерфейс можно считать самым низким уровнем, дающим как хорошую скорость, так и максимальный контроль. Они загружают движок в процесс и передают управление на микрофон и громкоговорители.
Голосовой текст. Голосовой текст- это средство, обеспечивающее простые возможности синтеза речи.
3.1. Пример кода.Приложение, использующее Voice Text API должно сначала инициализировать COM: #include "windows.h"
Далее приложение создает новый объект Voice Text и инициализирует его: PCVoiceText pCVTxt;
Посредством вызова Init() с именем приложения, приложение автоматически регистрируется. Чтобы заговорить, приложение вызывает CVoiceText::Speak(): hRes = pCVTxt->Speak(L"Hello world.");
После всего приложение освобождает объект и COM: if (pCVTxt)
Теперь поговорим подробнее о классе CVoiceText. Этот класс является оберткой для объекта Голосовой текст (ГТ). Объект ГТ представляет некоторое расположение на компьютере. Это расположение состоит из аудио-устройства, такого как компьютерный громкоговоритель или телефонная линия, и режима Text-to-speech (“Речь в текст”, TTS), обеспечиваемого движком. Внутри себя ГТ-расположение содержит два DirectToSpeech- объекта: объект TTS-движка и аудиовыход. Конструктор CVoiceText(void) Деструктор ~CVoiceText(void) Способы инициализации Приложению необходимо инициализировать оболочку объекта «Голосовой текст». Вот несколько вариантов функции Init: HRESULT Init (void) Создает новый COM-объект. Приложению необходимо вызвать Register. HRESULT Init (LPUNKNOWN pIUnkVTxt) Создает объект из существующего объекта «Голосовой текст». Обертка вызовет AddRef для pIUnkVTxt и освободит его, когда обертка будет разрушена. Приложение может пожедать вызвать pIUnkVTxt->Release после вызова Init. HRESULT Init (
Инициализирует обертку и вызывает Register с указанными параметрами. HRESULT Init (
Инициализирует обертку и вызывает Register c указанными параметрами.
3.2. Методы атрибутов.DeviceGet HRESULT DeviceGet (DWORD *pdwDeviceID);
Получает идентификатор аудио-устройства вывода, используемого ГТ-расположением. Возвращает NOERROR в случае успеха, или один из следующих кодов ошибки:
Идентификатор устройства для расположения сохраняется между использованиями расположения, даже если пользователь выключит компьютер в процессе работы программы. DeviceSet HRESULT DeviceSet (DWORD dwDeviceID) Устанавливает устройство аудио-вывода для использования ГТ-расположением. Возвращает NOERROR в случае успеха или одно из следующих значений:
Приложение может получить список устройств посредством вызова функций мультимедиа waveOutGetNumDevs и waveOutGetDevCaps. Идентификатор устройства для расположения сохраняется между использованиями расположения. EnabledGet HRESULT EnabledGet (DWORD *dwEnabled);
Определяет, доступен или нет голосовой текст для ГТ-расположения. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Предоставление или ограничение доступа к голосовому тексту отражается на всех приложениях, использующих ГТ-расположение. Обычно приложению не доступен голосовой текст из-за того, что пользователь не хочет, чтобы компьютер разговаривал. Придется касаться настроек пользователя, чтобы дать или ограничить доступ к голосовому тексту. Режим доступности сохраняется между использованиями расположения. EnabledSet HRESULT EnabledSet (DWORD dwEnabled) Дает или ограничивает доступ к голосовому тексту ГТ-расположению. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
IsSpeaking HRESULT IsSpeaking (BOOL *pfSpeaking);
Определяет, проговаривается ли текст в настоящий момент. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
IsSpeaking связан с извещениями ITTSNotifySink::AudioStart and AudioStop. IsSpeaking возвращает FALSE на короткое время между концом одного буфера в очереди и началом следующего из-за того, что аудио-вывод временно завис. Причиной этого может быть то, что объект голосового текста не получает результирующие данные от многих вызовов функции Speak прямо в TTS-движок. Вместо этого, объект сохраняет данные от каждого вызова в отдельном бфере, так чтобы строки приоритета VTXTSP_HIGH и VTXTSP_VERYHIGH могли быть вставлены в очередь в правильном месте. Например, приоритет VTXTSP_VERYHIGH может прервать строку с нормальным или высоким приоритетом. Прерванная строка обрабатывается после того, как будет обработана строка с очень высоким приоритетом. SpeedGet HRESULT SpeedGet (DWORD *pdwSpeed);
Получает текущую среднюю скорость речи для ГТ-расположения в словах в минуту. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Скорость речи для расположения сохраняется между использованиями расположения. SpeedSet HRESULT SpeedSet (DWORD dwSpeed) Устанавливает среднюю скорость речи для ГТ-расположения в словах в минуту. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Скорость речи для расположения сохраняется между использованиями расположения. 3.3. DirectTextToSpeech API3.3.1. Пример кода Объект DirectTextToSpeech позволяет очень легко использовать TTS из С++, особенно для тех, кто не обладает опытом программирования COM. Для начала программа, использующая это самый COM, должна его инициализировать: #include "windows.h" Затем приложение создает новый объект режима (mode) и затем его инициализирует: PCTTSMode pCTTSMode;
Посредством вызова Init() без параметров приложение выбирает TTS-движок по умолчанию. Сущестует другой вариант вызова Init(), который позволяет программе лучше управлять речевым движком. Следующая вещь, которую должно сделать приложение, чтобы заговорить: hRes = pCTTSMode->Speak(L"Hello, World.");
Когда этот кусок отработает, приложение освободит объекты и COM: if (pCTTSMode)
3.3.2. Класс CTTSMode. Объект CTTSMode служит оберткой для TTS-движка (производимого поставщиком движка) и части объектов перечислений движка. Он обертывает все интерфейсы объекта TTS-режима. Объект TTS-режима представляет режимы движка, которые преобразуют текст в речь, пригодную для озвучивания. Движок обычно поддерживает набор TTS-режимов, которые могут использоваться для озвучивания текста посредством различных голосов или с различной скоростью. Объект движка поддерживается его поставщиком. Конструктор CTTSMode (void); Деструктор ~CTTSMode (void); Методы инициализации. Если приложение намерено перенаправить звук куда-то кроме компьютерного звукового устройства по умолчанию, оно должно вызвать одну из функций InitAudioTest. HRESULT InitAudioDestMM (DWORD dwDeviceID); Инициализирует TTS на использование мультимедийного звукового устройства с указанным идентификатором. HRESULT InitAudioDestDirect (LPUNKNOWN lpUnkDirect); Инициализирует TTS-движок на использование DirectSound. Приложение должно передать в lpUnkDirect ссылку на библиотеку, и освободить ее при окончании работы движка. HRESULT InitAudioDestObject (LPUNKNOWN lpUnk); Инициализирует TTS-движок, использующий различные аудио-выходы. Приложение должно вызвать CoCreateInstance и инициализировать аудио-выход. Библиотека вызывает AddRef для lpUnk, а приложение может пожедать вызвать lpUnk->Release после вызова InitAudioDestObject. Init Приложению необходимо инициализировать TTS-режим. Вот несколько вариантов функции Init: HRESULT Init (void) Инициализирует, используя TTS-движок по умолчанию. Идентификатор языка получается из текущего потока. HRESULT Init (GUID gMode) Инициализирует TTS-движок, используя специальный GUID (глобальный идентификатор, сохраняемый в реестре) режима. HRESULT Init (TTSMODEINFOW *pTTSModeInfo, TSMODEINFORANK *pSRModeInfoRank = NULL) Инициализирует TTS-движок, находя ближайший движок к требуемому в pTTSModeInfo. HRESULT Init (LPUNKNOWN lpUnk) Заставляет объект использовать существующий TTS-режим. lpUnk увеличивает количество ссылок (AddRef) и все ссылки освобождаются, когда разрушается объект. Приложение может вызвать lpUnk->Release после вызова Init.
Методы атрибутов. PitchGet HRESULT PitchGet (WORD *pwPitch);
Возвращает текущий базовый уровень высоты тона для TTS-режима. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Если текст содержит управляющие тэги, действующий уровень высоты тона голоса обычно колеблется возле базового уровня. Тэг Pitch изменяет базовый уровень для режима, так же как если бы была вызвана функция PitchSet. Базовый уровень высоты тона по умолчанию – оптимальный уровень для режима. PitchSet HRESULT PitchSet (WORD wPitch); Устанавливает базовый уровень высоты тона для TTS-режима. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Действующий уровень высоты тона обычно колеблется возле базового уровня. Обычно не следует его понижать. Phoneme HRESULT Phoneme(VOICECHARSET eCharacterSet, DWORD dwFlags, SDATA dText, PSDATA pdPhoneme); Переводит текст в фонемное представление, являющееся промежуточным шагом между Unicode-текстом и цифровыми аудио-данными. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
eCharacterSet
CHARSET_TEXT не может быть использован как набор символов для конвертации. Вызывающее приложение выделяет память для структуры SDATA и передает ее адрес Phoneme. Phoneme выделяет память (используя аллокатор задач OLE) для возвращаемых данных и помещает указатель на нее в атрибут pData структуры SDATA. Если память выделить не удается, pData устанавливается в NULL, а атрибут dwSize равен нулю. После вызова приложение должно освободить память, на которую указывает pData, также как и саму структуру SDATA. Эта функция может быть использована, чтобы видоизменить фонетическое представление текста до того, как оно будет озвучено движком, например для установки более корректного произношения. Функция Phoneme синхронная, что означает, что она не вернет управление, пока конвертация не закончится. В зависимости от объема обрабатываемого текста это процесс может занять достаточно малое или достаточно большое время, так что порой целесообразно вызывать эту функцию в отдельном потоке. Если значение CHARSET_IPAPHONETIC используется в ANSI-версии, функция возвратит ошибку. Чтобы освободить память, выделенную этой функцией, вызывающей CoTaskMemAlloc , нужно вызвать CoTaskMemFree. Register HRESULT Register (PVOID pNotifyInterface, IID IIDNotifyInterface, DWORD *pdwKey);
Регистрирует интерфейс ITTSNotifySink для движка, чтобы использовать для оповещения движка независимые от буфера TTS-события. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Приложение может вызывать Register многократно. Функция возвращает различные ключи каждый раз, когда она вызывается. Приложение может использовать IID_ITTSNotifySink для ANSI или Unicode в зависимости от умолчаний для приложения. TextData HRESULT TextData (
Начинает процесс конвертации текста в аудиоданные, пригодные для озвучивания. Приложение может передать один или несколько управляющих тэгов без реального текста. Например: TextData с "\Rst\" будет работать. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Speak HRESULT Speak (
Проговаривает текст, обрабатывая тэги, если fTagged равен TRUE. UnRegister HRESULT UnRegister (DWORD dwKey); Позволяет приложению освободить интерфейс оповещения, через который движок посылает TTS-сообщения в приложение. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов: · E_INVALIDARG
Приложение должно вызвать UnRegisterдо до закрытия объекта движка.
3.3.3. Класс CTTSEnum. Объект CTTSEnum является оберткой для объекта перечисления. Он обертывает все интерфейсы объекта TTS-перечисления. Объект TTS-перечисления перечисляет TTS-режимы, предоставляемые всеми движками, доступными приложению. Приложение использует TTS-перечисление, чтобы выбрать TTS-режим и создать объект движка, предоставляющий этот режим в программу. TTS-перечисление поддерживается Microsoft. Конструктор CTTSEnum (void); Деструктор ~CTTSEnum (void); Методы инициализации Init HRESULT Init (void); Приложению нужно вызвать Init до использования объекта. · HRESULT Init (void) Инициализирует перечисление, создавая новый объект перечисления. HRESULT Init (LPUNKNOWN lpUnkEnum) Базирует объект перечисления на существующем COM-объекте. lpUnkEnum увеличивает счетчик ссылок (AddRef) и освобождается, когда объект перечисления разрушается. Методы перечисления Clone CTTSEnum* Clone (void); Получает новое перечисление, содержащее тот же статус перечисления, что и текущее. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов: · E_INVALIDARG
Используя Clone, возможно записать специфический элемент в последовательность перечисления и затем вернуться к этому элементу в последующем. Перечисление возвращает значение того же типа интерфейса, что и был клонирован. Next HRESULT Next (ULONG uNum, PTTSMODEINFOW pTTSModeInfo, ULONG *uFound = NULL); HRESULT Next (PTTSMODEINFOW pTTSModeInfo); Получает конкретный номер элемента в последовательности перечислении. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов: · E_INVALIDARG
Reset HRESULT Reset (void); Сбрасывает последовательность перечисления на начало. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
Select HRESULT Select (GUID gModeID, PCTTSMode *ppCTTSMode, LPUNKNOWN pUnkAudio = NULL); Выбирает движок. Обратите внимание, что метод возвращает pCTTSMode. Объект режима уже инициализирован. Выбирает TTS-режим и создает объект движка, представляющий выбранный режим. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов:
После того как приложение перечислит TTS-режимы и определит, какой именно использовать, оно вызывает Select, чтобы создать объект движка. Как только объект движка будет инициализирован, он вызывает интерфейс IAudio звуко-ориентированного объекта, определенного посредством pUnkAudio, чтобы определить, который из двух видов устройст вывода будет использоваться. Если это возможно, функция вернет объект CTTSMode для вновь созданного объекта движка. Иначе, объект движка освободит сам себя и функция Select возвратит ошибку. После создания объекта движок вызывает IAudio::PassNotify, чтобы передавать свои собственные извещения звуко-ориентированному объекту. Передача шлюза оповещения звуко-ориентированному объекту позволяет объекту извещать движок, когда звуковые данные закончили воспроизводиться. Когда все ссылки на объект движка освобождены, объект движка вызывает IAudio::Release. Мультимедийный звуко-ориентированный объект может использоваться для передачи аудио-данных устройству звукового вывода. Функция Select передает интерфейс IUnknown раньше, чем интерфейс IAudioDest, поэтому, хотя все устройства должны поддерживать IAudioDest, некоторые движки могут использовать пользовательские интерфейсы, чтобы работать со специальными устройствами и драйверами и IUnknown может быть использован, чтобы получить такой интерфейс.. Параметр pIUnknownForAudio получается в результате использования функции CoCreateInstance. Из –за того, что счетчик ссылок начинается с 1, интерфейс должен быть освобожден после того как отработает Select. Работа с звуко-ориентированным объектом ведется внутри функции Select, поэтому, если Select отработала без ошибок, контакт с ним успешно установлен. Skip HRESULT Skip (ULONG uNum = 1); Перепрыгивает через заданное число элементов в последовательности. Возвращает NOERROR в случае успеха, иначе – один из следующих кодов: · E_INVALIDARG
Find HRESULT Find (PTTSMODEINFOW pTTSFind, PTTSMODEINFORANK pRank, PTTSMODEINFOW pTTSFound); HRESULT Find (PTTSMODEINFOW pTTSFind, PTTSMODEINFOW pTTSFound); Ищет TTS-режим, который наиболее точно соответсвует желаемым характеристикам. Returns NOERROR, if successful, or one of these error values: · E_FAIL
Если нет подходящих движков или система исчерапала доступную память, возвращается ошибка.
3.3.4. Структуры данных.
TTSMODEINFO typedef struct { // ttsmi
Обеспечивает детальную информацию о TTS-режиме, поддерживаемом конкретным движком.
Свойства, обеспечиваемые данным движком определяются автором движка. Приложение может использовать интерфейс ITTSEnum, чтобы перечислить движки и определить, какой из них должен быть выбран, чтобы обеспечить необходимую функциональность. LANGUAGE typedef struct { // lang
Содержит название языка и диалекта. Строки языка и диалекта не зависят от регистра.
SDATA typedef struct { // sdata
Содержит адрес буфера данных и объем данных в буфере. Приложение использует эту структуру, чтобы передавать данные различным API-функциям.
|