Разработка программного обеспечения для голосового управления трехмерными моделями функционирования промышленных роботов

Цифровая обработка сигналов и ее использование в системах распознавания речи, дискретные сигналы и методы их преобразования, основы цифровой фильтрации. Реализация систем распознавания речи, гомоморфная обработка речи, интерфейс записи и воспроизведения.

Рубрика Коммуникации, связь, цифровые приборы и радиоэлектроника
Вид дипломная работа
Язык русский
Дата добавления 10.06.2010
Размер файла 1,1 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

2.3.5 Обзор существующих систем распознавания речи

В настоящее время отсутствуют дикторонезависимые системы распознавания слитной речи как с неограниченным словарем, так и ограниченным, а имеющиеся системы (такие как Dragon Dictate - программа для печати текста с голоса) требуют очень много времени и терпения для того, чтобы обучить их удовлетворительно распознавать раздельно произносимые слова одного диктора. Среди других распознающих систем можно назвать Lotus Word Pro, MedSpeak, Voice Type Simplify Speaking, ViaVoice, Kurzweil Voice. He требующие обучения системы распознают обычно от нескольких десятков до сотен слов и используются для подачи команд голосом. Однако они также являются дикторозависимыми. В этой же области остается реализация амбициозных планов, наподобии принятого в 1986 в Японском национальном проекте АТК (Advanced Telecommunication Research), который состоял в том, чтобы получать речь на одном языке и одновременно синтезировать ее на другом или утверждения о реализации идеи человеко-машинного общения. Поэтому исследования в этой области являются весьма актуальными.

3. Разработка программного обеспечения для распознавания команд управления промышленным роботом

3.1 Реализация интерфейса записи и воспроизведения звукового сигнала в операционной системе Microsoft Windows

3.1.1 Основные сведения

Звуковые данные хранятся в компьютере с помощью метода импульсно-кодовой модуляции - РСМ. Расшифровывается РСМ как Pulse-Code Modulation. При этом методе аналоговый звук квантуется по времени и амплитуде. При выводе звука на колонки происходит обратное преобразование.

При прямом преобразовании кривая звука превращается в точки. Все, что между точками, теряется, поэтому чем чаще происходит замер амплитуды, тем выше качество звука и меньше потерь. Значение, обратное времени замера (Т3), называется частотой дискретизации - Тд. Для качественного звука частота дискретизации должна быть вдвое больше, чем высшая частота в обрабатываемом сигнале звука.

В Windows есть хорошо продуманная и хорошо документированная библиотека для работы со звуком - mmsystem.

Для работы со звуковой картой используется следующий алгоритм работы:

инициализировать звуковой драйвер;

установить параметры;

воспроизвести или записать звуковые данные;

закрыть драйвер.

Для вывода звука данные о звуке в цифровом виде просто отправляются звуковой карте. Она преобразует их в аналоговый сигнал [14].

3.1.2 Основные функции, необходимые для записи звука

Все основные функции содержатся в модуле rnmsystem, поэтому необходимо подключить этот модуль, а также добавить в проект файл WINMM.LIB.

Прежде всего необходимо заполнить структуру WAVEHDR. Она содержит следующие поля:

typedef struct wavehdr_tag {LPSTR lpData;

DWORD dwBufferLength;

DWORD dwBytesRecorded;

DWORD dwUser;

DWORD dwFlags;

DWORD dwLoops;

struct wavehdr_tag далеко * lpNext;

reserved DWORD;} WAVEHDR;

Структура WAVEHDR определяет заголовок, используемый, чтобы идентифицировать буфер звуковых данных

Составляющие структуры:

lpData - указатель на звуковые данные;

dwBufferLength - размер звуковых данных;

dwBytesRecorded - количество записанных байт (при воспроизведении этот параметр не используется);

dwUser - сюда можно записать все, что угодно;

dwFlags - здесь происходит описание заголовка. Конкретизирует флаги, предоставляющие информацию о буфере данных. Может принимать значения, приведенные в табл. 3.1

dwLoops - указывает количество циклов. Этот параметр используется только с буферами выходных данных.

lpNext - зарезервирован для использования драйвером устройства, чтобы указать на следующую структуру WAVEHDR в очереди.

reserved - зарезервирован для использования драйвером устройства.

Это поле может использоваться, чтобы запомнить указатель на структуру, содержащую информацию о клиенте.

Таблица 3.1- Флаги и их значения

Флаг

Значение

WHDR_DONE

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

WHDR_BEGINLOOP

показывает, что этот буфер - первый буфер в цикле. Этот флаг используется только с буферами выходных данных.

WHDR_ENDLOOP

показывает, что этот буфер - последний буфер в цикле. Этот флаг используется только с буферами выходных данных

WHDR_PREPARED

устанавливается драйвером устройства, чтобы указать, что буфер данных был подготовлен с помощью waveInPrepareHeader или waveOutPrepareHeader

WHDR_JNQUEUE

устанавливается драйвером устройства, чтобы указать, что буфер данных находится в очереди для воспроизведения

Используйте WHDR_BEGINLOOP и флаг WHDR_ENDLOOP в поле dwFlags, чтобы указать начала и концы блоков данных для использования их в цикле. Чтобы прокручивать в цикле один блок, необходимо установить оба флага для этого блока. Необходимо использовать поле dwLoops в структуре WAVEHDR для первого блока в цикле, чтобы установить количество циклов.

Первая функция используемая для записи звука - wavelnOpen. Эта функция устройство ввода для звукового потока. В модуле она объявлена следующим образом:

MMRESULT waveInOpen(

LPHWAVEIN phwi,

UINT_PTR uDevicero,

LPWAVEFORMATEX pwfx,

DWORD_PTR dwCallback,

DWORD_PTR dwCallbacklnstance,

DWORD fdwOpen);

В функции определен ряд параметров. Рассмотрим их основное назначение

phwi - адрес, по которому будет записан указатель на устройство воспроизведения. Этот параметр может быть NULL, если WAVE_FORMAT_QUERY указан для fdwOpen.

UDevicelD - идентификатор устройства, которое необходимо открыть, если поставить сюда константу WAVE_MAPPER, то откроется устройство по умолчанию.

IpFormat - указатель на структуру типа WAVEFORMATEX, в которой описан формат записываемых звуковых данных.

dwCallback - указатель на функцию «семафор». Эта функция вызывается для сообщения о текущих событиях.

fdwOpen - параметры открываемого устройства. Может принимать значения, приведенные в табл. 3.2

Необходимо использовать функцию wavelnGetNumDevs, чтобы определить число устройств ввода, присутствующих в системе. Идентификатор устройства, указанный uDeviceID, изменяется в пределах от ноля до на один меньше, чем количество присутствующих устройств. Константа WAVE_MAPPER может также использоваться в качестве идентификатора устройства.

Если выбирать, чтобы окно или поток получал информацию отзыва, следующие сообщения отправляются процедуре окна или потока, чтобы указать изменения в процессе ввода звуковой информации: MM_WIM_OPEN, MM_WIM_CLOSE, и MM_WIM_DATA.

Если вы выбираете, чтобы функция получала информацию отзыва, функции отправляются следующие сообщения, чтобы указать изменения в процессе ввода звуковой информации: WIM_OPEN, WIM_CLOSE, и WIM_DATA.

Таблица 3.2 - Параметры открываемого устройства

CALLBACK_EVENT

в параметре dwCallback находится событие THandle, через которое происходит информирование о ходе воспроизведения;

CALLBACK_FUNCTION

в dwCallback находится указатель на функцию;

CALLBACK_THREAD

в dwCallback находится идентификатор потока

CALLBACK_WINDOW

в dwCallback находится указатель на окно, которому посылается сообщение

CALLBACK_NULL

в dwCallback ничего нет

WAVE_ALLOWSYNC

можно открыть устройство в синхронном режиме

WAVE_FORMAT_DIRECT

запрещается преобразование данных с помощью АСМ-драйвера (ACM - Audio Compression Manager)

WAVE_FORMAT_QUERY

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

MMS YSERR_ALLOCATED

указанный ресурс уже занят

MMSYSERR_BADDEVICEID

указанный идентификатор устройства не существует

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

WAVERR_BADFORMAT

попытка открытия в неподдерживаемом звуковом формате

Необходимо заполнить структуру WAVEFORMATEX. Она имеет следующий вид:

typedef struct WAVEFORMATEX { WORD wFormatTag;

WORD nChannels;

DWORD nSamplesPerSec;

DWORD nAvgBytesPerSec;

WORD nBlockAlign;

WORD wBitsPerSample;

WORD cbSize;} WAVEFORMATEX;

В этой структуре:

wFormatTag - формат звуковых данных (чаще всего используется WAVE_FORMAT_PCM);

nChannels - количество каналов (1 - монО, 2 - стерео);

nSamplesPerSec - частота дискретизации (возможны значения 8000, 11025, 22050 и 44100);

nAvgBytesPerSec - количество байт в секунду для WAVEFORMATPCM это является результатом nSamplesPerSec* nBlockAlign;

nBlockAlign - выравнивание блока (для WAVEFORMATPCM равен wBitsPerSample /8* nChannels);

wBitsPerSample - количество бит в одной выборке (для WAVE_FORMAT_PCM может быть 8 или 16);

cbSize - размер дополнительной информации, которая располагается после структуры (если ничего нет, то должен быть 0).

Теперь следует подготовить заголовки, которые будут отправляться драйверу. Для этого существует функция waveInPrepareHeader

MMRESULT waveInPrepareHeader(

HWAVEOUT hwo,

LPWAVEHDR pwh,

U1NT cbwh);

Внутренняя структура:

hwo - идентификатор устройства записи (полученный после вызова функции wavelnOpen).

pwh - указатель на структуру wavehdr_tag;

cbwh - размер структуры wavehdr_tag.

Функция возвращает значения, приведенные в табл. 3.3.

При этом lpData, dwBufferLength, и dwFlags - члены структуры

WAVEHDR - должны быть установлены перед запросом этой функции (dwFlags должен быть нулевым).

Таблица 3.3 - Возвращаемые значения

MMSYSERR_NOERROR

успех

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_INVALPARAM

базовый адрес буфера не выровнен с объемом выборки

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

Для того, чтобы освободить драйвер необходимо использовать функцию waveInUnprepareHeader. Эта функция должна быть вызвана после того, как драйвер устройства заполняет буфер и возвращает его приложению. Необходимо вызвать эту функцию перед освобождением буфера.

MMRESULT waveInUnprepareHeader(

HWAVEIN hwi,

LPWAVEHDR pwh,

U1NT cbwh);

Параметры:

hwi - указатель на записывающее устройство;

pwh - указатель на структуру WAVEHDR, идентифицирующую буфер, который необходимо очистить.

cbwh - размер, в байтах, структуры WAVEHDR.

Функция возвращает MMSYSERR_NOERROR, если всё проходит успешно, если есть ошибки, возвращается одно из значений, приведенных в табл. 3.4.

Эта функция дополняет waveInPrepareHeader функцию. Необходимо вызвать эту функцию перед освобождением буфера. После передачи буфера в драйвер устройства функцией waveInAddBuffer, необходимо ждать, пока драйвер не закончит работу с буфером перед запросом waveInUnprepareHeader. Очистка буфера, который не был занят, не имеет никакого эффекта, и функция возвращает ноль.

Таблица 3.4 - Значения, выдаваемые при ошибках

Ошибка

Значение

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

MMSYSERR_STILLPLAYING

буфер, указанный pwh, занят

Для передачи буфера приёма данных предоставленному звуковому устройству используется функция waveInAddBuffer. Когда буфер заполнен, приложение получает соответствующее сообщение. Функция имеет следующий вид:

MMRESULT waveInAddBuffer(HWAVEIN hwi,

LPWAVEHDR pwh,

UINT cbwh);

Описание параметров:

hwi- указатель на входное устройство;

pwh - указатель на структуру WAVEHDR, которая идентифицирует буфер.

cbwh - размер, в байтах, структуры WAVEHDR.

Функция возвращает MMSYSERR_NOERROR, если всё проходит успешно, если есть ошибки, возвращает одно из значений, приведенных в табл. 3.5.

Таблица 3.5 - Возвращаемые значения

Ошибка

Значение

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

WAVERR_UNPREPARED

буфер, указанный pwh, не был готов

Когда буфер заполнен, бит WHDR_DONE установлен в dwFlags -члене структуры WAVEHDR.

Буфер должен быть подготовлен функцией waveInPrepareHeader перед тем, как это будет передаваться функции waveInAddBuffer.

Далее вызывается функция waveInStart. Она начинает ввод данных через предоставленное устройство. Эта функция выглядит следующим образом:

MMRESULT waveInStart(HWAVEIN hwi);

Параметр hwi указывает на устройство, принимающее информацию.

Функция возвращает MMSYSERR_NOERROR, если всё проходит успешно, если есть ошибки, возвращается одно значений, приведенных в табл. 3.6

Таблица 3.6 - Возвращаемые значения

Ошибка

Значение

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

Буферы возвращаются приложению, когда заполнены или, когда вызвана функция waveInReset(dwBytesRecorded) член в заголовке будет содержать длину данных). Если нет никаких буферов в очереди, данные проходят мимо приложения, и ввод продолжается.

Вызов этой функции, когда она уже была вызвана, не имеет эффекта, и функция возвращает ноль [15].

3.1.3 Основные функции, необходимые для воспроизведения звука.

Для воспроизведения звуковой информации первая функция waveOutOpen. Она открывает устройство вывода для звукового потока. В модуле она объявлена следующим образом:

MMRESULT waveOutOpen (LPHWAVEIN phwi,

UINT_PTR uDeviceID, LPWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwCallbacklnstance, DWORD fdwOpen);

В функции определен ряд параметров. Рассмотрим их основное назначение

phwi - адрес, по которому будет записан указатель на устройство воспроизведения;

UDeviceID - идентификатор устройства, которое необходимо открыть, если поставить сюда константу WAVE_MAPPER, то откроется устройство по умолчанию.

lpFormat - указатель на структуру типа WAVEFORMATEX, в которой описан формат воспроизводимых звуковых данных.

dwCallback - указатель на функцию «семафор». Эта функция вызывается для сообщения о текущих событиях.

dwFlags - параметры открываемого устройства. Может принимать следующие значения, совпадающие со значениями fdwOpen для функции wavelnOpen

Структура WAVEFORMATEX для воспроизведения звуковой информации имеет такой же вид, как и для записи. Однако при воспроизведении звука, она заполняется автоматически при выборе воспроизводимого файла.

Теперь предстоит подготовить заголовки, которые будут отправляться драйверу. Для этого есть функция waveOutPrepareHeader

MMRESULT waveOutPrepareHeader(HWAVEOUT hwo,

LPWAVEHDR pwh,

UINT cbwh);

Возвращаемые параметры те же. Внутренняя структура:

hwo - идентификатор устройства воспроизведения (полученный

после вызова функции waveOutOpen).

pwh - указатель на структуру wavehdr_tag; cbwh - размер структуры wavehdr_tag.

Теперь структура wavehdr_tag. Она выглядит так же, как и в случае записи.

После окончания работы с этим заголовком нужно освободить его с помощью функции waveOutUnprepareHeader.

Теперь нужно отправить подготовленный заголовок драйверу. Для этого используется функция waveOutWrite, которая выглядит следующим образом:

MMRESULT waveOutWrite (HWAVEOUT hwo,

LPWAVEHDR pwh,

UINT cbwh);

В ней:

hwo - идентификатор устройства воспроизведения;

pwh - это указатель на структуру, сформированную с помощью waveOutPrepareHeader;

cbwh - размер структуры wavehdr. Возвращаемые значения те же, что и при открытии звуковой карты.

После вывода звука нужно вызвать waveOutUnprepareHeader, чтобы очистить заголовки и закрыть устройство. Теперь необходимо закрыть устройство с помощью функции waveOutClose. Она имеет следующий вид:

MMRESULT waveOutClose (HWAVEOUT hwo);

Параметр hwo указывает на устройство вывода. Если функция завершается успешно, дескриптор не больше действителен после этого вызова. Функция возвращает MMSYSERR_NOERROR, если всё проходит успешно, если есть ошибки, возвращается одно из значений, приведенных в табл. 3.7.

Если устройство ещё воспроизводит звуковой файл, функция его не закрывает. Необходимо использовать функцию waveOutReset, чтобы закончить воспроизведение перед запросом waveOutClose.

Таблица 3.7 - Возвращаемые значения

Ошибка

Значение

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

WAVERR_STILLPLAYING

буфер, указанный pwh, занят

waveOutReset останавливает воспроизведение на указанном вывода и сбрасывает текущую координату в нолю. Воспроизведение из буферов отмечается как выполнено и управление передаётся приложению. Функция имеет следующий вид:

MMRESULT waveOutReset (HWAVEOUT hwo);

Параметр hwo указывает на устройство вывода.

Функция возвращает MMSYSERR_NOERROR, если всё проходит успешно, если есть ошибки, возвращается одно из значений, приведенных в табл. 3.8 [14,15].

Таблица 3.8 - Возвращаемые значения

Ошибка

Значение

MMSYSERR_INVALHANDLE

указанный дескриптор устройства недействителен

MMSYSERR_NODRIVER

нет драйвера для устройства

MMSYSERR_NOMEM

невозможно использовать память

MMSYSERR_NOTSUPPORTED

указанное устройство является синхронным и не поддерживает приостановку

3.2 Реализация программного обеспечения для записи, воспроизведения и анализа звукового сигнала

Для реализации программного обеспечения для записи. воспроизведения и анализа звукового сигнала были созданы следующие окна: главное окно программы, окно добавления слова в словарь, окно записи и обработки звука и окна, обеспечивающие просмотр рассчитанных характеристик в виде графиков.

В главном окне обеспечивается просмотр и редактирование существующих словарей, а также их сохранение. Это окно содержит главное меню, панель управления и рабочую область приложения. Главное меню состоит из следующих пунктов: File, Edit, View, Help. Нажатие на пункт File позволяет создать новый файл, открыть существующий файл с расширением *.spl, открыть недавно использованный файл, сохранить новый файл и сохранить существующий файл под другим именем, выйти из программы. При нажатии на пункт Edit можно выбрать одно из предлагаемых действий: добавить слово, удалить слово, воспроизводить звук выделенного слова в рабочей области приложения. Пункт View отвечает за вид главного окна: наличие или отсутствие панели управления и строки состояния.

В панели управления присутствуют следующие кнопки: создание нового файла, открытие существующего файла, сохранение файла, удаление и добавление слова, воспроизведение слова,

Для воспроизведения выбранного слова требуется лишь нажать на соответствующую кнопку в панели управления либо выбрать Edit->Play Sound.

Для записи нового слова требуется нажать на соответствующую кнопку в панели управления либо выбрать Edit->Add Word. При этом появляется новое окно, основанное на диалоговой форме, в котором есть поле для ввода буквенного обозначения нового слова. После ввода слова в поле Word, необходимо нажать кнопку Record. После этого появляется новое окно, также основанное на диалоговом окне. Это окно обеспечивает запись и анализ нового слова. Для записи нового слова, прежде всего, необходимо выбрать в поле Source присутствующую в данном компьютере звуковую карту. Далее в поле Format необходимо выбрать формат записываемых данных. Предлагаются форматы данных, приведенные в табл. 3.9.

Выбор формата записываемых данных необходимо осуществлять исходя из следуюпщх предпосылок: с одной стороны, чем выше частота дискретизации (количество элементов в секунду), чем выше количество каналов и чем выше количество бит в элементе, тем выше качество записи, а потом и воспроизведения звука; с другой стороны, чем выше эти параметры, тем сложнее проводить анализ звука, тем дольше обрабатываются данные. Поэтому для решения поставленной задачи выбирается частота дискретизации 11025 Гц, выбирается моно-режим, т.е. количество каналов=1, и количество бит в элементе=8.

После этого всё уже готово для записи. Для непосредственного осуществления записи звукового аналога слова необходимо нажать на кнопку Record.

Таблица 3.9 - Форматы данных

Название

Количество

Частота

Количество

каналов

дискретизации

бит

WAVE_FORMAT_1M08

1

11025

8

WAVE_FORMAT_1M16

1

11025

16

WAVE_FORMAT_J S08

2

11025

8

WAVE_FORMAT_lS16

2

11025

16

WAVE_FORMAT_2M08

1

22050

8

WAVE_FORMAT_2M16

1

22050

16

WAVE_FORMAT_2S08

2

22050

8

W AVE_FORMAT_2 S16

2

22050

16

WAVE_FORMAT_4M08

1

44100

8

WA VE_FORMAT_4Ml 6

1

44100

16

WAVE_FORMAT_4S08

2

44100

8

WAVE_FORMAT_4S16

2

44100

16

После нажатия на кнопку Record, в программе устанавливается режим работы программы - запись. При этом вызываются функции, которые

останавливают воспроизведение, если оно было включено. Кнопка Record становится неактивной, а кнопка Stop - активной. Далее определяются параметры выбранной звуковой карты и формат записываемого звука, Очищаются буферы, в которые будет производиться запись.

Ниже приведена функция, обеспечивающая запись звуковой информации.

BOOL CWaveIriDevice::Record(CWave* pWave, int iBlockSize) {if (IsOpenQ) {if (! CanDoFormat(pWave->GetFormat())) {TRACE("Imput device is already open and doesn't support format"); return FALSE;}

} else {if (!Open(WAVE_MAPPER, pWave->GetFormat())) { TRACE("No input device supports format"); return FALSE;}} miBlockSize = iBlockSize;

WAVEHDR* phdr = (WAVEHDR*)malloc(sizeof(WAVEHDR)); ASSERT(phdr);

memset(phdr, 0, sizeof(WAVEHDR));

phdr->lpData = (char*)malloc(iBlockSize);

ASSERT(phdr->lpData);

phdr->dwBufferLength = iBlockSize;

phdr->dwUser = (D WORD)(void*)p Wave;

MMRESULT mmr = waveInPrepareHeader(m_hInDev, phdr,

sizeof(WAVEHDR)); if (mmr) (MMERR(mmr); return FALSE;}

mmr = waveInAdabuffer(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) {MMERR(rnmr);

return FALSE;} (3.1)

phdr = (WAVEHDR*)malloc(sizeof(WAVEHDR));

ASSERT(phdr);

memset(phdr, 0, sizeof(WAVEHDR)); phdr->lpData = (char*)malloc(iBlockSize); ASSERT(phdr->lpData); phdr->dwBufferLength = iBlockSize; phdr->dwUser = (DWORD)(void*)pWave;

mmr = waveInPrepareHeader(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) {MMERR(mmr); return FALSE;}

mmr = waveInAddBufTer(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) (MMERR(mmr); return FALSE;}

mmr = wavelnS tart(m_h InDe v); if (mmr) {MMERR(mmr); return FALSE;} return TRUE;}

Прежде всего, проверяется, открыто ли устройство. Если открыто, то проверяется, поддерживает ли оно выбранный формат. Если не поддерживает, то выводится сообщение, что устройство уже открыто, но такой формат оно не поддерживает. Если устройство закрыто, то предпринимается попытка открыть какое-либо устройство, поддерживающее данный формат. Если не удалось открыть устройство, поддерживающее данный формат, то выводится сообщение, что никакое устройство не поддерживает данный формат. Устанавливаем два буфера и отправляем их в драйвер устройства. Устанавливаем заголовок. Опустошаем заголовок. Подготавливаем заголовок. Начинаем запись

До тех пор, пока не будет нажата кнопка Stop, будет производиться запись. После этого при нажатии на кнопку Play можно прослушать весь записанный сигнал. При наличии претензий к записанному сигналу, его

можно переписать, повторно нажав на кнопку Record. Все ранее записанные данные при этом теряются

Для обработки полученных данных необходимо нажать на кнопку OpenData, которая вызывает функцию обработки данных. После нажатия на кнопку OpenData, в программе устанавливается режим работы программы -обработка данных, находящихся в буфере.

Ни же приведена функция, обеспечивающая обработку данных, находящихся в буфере.

BOOL CWaveOutDevice::OpenData(CWave *pWave,CClientDC *curDC) (int count=0;

CWaveBlockList* pBL = pWave->GetBlockList(); if(!pBL) return FALSE; POSITION pos = pBL->GetHeadPositionO; if(!pos) return FALSE;

if (pWave->m_bAutoDestruct) pWave->AddRef(); while (pos)

{CWaveBlock* pBlock = pBL->GetNext(pos); ASSERT(pBlock);

WAVEHDR* phdr = (WAVEHDR*)malloc(sizeof(WAVEHDR)); ASSERT(phdr);

memset(phdr, 0, sizeof(WAVEHDR)); phdr->lpData = (char*) pBlock->GetSamples(); phdr->dwBufferLength = pBlock->GetSize(); phdr->dwUser = (DWORD)(void*)pWave; CString ss("");

ss.Format(_T("%s"),pBlock->m_pSamples); int iw = ss.GetLengthO;

intnum=0; (3.2)

for(long h=0;h<4096;h++)

{num=count*4096+h; bunker[num]=(int)ss. GetAt(O); CString s("");

s.Format(_T("%f "),bunker[num]);

ss.Delete(0,l);}

count-H-;

len=4096*count;}

Noise(bunker,len,0);

Filter(bun,l);

Hamming(fнl,l);

Furje(ham,l);

СИр(пЦ);

AfxMessageBox("Data are..."); return TRUE;}

Прежде всего, обнуляем номер буфера. Далее берём список блоков данных из функции GetBlockList(). Если это невозможно, выходим из функции. Определяем позицию первого элемента в блоке данных. При невозможности выполнения действия, выходим из функции. Наращиваем счётчик ref, если мы его используем. До тех пор, пока существует pos, выполняем следующий цикл. Определяем позицию следующего элемента. Устанавливаем заголовок. Очищаем заголовок. Передаём в параметр IpData значения элементов. Определяем длину буфера. Объявляем строку. В эту строку записываем данные о звуке из pBlock. Определяем длину строки. Объявляем и обнуляем счётчик для массива, в который будем записывать данные о звуке. Т.к. буфер ограничен числом 4096, в цикле от 0 до 4096 записываем данные из строки в массив. Номер элемента массива определяется как номер буфера умноженный на его длину плюс номер элемента в буфере. Непосредственно сама запись из строки в массив. Переопределяем тип данных массива. Увеличиваем номер массива.

Рассчитываем длину массива. Вызываем функцию избавления от шумов. Вызываем функцию обработки с помощью фильтра. Вызываем функцию обработки в окне Хэмминга. Вызываем функцию выполнения преобразования Фурье. Вызываем функцию проведения клиппирования. Выводим на экран сообщение, что данные успешно обработаны. Выходим из функции.

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

Для просмотра графиков, представляющих результаты обработки данных, в этом окне расположены кнопки, при нажатии на каждую из которых появляется окно, в котором есть кнопка, нажав на которую, получаем график интересующей нас зависимости.

3.3 Реализация функции распознавания голосовых команд голосового управления промышленным роботом

Для реализации функции распознавания голосовых команд голосового управления промышленным роботом была создана функция OpenData. После того, как данные о записанной информации занесены в массив, функция вызывает функции, отвечающие за преобразование этого массива. Прежде всего, вызывается функция Noise, которая на основании разделения вокализованного звука и невокализованного переписывает массив с данными о звуке в новый массив, содержащий лишь участки вокализованного звука.

После этого проводится обработка в окне Хэмминга. График полученный в результате этого преобразования приведен на рис 3.3.

Рисунок 3.3 - График функции, после обработки в окне Хэмминга

Далее выполняется преобразование Фурье для коэффициентов, взвешенных окном Хэмминга После этого производится фильтрация. Затем проводится обратное преобразование Фурье. Далее следует операция клигширования, на основании графика которой делается вывод о том, какое слово было произнесено. На рис. 3.4 приведены графики сигнала для слова «вперёд».

Рисунок 3.5 - Графики сигнала для слова «назад» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в -график сигнала после клиппирования)

На рис. 3.6 приведены графики сигнала для слова «стоп».

Рисунок 3.6 - Графики сигнала для слова «стоп» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в -график сигнала после клиппирования)

На рис. 3.11 приведены графики сигнала для слова «пять».

Рисунок 3.11 - Графики сигнала для слова «пять» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в - график сигнала после клиппирования)

Недостатком предложенного метода распознавания слова является необучаемость программы, отнесение всех произнесенных слов к какому-то из заложенных в программе, а также невозможность настройки в конкретном помещении без специалиста. К достоинствам программы можно отнести независимость программы от диктора, кроме случаев дефекта дикции.

3.4 Реализация голосового управления трёхмерными моделями промышленного робота

Библиотека OpenGL представляет собой интерфейс программирования трехмерной графики - это её основное предназначение. Библиотека представляет собой программный интерфейс для аппаратного обеспечения машинной графики. Этот интерфейс состоит приблизительно из 250 отдельных команд (почти 200 команд в ядре OpenGL и еще 50 команд в библиотеке утилит OpenGL), которые используются для того, чтобы определить объекты и операции, необходимые для создания интерактивных трехмерных прикладных программ.

Единицей информации является вершина, из них состоят более сложные объекты. При создании заданной модели необходимо создать вершины, указать, как их соединять (линиями или многоугольниками), установить координаты и параметры камеры и ламп, а библиотека OpenGL создает изображения на экране [16].

Исходя из вышеуказанных причин было принято решение реализовать моделирование функционирования промышленного робота с помощью средств библиотеки OpenGL.

Для создания требуемой модели робота используются различные трехмерные объекты. Каждая трехмерная модель имеет две разновидности: каркас (wireframe) без поверхностных нормалей и объемная модель (solid) с закраской и поверхностными нормалями. При создании программного обеспечения использовались каркасные модели.

Преобразование вида и моделирование сложно связаны в OpenGL и в действительности объединены в одну матрицу видового преобразования (modelview matrix). Существуют три подпрограммы OpenGL для преобразований модели: glTranslate(), glRotate(), glScale(). Эти подпрограммы выполняют преобразование объекта (или системы координат) с помощью его параллельного переноса (moving), поворота (rotating), растягивания (stretching), сжатия (shrinking) или зеркального отражения (reflecting). Все три команды эквивалентны созданию соответствующей матрицы параллельного переноса (translation), поворота (rotation) или

масштабирования {scaling), а затем вызову команды glMultMatrixQ с этой матрицей в качестве аргумента. Однако использование этих трех подпрограмм должно быть быстрее использования команды glMultMatrixQ. OpenGL автоматически вычисляет эти матрицы для пользователя [17].

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

Ниже приведена функция, обеспечивающая моделирование функционирования промышленного робота.

void CMain::OnOpenGLFirst()

{glPushMatrixQ;

glTranslatef(k*per,-3.0,0.0);

glRotatef(360.0* vspos/100,0,1,0);

glRotatef(l 80,0,0,1);

glLineWidth(2.0);

glPushMatrix();

glRotatef(90.0,1.0,0.0,0.0);

glColor3f(0.0,0.0,1.0);

auxWireCone(1.5,1.0);

glPopMatrix();

glTranslatef(0.0,-l.0,0.0);

glColor3f(0.0,0.5,0.5);

auxWireCylinder(0.6,4.0);

glPushMatrix();

glTranslatef(0.0,-3.0,0.0);

glRotatef(90.0,1.0,0.0,0.0);

glColor3f(l.0,0.0,0.0);

auxWireCylinder(0.6,2.0);

glRotatef(180.0*hspos/100,0.0,1.0,0.0);

glTranslatef(l.0,0.5,0.0); (3.3)

Прежде всего, перемещаем сцену. Далее задаём вращение вокруг оси ъ. Задаём переменную, которая будет обеспечивать перемещение робота согласно голосовым командам. Запоминаем положение основы робота. Строим его основу - конус, поднимаемся к его вершине. Строим колонну робота и перемещаемся к её вершине, поворачиваемся на 90 градусов относительно оси х. Строим цилиндр - крепление плеча. Задаём движение

плеча горизонтальной прокруткой. Перемещаемся в конец крепления плеча и создаём плечо -- строим призму. Перемещаемся к её концу, поворачиваемся на 90 градусов и создаём цилиндр - локоть. Далее после перемещения к концу этого цилиндра строим призму - основание схвата, поворачиваемся на 90 градусов и строим первый и второй пальцы.

Результат моделирования робота приведен на рис. 3.1

Рисунок 3.1 Результат моделирования функционирования промышленного робота

Выводы

Организация управления промышленными роботами (ПР) продолжает оставаться актуальной задачей робототехники. Управление роботами реализуется различными способами. К ним относятся: управление при помощи пультов ручного управления, командное управление от управляющих компьютеров, дистанционное управление при помощи внешних вычислительных систем. С точки зрения повышения эффективности обучения ПР одним из наиболее перспективных способов является голосовое управление.

Во время написания магистерской аттестационной работы были проанализированы методы цифровой обработки звуковых сигналов и их использование в системах распознавания речи, выполнен анализ цифровой фильтрации и особенностей акустической фонетики и её учёт при обработке цифровых сигналов.

В работе рассмотрены гомоморфная обработка речи, кодирование речи на основе линейного предсказания и цифровая её обработка в системах речевого общения человека с машиной, особенности различных систем распознавания речи.

Первоначальной задачей являлось создание интерфейса записи и воспроизведения звукового сигнала. Это было выполнено с использованием встроенной библиотеки mmsystem операционной системы Windows. Далее были добавлены функции, обеспечивающие обработку записанного сигнала: выделение вокализованных участков речи, взвешивание коэффициентов дискретного сигнала с помощью окна Хэмминга, преобразование Фурье, фильтрация, обратное преобразование Фурье, а также клиппирование и вычисление кепстра.

На основании проведенного анализа сигнала создана функция распознавания слова-команды. При помощи графической библиотеки OpenGL была обеспечена визуализация выполнения трёхмерной моделью ПР

распознанной голосовой команды. Применение библиотеки OpenGL позволяет моделировать любой из как уже существующих, так и разрабатываемых видов ПР.

Сложность решаемой задачи обуславливалась тем, что даже один и тот же человек не может два раза произнести одно и то же слово абсолютно одинаково и возникает разница в скорости произнесения слова и амплитуде звукового смгнала. При этом возникает необходимость выделения зависимости фонем (сочетания элементарных звуков), присущих одному слову, а потом описания этих зависимостей в виде, понятном для распознавания. Выделение этих зависимостей - является достаточно сложно реализуемой задачей.

Основным достоинством программы является её независимость от оператора: при условиях достаточно чёткого произношения команды, пол и возраст диктора не имеет влияния на распознавание слова. Её применение целесообразно для адаптации промышленного робота к условиям производственной среды, а также для создания информационного потока управления роботом. Возможными перспективами улучшения программы являются увеличение словаря, добавление возможности обучения и улучшение гибкости цифрового представления звукового сигнала.

Перечень ссылок

Рабинер Л. Р., Шафер Р. В. Цифровая обработка речевых сигналов: Пер. с англ./Под ред. М. В. Назарова и Ю. Н. Прохорова. - М.: Радио и связь, 1981.-496 с.

Рабинер Л. Р., Гоулд Б. Теория и применение цифровой обработки сигналов: Пер. с англ./Под ред. Александрова Ю. Н. - М.: Мир, 1978. -848 с.

А. V. Oppenhehn and R. W. Schafer, Digital Signal Processing,, Prentice-Hall, Inc., Englewood Cliffs, N.J., 1975. - 436 p.

A. Peled and B. Liu, Digital Signal Processing. Theory, Design and Implementation, John Wiley and Sons.New York, 1976. - 675 p.

J. W. Cooley and J. W. Tukey, "An Algorithm for the Machine Computation of Complex Fourier.Series," Math Computation, Vol. 19, 1965. - 452 p.

Бондарев В. H., Трёстер Г., Чернега В. С. Цифровая обработка сигналов: методы и средства. Учеб. Пособие для вузов. 2-е изд. - X.: Конус, 2001. -398 с.

Марпл С. Л. Цифровой спектральный анализ и его приложения. - М.: Мир, 1990.-584 с.

Бендат Дж., Пирсол А. Применения корреляционного и спектрального анализа. -М.: Мир, 1983. -312 с.

Гольденберг Л. М., Матюшкин Б. Д., Поляк М. Н. Цифровая обработка сигналов: Справочник. -М.: Радио и связь, 1985. - 312 с.

Гутников В. С. Фильтрация измерительных сигналов. - Л.: Энергоатомиздат, Ленингр. отд-ние, 1990. - 192 с.

J. Н. McClellan, Т. W. Parks, and L. R. Rabiner, "A Computer Program for Designing Optimum FIR Linear Phase Digital Filters," IEEE Trans. Audio and Electro acoustics, Vol. AU-21, 1973. - 347 p.

Цифровые фильтры в электросвязи и радиотехнике/ А. В. Брунченко, Ю.Г. Бутыльский, Л. М. Гольденберг и др.: под ред. Л. М. Гольденберга.

- M.: радио и связь, 1982. - 224 с.

J. L. Ftanagan, С. H. Coker, L. R. Rabiner, R. W. Schafer, and N. Umeda, "Synthetic Voices for Computers," IEEE Spectrum, Vol. 7, No. 10, October 1970.-536 p.

MFC и Visual С++. Энциклопедия программиста: Пер. с англ./ Юджин Олафсен, Кенн Скрайбнер, К. Дэвид Уайт и др. - СПб.: ООО «ДиаСофтЮП», 2004. - 992с.

Шилдт Герберт. MFC: основы программирования. - К.: Издательская группа BHV, 1997. - 560 с.

Тихомиров Ю.В. OpenGL. Программирование трехмерной графики. -СПб.: БХВ-Петербург, 2002.-304 с.

OpenGL. Официальное руководство программиста: Пер. с англ. / Мейсон By, Джеки Нейдер, Том Девис, Дейв Шрайнер. - СПб: ООО «ДиаСофтЮП», 2002. - 592 с.

Приложение А. Элементы текстов программного кода

// recorddlh: header file class CRecordDlg;

class CRecDlgNotifyObj: public CWaveNotifyObj {public:

CRecDlgNotifyObjO; -CRecDlgNotifyObjO; void Attach(CRecordDlg* pDlg) {m_pDlg = pDlg;}

virtual void NewData(CWave *pWave, CWaveBIock* pBlock);

virtual void EndPlayback(CWave *pWave);

CRecordDlg* m_pDlg;};

class CFilterDlg. public CDialog

{public. CWaveOutDevice* m_pOutDev;

CFilterDlg(CWnd* pParent = NULL);

enum { IDD = IDD_FILTERDLG };

protected:

virtual void DoDataExchange(CDataExchange* pDX); protected:

afxmsg void OnFilter(); DECLAREMESSAGEMAPOJ; class CRecordDlg: public CDialog {public:

CRecordDlg(CWnd* pParent = NULL); ~CRecordDlg();

void NewData(CWave *pWave, CWaveBIock* pBlock);

void EndPlayback(CWave *pWave);

enum { IDD = IDD_RECORDDLG };

CButtonmbtnOpenData;

CComboBox mcbSource;

CComboBox mcbFormat;

CStatic mwndFrame;

CButton mbtnPause;

CButton mbtnPlay;

CButton mbtnRecord;

CButton mbtnOK;

CButton mbtnStop;

CString mstrFormat;

CString m_strSource;

public:

void UDdatdTJClientDC *curDC>:

CFilterDIg* m_pFUter; CWave* m_pWave; private:

enum MODE {IDLE, SAMPLING,PLAYTNG,RECORDING,OPEN };

CVUMeter m_VU;

int mJNumDevs;

WAVEINCAPS* m_pDevCaps;

CWavelnDevice mlnDev;

CWave mSampleWave;

CRecDlgNotifyObj m_NotifyObj;

int mJMode;

void FillDeviceList();

void FillFormatListQ;

void SetMode(MODE m);

void BuildFormat(PCMWAVEFORMAT& fmt, DWORD dwFormat); protected:

virtual void DoDataExchange(CDataExchange* pDX);

virtual BOOL OnlnitDialogO;

afxmsg void OnSelchangeFormat();

afxmsg void OnClickedPlay();

afxjmsg void OnClickedRecordO;

afxmsg void OnClickedStop();

afxmsg void OnSelchangeSource();

virtual void OnCancel();

virtual void OnOK();

afxmsg void OnDrawItem(int nlDCtl, LPDRAW1TEMSTRUCT IpDrawItemStruct); afxmsg void OnMeasureItem(int rJDCtl, LPMEASUREITEMSTRUCT IpMeasureltemStruct); afxmsg void OnClickedOpenData(); afxmsg void OnUpdate();

afxmsg void OnHScroll(UTNT nSBCode, UINT nPos, CScrollBar* pScrollBar);

afx_msg void OnGraphicQ;

afxmsg void OnHamming();

afxmsg void OnFilterQ;

afxmsg void OnFurjeQ;

afx_msg void OnObrfurje();

afxmsg void OnClip();

DECLARE_MESSAGE_MAP()};

class CGraphicDlg: public CDialog

{public:

CWaveOutDevice* mjOutDev; CGraphicDlg(CWnd* pParent = NULL); enum { IDD = IDD GRAPHIC };

protected:

virtual void DoDataExchange(CDataExchange* pDX); protected:

afxmsg void OnGraphicQ; DECLAREMESS AGE_MAP()}; class CHammingDlg: public CDialog {public:

CWaveOutDevice* m_pOutDev; CHammingDlg(CWnd* pParent = NULL); enum {IDD = IDD HAMMING }; protected:

virtual void DoDataExchange(CDataExchange* pDX); protected:

afxmsg void OnHammingO; DECLAREMESSAGEMAPO); class CFurjeDlg. public CDialog {public:

CWaveOutDevice* m_pOutDev; CFurjeDlg(CWnd* pParent = NULL); enum {IDD = IDDFURJE }; protected:

virtual void DoDataExchange(CDataExchange* pDX); protected:

afxmsg void OnFurjeO; DECLAREMESSAGEMAPO}; class CObrFurjeDlg: public CDialog {public:

CWaveOutDevice* m_pOutDev; CObrFurjeDlg(CWnd* pParent = NULL); enum { IDD = IDD OBRFURJE }; protected:

virtual void DoDataExchange(CDataExchange* pDX); protected:

afxmsg void OnObrfurje(); DECLAREMESSAGEMAPO}; class CClipDlg. public CDialog {public:

CWaveOutDevice* m_pOutDev; CClipDlg(CWnd* pParent = NULL); enum { IDD = EDDCLIP }; protected:

virtual void DoDataExchange(CDataExchange* pDX);

ON_BN_CLICKED(IDC_GRAPHIC, OnGraphic) ON_BN_CLICKED(IDC_HAMMrNG, OnHamming) ON_BN_CLICKED(IDC_FILTER OnFilter) ON_BN_CLICKED(IDC_FURJE, OnFurje) ON_BN_CLICKED(IDC_OBRFURJE, OnObrfurje) ON_BN_CLICKED(IDC_CLIP, OnClip) END_MESSAGE_MAP() BOOL CRecordDlg::OnInitDialog() {CDialog::OnInitDialog(); ASSERT(mjpWave = NULL); CRect rcVU;

m_wndFrame.GetWindowRect(&rcVU); ScreenToClient(&rcVU);

m_VU.Create(nVU",WS_CHILD | WS_VISIBLE,rcVU,this,l);

m_VU.SetValue(0> 0);

FillDeviceListQ;

FillFormatListO;

SetMode(SAMPLLNG);

return TRUE; }

void CRecordDlg::OnSelchangeFormatO

{OnClickedStopO;}

void CRecordDlg::OnClickedPIayO

{SetMode(PLAYING);

CClientDCdc(this);}

void CRecordDlg. OnClickedRecordO

{ SetMode(RECORDLNG);}

void CRecordDlg. OnClickedStopO

{SetMode(S AMPLING);}

void CRecordDlg::OnSelchangeSource()

{OnClickedStopO;

FillFormatListO;}

void CRecordDlg::OnCancelO

{ OnClickedStopO;

SetMode(IDLE);

mVU.DestroyWindowO;

if (m_pWave) {delete m_pWave;

m_pWave = NULL;}

CDialog::OnCancel();}

void CRecordDlg. OnOKO

{ OnClickedStopO;

SetMode(IDLE);

mVU.DestroyWindowO;

CDialog::OnOK();}

void CRecordDlg::FillDeviceList()

{miNumDevs = wavelnGetNumDevsO;

if (miNumDevs == 0) {

AfxMessageBox("There are no suitable input devices");

EndDialog(IDCANCEL);

return;}

if (m_pDevCaps) delete m_pDevCaps;

m_pDevCaps = new WAVEINCAPSfmiNumDevs];

m_cbSource.ResetContent();

for (int i=0; KmiNumDevs; i++) {

waveInGetDevCaps(i,&m_pDevCaps[i],sizeof(WAVEINCAPS)); m_pDevCaps[i].wMid = i;

m_cbSource.AddString((LPCSTR)&m_pDevCaps[i]);}

mcbSource. SetCurSel(0);}

void CRecordDlg.:FillFormatList()

{ mcbFormat.ResetContentO;

int iSel = m_cbSource.GetCurSel();

if(iSel = CBERR) return;

WAVEINCAPS* pCaps = (WAVEINCAPS*) m_cbSource.GetItemData(iSel);

ASSERT(pCaps);

DWORD dwMask = 0x00000001;

for(inti=0; i<12; i++) {

if (pCaps->dwFormats & dwMask) {

m_cbFormat.AddString((LPCSTR)dwMask);}

dwMask = dwMask « 1; }

mcbFormat. SetCurSel(O);}

void CRecordDlg.OnDrawItem(int nlDCtl, LPDRAWITEMSTRUCT pDI) {char* pszText = NULL; switch (nlDCtl) { case IDC_SOURCE: {

WAVEINCAPS* pCaps = (WAVEINCAPS*)(pDI->itemData); pszText = pCaps->szPname; } break;

case IDC FORMAT: { switch(pDI->itemData) { case WAVE_FORMAT_1M08: pszText = "11.025 kHz, 8 bit, mono"; break;

case WAVE_FORMAT_1S08: pszText = "11.025 kHz, 8 bit, stereo"; break;

case WAVE_FORMAT_lM16: pszText = "11.025 kHz, 16 bit, mono"; break;

case WAVE_F0RMAT_1S16. pszText = "22.05 kHz, 16 bit, stereo"; break;

case WAVE_FORMAT_2M08: pszText = "22.05 kHz, 8 bit, mono"; break;

case WAVE_FORMAT_2S08: pszText = "22.05 kHz, 8 bit, stereo"; break;

case WAVE_FORMAT_2M16: pszText = "22.05 kHz, 16 bit, mono"; break;

case WAVEJFORMATJ2S16. pszText = "22.05 kHz, 16 bit, stereo"; break;

case WAVEJ?ORMAT_4M08: pszText = "44.1 kHz, 8 bit, mono"; break;

case WAVE_FORMAT_4S08: pszText = "44.1 kHz, 8 bit, stereo"; break;

case WAVE_FORMAT_4M16: pszText = "44.1 kHz, 16 bit, mono"; break;

case WAVE_FORMAT_4S16:

pszText = "44.1 kHz, 16 bit, stereo";

break; default:

pszText = "Unknown";

break;} } break; default:

break;} if (IpszText) return;

: ^rawTextCpDI^hDC^szText.-L&CpDI^rcItem), DTLEFT | DTVCENTER); if (pDI->itemState & ODSSELECTED) {

::InvertRect(pDI->hDC, &(pDI->rcItem));} if (PDI->itemState & ODS_FOCUS) {

::DrawFocusRect(pDI->hDC, &(pDI->rdtem)); }}

void CRecordDlg::OnMeasureItem(int ruDCtl, LPMEASUREITEMSTRUCT lpMeasureltemStruct) { CClientDC dc (this);

TEXTMETRIC tm;

dc. GetTextMetrics(&tm);

lpMeasureItemStruct->itemHeight = tm.tmHeight;} void CRecordDlg::SetMode(MODE m) { CClientDC dc(this); if (m = miMode) return; if (m_pWave) m_pWave->Stop(); switch (miMode) {case SAMPLING: case RECORDING: mlnDev.ResetO; m_InDev.Close(); break; case PLAYING: break;

case OPEN:

break;}

miMode = IDLE;

switch (m) {case SAMPLING:

f case RECORDING.

{int iSel = m_cbSource.GetCurSel(); if(iSel = CBERR) return;

WAVEINCAPS* pCaps = (WAVEINCAPS*) m_cbSource.GetItemData(iSeI);

ASSERT(pCaps);

UINT uiBD = pCaps->wMid;

iSel = m_cbFormat.GetCurSel();

if(iSel == CBERR) return;

DWORD dwFormat = mcbFormat.GetltemData(iSel);

ASSERT(dwFormat);

PCMWAVEFORMAT fmt;

BuildFormat(fmt, dwFormat);

if (!m_InDev.Open(uiID, &fmt)) return;

if (m = SAMPLING) {

mSampleWave.DeleteAllO;

mSampleWave. Create(&frnt);

m_SampleWave.Record(&m_InDev, 1024,&m_NotifyObj); } else if (m -- RECORDING) { if (!m_pWave) m_pWave = new CWave; ASSERT(m_pWave); mjpWave->Create(&fmt);

m_pWave->Record(&mJnDev,4096,&m_NotifyObj);}

case PLAYING, if (m_pWave) m_pWave->Play(NULL, &m_NotifyObj); break;

case OPEN.

if (m_pWave) m_pWave->OpenData(NULL, &m_NotifyObj,&dc); break;} miMode = m,

if ((mjMode = PLAYING) || (mjMode = RECORDING)! |(m_iMode btnStop.EnableWindow(TRUE);

} else {m_btnStop.EnableWindow(FALSE);}

if (mjMode = PLAYING) { m_btnPlay.EnableWindow(FALSE); } else {mbtnPlay.EnableWindow(TRUE);}

if (m_iMode = OPEN) {mbtnOpenData.EnableWindow(FALSE); } else {mbtnOpenData.EnableWindow(TRUE);} if (mjMode = RECORDING) {m_btnRecord.EnableWindow(FALSE); } else {m_btnRecord.EnableWindow(TRUE);}} void CRecordDlg::NewData(CWave *pWave, CWaveBlock* pBlock) { ASSERT(pWave); ASSERT(pBlock);

PCMWAVEFORMAT* pwf = (PCMWAVEFORMAT*) pWave->GetFormat(); ASSERT(pwf->wf.wFormatTag = WAVEFORMATPCM); int iCount = pBlock->GefNumSamples(); if (pwf->wBitsPerSample = 8) {

BYTE* pData = (BYTE*)pBlock->GetSamplesO; BYTE bMax - 0; while (iCount--) {

if (*pData > bMax) bMax = *pData; pData++;}

if (bMax < 128) { bMax = 0;} else {bMax -= 128;} m_VU.SetValue(bMax « 8, bMax « 8); } else {ASSERT(sizeof(short int) = 2); short int* pData = (short int*) pBlock->GetSamples(); int iMax = 0;

while (iCount--) {if (*pData > iMax) iMax = *pData;

pData++;} m_VU.SetValue(iMax, iMax);} if(m_iMode!= RECORDING) { pWave->GetBlockList()->FreeAll();}} void CRecordDlg::EndPlayback(CWave *pWave) { ASSERT(pWave); SetMode(SAMPLjrNG);}

void CRecordDlg::BuildFormat(PCMWAVEFORMAT& fmt, DWORD dwFormat) { ASSERT(dwFormat); fmt.wf.wFormatTag = WAVEFORMATPCM; switch (dwFormat) { case WAVE_FORMAT_1M08: fmt.wf.nChannels = 1; rmtwf.nSamplesPerSec = 11025; fmtwBitsPerSample = 8; break;

case WAVE_F0RMAT_1M16: fmt.wf.nChannels = 1; fmt.wf.nSamplesPerSec = 11025; fmt.wBitsPerSample = 16; break;

case WAVE_FORMAT_1S08: fmt.wf.nChannels = 2; fmt.wf.nSamplesPerSec = 11025; fmt.wBitsPerSample = 8; break;

case WAVE_F0RMAT_1S16: fmt.wf.nChannels = 2; fmtwf.nSamplesPerSec = 11025; fmt.wBitsPerSample = 16; break;

case WAVE_FORMAT_2M08: fmt.wf.nChannels = 1; fmt.wf.nSamplesPerSec = 22050; fmt.wBitsPerSample = 8; break;

case WAVE FORMAT 2M16 fmt.wf.nChannels = 1; fmt.wf.nSamplesPerSec = 22050; fmt.wBitsPerSample = 16; break;

case WAVE_FORMAT_2S08: fmt.wf.nChannels = 2; fmt.wf.nSamplesPerSec = 22050; fmt.wBitsPerSample = 8; break;

case WAVE_FORMAT_2S16: fmt.wfnChannels = 2; fmt.wf.nSamplesPerSec = 22050;

fmt.wBitsPerSatnple = 16; break;

case WAVE_FORMAT_4M08: fmt.wf.nChannels = 1; fmt.wf. nSamplesPerSec = 44100; fmt.wBitsPerSampIe = 8; break;

case WAVE_FORMAT_4M16: fmt.wf.nChannels = 1; fmt.wf.nSamplesPerSec = 44100; fmt.wBitsPerSampIe = 16; break;

case WAVE_FORMAT_4S08. fmt.wf.nChannels = 2; fmt.wf.nSamplesPerSec = 44100; fmt.wBitsPerSampIe = 8; break;

case WAVE_FORMAT_4S 16:

fmt.wf.nChannels = 2;

fmt.wf.nSamplesPerSec = 44100;

fmtwBitsPerSample = 16;

break; default:

ASSERT(O);

return;}

fmt.wf.nAvgBytesPerSec = fmt.wf.nSamplesPerSec;

fmt.wf.nBlockAlign = fmt.wBitsPerSampIe /8;} CRecDlgNotifyObj::CRecDlgNotifyObj() { m_pDlg = NULL;} CRecDlgNotifyObj.:~CRecDlgNotifyObj() {}

void CRecDlgNotifyObj::NewData(CWave *pWave,CWaveBlock* pBlock) { ASSERT(m_pDlg);

m_pDlg->NewData(pWave, pBlock);} void CRecDlgNotifyObj::EndPlayback(CWave *pWave) { ASSERT(m_pDlg);

m_pDlg->EndPlayback(pWave);}

void CRecordDlg.:OnClickedOpenData0

{ SetMode(OPEN);

CClientDC dc(this);} CFilterDlg::CFilterDlg(CWnd* pParent /*=NULL*/): CDialog(CFilterDlg::IDD, pParent)

void CFilterDlg::DoDataExchange(CDataExchange* pDX)

{ CDialog::DoDataExchange(pDX);}

BEGIN_MESSAGE_MAP(CFilterDlg, CDialog)

ONJBN_CLICKED(IDC_FILTER, OnFilter) ENDMES S AGEM AP() void CFiIterDlg::OnFilterO (CCIientDC dc(this);

dc.SelectObject(GetStockObject(WHITE_PEN));

for(inti=0; i<110;i++)

{ dc.MoveTo(lO*i,0);

dc.LineTo(10*i,800);

dc.MoveTo(0,10*i);

dc.LineTo(1100,10*i);} dc.SelectObject(GetStockObject(BLACK_PEN)); dc.MoveTo(0,200); dc.LineTo(l 100,200); m_pOutDev->ShowFilter(&dc);}

void CRecordDlg::OnUpdate{) { CCIientDC dc(this); Update(&dc);}

void CRecordDlg::Update(CClientDC *curDC) (CWnd *win= curDC->GetWindowO; win->Invalidate(TRUE);}

int hspos=0; int curpos=0;

void CRecordDlg::OnHScroll(UTNT nSBCode, UINT nPos, CScrollBar* pScrollBar) { curpos=hspos;

switch (nSBCode) { case SBJLEFT:.

if(hspos>0)

hspos--;

break;

case SBRIGHT: hspos++;

break;

case SBLINELEFT: if(hspos>0) hspos--;

case SBLINEPJGHT: hspos++;

break;

case SBTHUMBPOSITION: hspos = nPos;

break;

case SBTFTUMBTRACK: hspos = nPos; break;

case SBPAGELEFT: if(hspos>0) hspos--;

break;

case SBPAGERIGHT.

hspos++;

break;}

CREATESTRUCT cs;

cs.cx =::GetSystemMetrics(SM_CXSCREEN);

SetScrollPos(SB_HORZ,hspos,TRUE);


Подобные документы

  • Структурные схемы гомоморфной обработки и анализа речевых сигналов. Комплексный кепстр речи. Компонент речевого сигнала. Период основного тона и частоты формант. Модуль передаточной функции речевого тракта. Оценивание основного тона на основе кепстра.

    реферат [297,1 K], добавлен 19.11.2008

  • Задачи при передаче речи и данных. Цифровая передача речи. Категории методов цифрового кодирования речи. Кодеры формы сигнала. Вид амплитудной характеристики компрессора. Дискретная модель речеобразования. Особенности метода кратковременного анализа.

    контрольная работа [56,6 K], добавлен 18.12.2010

  • Состояние проблемы автоматического распознавания речи. Обзор устройств чтения аудио сигналов. Архитектура системы управления периферийными устройствами. Схема управления электрическими устройствами. Принципиальная схема включения электрических устройств.

    дипломная работа [1,1 M], добавлен 18.10.2011

  • Характеристика и область применения сигналов в системах цифровой обработки. Специализированный процессор цифровой обработки сигналов СПФ СМ: разработчики и история, структура и характеристики, область применения, алгоритмы и программное обеспечение.

    курсовая работа [224,9 K], добавлен 06.12.2010

  • Цифровая обработка сигналов. Классификация вокодеров по способу анализа и синтеза речи. Структура БИХ-фильтра. Разработка функциональной схемы вокодера. Расчет параметров и характеристик набора цифровых полосовых фильтров. Алгоритм работы вокодера.

    курсовая работа [1,0 M], добавлен 07.11.2012

  • Ансамбли различаемых сигналов - группы M однородных сигналов. Условие различимости сигналов - их взаимная ортогональность. Правило задачи распознавания-различения по аналогии с задачей обнаружения. Задачи обнаружения по критерию минимума среднего риска.

    реферат [1,0 M], добавлен 28.01.2009

  • Преимущества радиоканальных охранных систем. Основные направления кодирования речи: кодирование формы (Waveform coding) и источника сигнала (Source coding). Структурная схема процесса обработки речи в стандарте GSM. Оценка качества кодирования речи.

    реферат [46,8 K], добавлен 20.10.2011

  • Общее понятие и классификация сигналов. Цифровая обработка сигналов и виды цифровых фильтров. Сравнение аналогового и цифрового фильтров. Передача сигнала по каналу связи. Процесс преобразования аналогового сигнала в цифровой для передачи по каналу.

    контрольная работа [24,6 K], добавлен 19.04.2016

  • Рассмотрение основных этапов в решении задачи оптимизации приема сигнала. Изучение методов фильтрации и оптимизации решений. Вероятностный подход к оценке приёма сигнала; определение вероятности ошибок распознавания. Статические критерии распознавания.

    презентация [3,0 M], добавлен 28.01.2015

  • Структурная схема цифровых систем передачи и оборудования ввода-вывода сигнала. Методы кодирования речи. Характеристика методов аналого-цифрового и цифро-аналогового преобразования. Способы передачи низкоскоростных цифровых сигналов по цифровым каналам.

    презентация [692,5 K], добавлен 18.11.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.