Технологии программирования миди

 Навигация:

 Поиск:

 Новости:

17.02.2007
Полностью переработан дизайн сайта.

6.01.2007
Добавлен раздел Наработки Полезные и интересные программы и их исходники от автора.

19.11.2006
Функции WriteVarLen и ReadVarLen портированы с СИ на Delphi читать

14.11.2006
Появилась cтатья Midi-протокол глазами программиста

24.10.2006
Написана вторая часть MMSystem Функции midiOutGetVolume midiOutSetVolume midiOutMessage midiOutShortMsg и midiOutLongMsg

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

1.09.2006
Добавлен раздел MMSystem в котором находятся
подробные опсания функций winmm.dll, определенных в модуле mmSystem.pas,
с примерами их использования в Delphi.

13.08.2006
Опубликован исходник приложения, записывающего игру на клавиатуре
в стандартный midi-файл SMF - 0

4.07.2006
Добавлен раздел Структура формата миди-файла

 Счетчики:
Rambler's Top100 Яндекс цитирования Rambler's Top100
 Контент:

Воспроизведение звука

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

UINT
waveOutOpen(LPHWAVEOUT lphWaveOut,

UINT wDeviceID,

LPWAVEFORMAT lpFormat,

DWORD dwCallbackInstance,

DWORD dwFlags);

Здесь lphWaveOut -дальний указатель на переменную типа HWAVEOUT. В эту переменную будет записан идентификатор устройства вывода, который необходим для выполнения всех операций с устройством. Функция waveOutOpen также может быть использована для определения возможности воспроизведения звуковых данных заданного формата (в том числе нестандартного), в этом случае параметр lphWaveOut может иметь значение NULL, дополнительно в параметре dwFlags следует установить флаг WAVE_FORMAT_QUERY.

Через параметр wDeviceID приложение должно передать функции waveOutOpen номер устройства вывода, которое оно собирается открыть или константу WAVE_MAPPER, определенную в файле mmsystem.h. В первом случае номер устройства может лежать в пределах от нуля до по-лученного с помощью функции waveOutGetNumDevs значения. Обычно используется константа WAVE_MAPPER, при этом функция waveOut-Open пытается самостоятельно выбрать и открыть устройство вывода, подходящее для проигрывания звуковых данных указанного формата.

Через параметр lpFormat приложение должно передать функции waveOutOpen адрес заполненной структуры WAVEFORMAT (эта струк-тура и указатели на нее описаны выше).

Параметр dwCallback передает функции waveOutOpen адрес функ-ции обратного вызова. Эту функцию будет вызывать драйвер устройства вывода при возникновении событий, имеющих отношение к проигрыва-нию блока данных. При использовании функции обратного вызова в пара-метре dwFlags следует установить флаг CALLBACK_FUNCTION.

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

Параметр dwCallbackInstance является идентификатором данных, пе-редаваемым функции обратного вызова (этот параметр не используется совместно с флагом CALLBACK_WINDOW).

В поле dwFlags можно указывать следующие флаги

Идентификатор флага Описание

WAVE_FORMAT_QUERY Функция waveOutOpen вызывается только с це-лью проверки возможности использования фор-мата звуковых данных, определенных в структу-ре WAVEFPRMAT, адрес которой передается через параметр lpFormat. Этим способом можно проверить, способно ли данное устройство рабо-тать с нестандартной частотой дискретизации

WAVE_ALLOWSYNC Флаг необходимо использовать для открытия синхронного устройства вывода, во время рабо-ты которого все приложения блокируются

CALLBACK_WINDOW Для извещения о наступлении событий исполь-зуется окно, идентификатор которого передается через параметр dwCallback

CALLBACK_FUNCTION Для извещения о наступлении событий исполь-зуется функция обратного вызова, адрес которой передается через параметр dwCallback

При нормальном завершении функция waveOutOpen возвращает ну-левое значение, в противном случае -описанный в нижележащей таблице код ошибки

Код ошибки Описание ошибки

MMSYSERR_BADDEVICEID Указан неправильный номер устройства вы-вода

MMSYSERR_ALLOCATED Это устройство уже открыто

MMSYSERR_NOMEM Для выполнения операции недостаточно па-мяти

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

WAVEERR_SYNC Была выполнена попытка открыть синхрон-ное устройство вывода без использования флага WAVE_ALLOWSYNC

Обычно при проигрывании WAV-файлов приложение вызывает функ-цию waveOutOpen дважды. Первый раз она вызывается для проверки воз-можности проигрывания звуковых данных заданного формата

if (waveOutOpen(NULL, WAVE_MAPPER,

(WAVEFORMAT FAR *) lpwiocb->lpFmt,

NULL, 0L,

WAVE_FORMAT_QUERY | WAVE_ALLOWSYNC)) {

// сообщение о том, что воспроизведение невозможно }

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

rc=waveOutOpen(&hWaveOut, WAVE_MAPERR,

(WAVEFORMAT FAR *) lpwiocb->lpFmt,

(UINT) hwnd, 0L,

CALLBACK_WINDOW | WAVE_ALLOWSYNC);

Указанная методика позволяет определить возможность работы с нестандартными форматами.

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

Блоки данных, передаваемые драйверу, должны быть заказаны у сис-темы как глобальные с флагами GMEM_MOVEABLE и GMEM_SHARE.

Перед передачей блока драйверу необходимо его подготовить при по-мощи функции waveOutPrepareHeader UINT

waveOutPrepareHeader(HWAVEOUT hWaveOut,

LPWAVEHDR lpWaveOutHdr,

UINT wSize);

Здесь hWaveOut -полученный ранее от функции waveOutOpen иден-тификатор устройства вывода, lpWaveOutHdr -адрес описывающей пере-даваемый блок данных заполненной структуры WAVEHDR; описание данной структуры приведено ниже

typedef struct wavehdr_tag
{
LPSTR lpData; // адрес блока данных

DWORD dwBufferLength; // размер блока данных

DWORD dwBytesRecorded; // количество записанных байт

// (только при записи) DWORD dwUser; //
пользовательские данные DWORD dwFlags;
// флаги состояния буфера данных DWORD dwLoops;
// кратность проигрывания файла
// (только при воспроизведении) struct wavehdr_tag far *lpNext; // зарезервировано DWORD reserved; // зарезервировано (не используется)

} WAVEHDR;

typedef WAVEHDR *PWAVEHDR; typedef WAVEHDR NEAR *NPWAVEHDR; typedef WAVEHDR FAR *LPWAVEHDR;

После заказа блока памяти функцией GlobalAlloc с флагами GMEM_MOVEABLE и GMEM_SHARE необходимо зафиксировать его функцией GlobalLock; полученный в результате фиксирования адрес бло-ка записывается в поле lpData структуры WAVEHDR, а размер блока -в поле dwBufferLength.

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

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

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

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

вернул буфер приложению
WHDR_BEGINLOOP Данный буфер является первым в цикле (флаг используется только при воспроизведении). При желании проиграть в цикле только один блок он должен быть отмечен и флагом
WHDR_BEGINLOOP и флагом WHDR_ENDLOOP
WHDR_PREPARED Буфер подготовлен для воспроизведения функцией
waveOutPrepareHeader или для записи функцией waveInPrepareHeader

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

При нормальном завершении функция waveOutPrepareHeader воз-вращает нуль, в противном случае указанный в таблице код ошибки.

После обработки блока памяти функцией waveOutPrepareHeader его можно проиграть с помощью вызова функции waveOutWrite. UINT

waveOutWrite(HWAVEOUT hWaveOut, // идентификатор устройства

LPWAVEHDR lpWaveOutHdr, // указатель на ст-ру WAVEHDR

UINT wSize); // размер структуры WAVEHDR

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

Код ошибки Описание ошибки
MMSYSERR_INVALHANDLE Указан неправильный идентификатор устройства
MMSYSERR_UNPREPARED Переданный блок функции не был подготовлен функцией waveOutPrepareHeader

Реально проигрывание блока начинается после вызова функции waveOutWrite, в случае проигрывания блока до конца или остановки про-игрывания определенная указанным при открытии устройства через пара-метр dwCallback идентификатором оконная функция получит сообщение MM_WOM_DONE.

После получения приложением сообщения MM_WOM_DONE оно должно передать блок функции waveOutUnprepareHeader, затем разбло-кировать его функцией GlobalUnlock и освободить (если этот блок памяти больше не нужен) функцией GlobalFree.

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

UINT

waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT wSize);

При нормальном завершении функция waveOutUnprepareHeader воз-вращает нуль, в противном случае нижеуказанный код ошибки

Код ошибки Описание ошибки

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

MMSYSERR_STILLPLAYING Указанный блок все еще находится в очереди для проигрывания

После завершения работы с устройством его необходимо закрыть, вы-звав функцию waveOutClose

UINT waveOutClose(HWAVEOUT hWaveOut); // идентификатор устройства

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

Код ошибки Описание ошибки

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

MMSYSERR_STILLPLAYING Очередь данного устройства еще содержит блоки для проигрывания

Содержание
 Bash.org.ru:

 Реклама:

 ©Copyright:
http://www.last.h16.ru - программирование миди. Идея, разработка и поддержка : Mo-skin © 2006-2007
X