Мультимедиа для Windows

         

Break


Команда break позволяет определить код виртуальной клавиши, предназначенной для прерывания (по умолчанию используется комбинация клавиш <Control+Break>):

break device_id parameter [notify] [wait]

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

on virt_key

Для прерывания будет использована клавиша с виртуальным кодом virt_key

off

Действие клавиши прерывания отменяется

Если команда выдана с параметром wait, функция mciSendString вернет управление только после завершения операции. Если пользователь не желает дожидаться завершения длительной операции, он может нажать клавишу, прерывающую выполнение команды.



Capability


С помощью команды capability приложение может определить возможности устройства:

capability device_id parameter [notify] [wait]

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

can play

Если драйвер звукового адаптера может проигрывать wav-файлы, в ответ на эту строку он возвратит строку true, а если нет - то false

can record

Если устройство может записывать, возвращается true, в противном случае - false

can save

Используется для определения возможности сохранения записанного звукового фрагмента в wav-файле. Если такая возможность есть, возвращается строка true, в противном случае - false



compound device

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

device type

Для звукового адаптера возвращается строка waveaudio

has audio

Для звукового адаптера возвращается строка true

inputs

Общее количество устройств ввода

outputs

Общее количество устройств вывода

uses files

Для звукового адаптера возвращается строка true, так как он работает с wav-файлами



Чтение из файла


Для чтения файла, открытого при помощи функции mmioOpen, следует использовать функцию mmioRead . Эта функция позволяет за один вызов прочитать из файла блок данных размером, большим чем 64 Кбайт. После чтения выполняется перемещение текущей позиции вперед на количество прочитанных байт.

Функция mmioRead

LONG mmioRead( HMMIO hmmio, // идентификатор открытого файла HPSTR hpBuff, // указатель на буфер с данными LONG dwBytes); // размер буфера

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

hpBuff

Указатель типа huge на буфер, в который будут прочитаны данные

dwBytes

Размер буфера

Возвращаемое значение:

Возвращается количество прочитанных байт данных или -1 при возникновении ошибки. При достижении конца файла возвращается нулевое значение



Close


Команда close закрывает устройство и освобождает все связанные с ним ресурсы. Формат команды:

close device_id [notify] [wait]

Необходимо указать идентификатор устройства device_id, использованный при открытии устройства командой open.

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

close nsound



Cue


Подготовка для записи или воспроизведения. После выполнения такой подготовки устройство будет готово быстро приступить к выполнению требуемой операции. Эту команду нельзя выдавать во время записи или воспроизведения.

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

input

Подготовка для записи

output

Подготовка для воспроизведения



Delete


Удаление сегмента из фрагмента звуковых данных

delete device_id from position [to position] [notify] [wait]

Для этой команды можно указать либо оба параметра (from и to), либо только параметр from.



Драйвер mciavi.drv


Драйвер mciavi.drv предназначен для проигрывания файлов мультимедиа, содержащих звуковые данные и видео (как с поддержкой цветовых палитр, так и в режиме True Color). Звуковые данные могут быть моно- или стереофоническими с частотой дискретизации 44,1 Кгц, 22,05 Кгц или 11,025 Кгц. С помощью драйвера mciavi.drv можно проигрывать avi-файлы, содержащие звук и видео, только видео или только звук.

При воспроизведении видео со звуком возникает проблема синхронизации. К сожалению, производительность компьютера и особенно его видеоподсистемы не всегда оказывается достаточной для воспроизведения всех кадров, записанных в avi-файле, с нужной скоростью. В случае необходимости драйвер mciavi.drv пропускает некоторые кадры. Из-за инерционности зрения качество изображения во многих случаях остается при этом вполне удовлетворительным. Однако перерывы в воспроизведении звуковых данных или пропуски фрагментов звуковых данных недопустимы. Поэтому в процессе пропуска видеокадров драйвер mciavi.drv обеспечивает предварительную выборку звуковых данных и непрерывность воспроизведения звуковой информации.

В дополнение к командам MCI, рассмотренным нами ранее и предназначенным для управления звуковыми устройствами и устройствами чтения компакт-дисков, драйвер mciavi.drv позволяет использовать команды, имеющие отношение к воспроизведению видео. В частности, с помощью этих команд можно указать параметры окна, в котором будет выполняться просмотр видео. Однако, как мы уже говорили, самый простой способ проигрывания avi-файлов заключается в использовании интерфейса окна MCI вместо классического интерфейса MCI.



Другие функции низкого уровня


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



Другие макрокоманды


Перечислим некоторые другие полезные макрокоманды, имеющие отношение к окну MCI.

Макрокоманды MCIWndCanConfig , MCIWndCanEject , MCIWndCanPlay , MCIWndCanRecord , MCIWndCanSave , MCIWndCanWindow позволяют определить, соответственно, возможность конфигурирования, автоматической смены носителя, проигрывания, записи, сохранения и проигрывания в окне. Все эти макрокоманды имеют один параметр - идентификатор окна MCI. Если та или иная возможность поддерживается, соответствующая макрокоманда возвращает значение TRUE, в противном случае FALSE.

В любой момент времени приложение может изменить стиль окна MCI, вызвав макрокоманду MCIWndChangeStyles . Пример испльзования этой макрокоманды есть в приложении MCIWNDC (см. ниже). Для определения текущего стиля окна MCI можно воспользоваться макрокомандой MCIGetStyles .

Несколько макрокоманд предназначены для определения характеристик файла или такого носителя данных, как звуковой компакт-диск, загруженного в окно MCI. С помощью макрокоманд MCIWndGetLength , MCIWndGetStart , MCIWndGetEnd , MCIWndGetPosition , MCIWndGetPositionString приложение может определить, соотетственно, длину файла, начальную позицию, конечную позицию, текущую позицию и текущую позицию в виде текстовой строки.

Приложение может установить скорость проигрывания, громкость и размеры окна MCI, вызвав, соответственно, макрокоманды MCIWndSetSpeed , MCIWndSetVolume , MCIWndSetZoom . Есть макрокоманды, с помощью которых можно определить текущее значение для скорости проигрывания, громкости и размеров окна MCI - MCIWndGetSpeed , MCIWndGetVolume и MCIWndGetZoom .

Есть макрокоманды для изменения формата времени и определени текущего формата времени (MCIWndSetTimeFormat , MCIWndGetTimeFormat , MCIWndUseFrames , MCIWndUseTime ), для обновления информации о позиции при замене носителя данных (MCIWndValidateMedia ), для работы с таймером, палитрами и некоторые другие.

Если же этого обширного списка все же не хватит, то с помощью макрокоманды MCIWndSendString вы сможете передать окну любую команду MCI, лишь бы ее поддерживало используемое устройство. Ответ драйвера на посланную команду можно получить в виде текстовой строки при помощи макрокоманды MCIWndReturnString .



Другие приложения мультимедиа


Приложение World Atlas (атлас мира) поставляется на дискетах или компакт-диске. Его можно использовать как справочник, содержащий многочисленные сведения о различных странах и городах мира. Справочник содержит высококачественные цветные графические изображения карт и мощные средства поиска информации (рис. 1.17).

Рис. 1.17. Приложение World Atlas

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

С помощью World Atlas вы сможете без труда узнать поясное время в любом городе мира, определить расстояние между любыми двумя городами, узнать другие сведения о стране, необходимые для путешественника. Вы можете отметить нужные вам города на карте. Любая карта или диаграмма может быть скопирована в Clipboard и вставлена затем в документ (рис. 1.18).

Рис. 1.18. Карта Австралии, скопированная из атласа мира

Еще одно интересное приложение, использующее технологию мультимедиа - электронная книга "Guinness Multimedia Disk of Records" (вариант "Книги рекордов Гиннеса"), которая поставляется на компакт-диске (рис. 1.19).

Рис. 1.19. Приложение Guinness Multimedia Disk of Records

В отличие от обычной книги, где вы можете прочитать запись о рекорде и посмотреть соответствующую фотографию, электронный вариант позволяет вам прослушать звуковую запись. Например, мы узнали, что самое длинное слово в русском языке - "рентгеноэлектрокардиографического". Мы услышали произношение этого слова, а также пример предложения, в котором оно используется, и его перевод на английский язык - "Больше нет рентгеноэлектрокардиографического института".
Увы, больше нет...

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



Рис. 1.20. Пиктограммы для просмотра фотографии и прослушивания звуковой записи

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

Audobon's Mammals

Многотомное описание животных Северной Америки с цветными фотографиями и записями звуков.

Cameron's Fine Art Catalog

Работы художников и фотографов со звуковым сопровождением.

Compton's Interactive Encyclopedia

26-томная энциклопедия с фотографиями, звуковыми и видеозаписями.

Macmillian Dictionary for Children

Словарь, предназначенный для обучения детей. Использование средств мультимедиа позволяет значительно улучшить восприятие материала.

Mayo Clinic Family Health Book

Электронный семейный доктор. Фотографии, видеозаписи и звуковые записи иллюстрируют информацию о том, как сохранить свое здоровье.


Формат wav-файла


Данные, имеющие отношение к мультимедиа (звук, видео и т. п.) хранятся в файлах в так называемом RIFF-формате (Resource Interchange File Format - формат файла для обмена ресурсами). Как wav-файлы, содержащие звук, так и avi-файлы, содержащие видеоинформацию, имеют формат RIFF.

Файл в формате RIFF содержит вложенные фрагменты (chunk's ). Внешний фрагмент состоит из заголовка и области данных (рис. 2.3).

Рис. 2.3. Фрагмент "RIFF"

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

Область данных имеет переменную длину, однако она должна быть выравнена на границу слова и при необходимости дополнена в конце нулевым байтом до целого числа слов.

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

Область, обозначенная на рис. 2.3 как "Данные", может содержать внутри себя другие фрагменты. Для файла, в котором хранятся звуковые данные (wav-файл), эта область содержит идентификатор данных "WAVE", фрагмент формата звуковых данных "fmt " (три символа "fmt" и пробел на конце), а также фрагмент звуковых данных (рис. 2.4). Файл может дополнительно содержать фрагменты других типов, поэтому не следует думать, что заголовок wav-файла имеет фиксированный формат. Например, в файле может присутствовать фрагмент "LIST" или "INFO", содержащий информацию о правах копирования и другую дополнительную информацию. Из-за ограниченного объема книги мы не будем рассматривать форматы других фрагментов, при необходимости вы можете узнать их из документации, которая поставляется в составе Microsoft SDK for Windows 3.1.

Рис. 2.4. Формат wav-файла

Область, обозначенная на рис. 2.4 как "Формат данных", описывает звуковые данные.
Формат этой области для файлов PCM (записанных с использованием импульсно-кодовой модуляции) соответствует структуре PCMWAVEFORMAT , определенной в файле mmsystem.h следующим образом:

typedef struct pcmwaveformat_tag { WAVEFORMAT wf; WORD wBitsPerSample; } PCMWAVEFORMAT; typedef PCMWAVEFORMAT *PPCMWAVEFORMAT; typedef PCMWAVEFORMAT NEAR *NPPCMWAVEFORMAT; typedef PCMWAVEFORMAT FAR *LPPCMWAVEFORMAT;

Структура WAVEFORMAT также описана в файле mmsystem.h:

typedef struct waveformat_tag { WORD wFormatTag; // тип формата WORD nChannels; // количество каналов (моно или стерео) DWORD nSamplesPerSec; // частота дискретизации DWORD nAvgBytesPerSec; // скорость потока данных WORD nBlockAlign; // выравнивание блока данных } WAVEFORMAT; typedef WAVEFORMAT *PWAVEFORMAT; typedef WAVEFORMAT NEAR *NPWAVEFORMAT; typedef WAVEFORMAT FAR *LPWAVEFORMAT;

Поле wFormatTag описывает тип формата звуковых данных. Для импульсно-кодовой модуляции PCM, которая поддерживается стандартной библиотекой mmsystem.dll, в этом поле должно находиться значение WAVE_FORMAT_PCM , определенное в файле mmsystem.h:

#define WAVE_FORMAT_PCM 1

Поле nChannels содержит количество каналов. В нем могут находиться значения 1 (моно) или 2 (стерео).

В поле nSamplesPerSec записана частота дискретизации, то есть количество выборок сигнала в секунду. В этом поле могут находиться стандартные значения (11025 Кгц, 22050 Кгц или 44100 Кгц), либо нестандартные значения, такие как 5000 Кгц или 4400 Кгц. Учтите, что не все драйверы звуковых адаптеров могут работать с нестандартными частотами дискретизации.

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


Точное значение вы можете подсчитать по формуле:

nAvgBytesPerSec = (nChannels * nSamplesPerSec * wBitsPerSample) / 8

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

nBlockAlign = (nChannels * wBitsPerSample) / 8

Поле wBitsPerSample находится в структуре PCMWAVEFORMAT и содержит дискретность сигнала, то есть количество бит, используемых для представления одной выборки сигнала. Обычно используются значения 8 или 16.

Что же касается формата самих звуковых данных, то он зависит от количества каналов и от дискретности.

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

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

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

Диапазон изменения значений выборок сигнала определяется дискретизацией. Для 8-битовых данных он составляет от 0 до 255 (0xff), причем отсутствию сигнала (полной тишине) соответствует значение 128 (0x80). Для 16-битовых данных диапазон изменения составляет от -32768 (-0x8000) до 32767 (0x7fff), отсутствию сигнала соответствует значение0.


Функции для работы с файлами


Для чтения или записи wav-файлов вы, конечно, можете использовать стандартные функции или такие функции, как _hread или _hwrite. Однако в библиотеке mmsystem.dll есть более удобные функции, специально предназначенные для работы с файлами в стандарте RIFF. Все эти функции могут работать с блоками памяти большого размера (больше 64 Кбайт), что очень удобно, так как звуковые данные редко помещаются в одном сегменте памяти.



Функции для работы с RIFF-файлами


Ваше приложение может работать с RIFF-файлами с использованием обычных функций ввода/вывода или с помощью функций, описанных выше (что удобнее). Дополнительно в библиотеке mmsystem.dll есть функции, сильно облегчающие работу с фрагментами RIFF-файлов. Эти функции помогут вам заполнить четырехбайтовый идентификатор фрагмента, найти в файле нужный фрагмент и установить на него (или за него) текущую позицию файла, а также создать новый фрагмент в новом файле.

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

Функция mmioFOURCC

FOURCC mmioFOURCC( CHAR ch0, // первая буква кода CHAR ch1, // вторая буква кода CHAR ch2, // третья буква кода CHAR ch3); // четвертая буква кода

Параметры функции:

ch0, ch1, ch2, ch3

Коды букв, из которых будет составлен четырехбуквенный код

Возвращаемое значение:

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

Функция mmioFOURCC реализована как макрокоманда, выполняющая упаковку четырех байт в двойное слово:

#define mmioFOURCC(ch0, ch1, ch2, ch3) \ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))

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

FOURCC fourccWaveID; fourccWaveID = mmioFOURCC('W', 'A', 'V', 'E');

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

Функция mmioStringToFOURCC

FOURCC mmioStringToFOURCC( LPCSTR szString, // преобразуемая строка UINT wFlags); // режим преобразования

Параметры функции:

szString

Указатель на преобразуемую строку, закрытую двоичным нулем

wFlags

Если указан флаг MMIO_TOUPPER , все буквы строки будут преобразованы в заглавные

Возвращаемое значение:


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

Пример использования функции mmioStringToFOURCC:

FOURCC fourccWaveID; fourccWaveID = mmioStringToFOURCC("wave", MMIO_TOUPPER);

Для создания нового фрагмента в RIFF-файле удобно использовать функцию mmioCreateChunk . Новый фрагмент создается в текущей позиции файла, открытого с помощью функции mmioOpen.

Функция mmioCreateChunk

UINT mmioCreateChunk( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO UINT wFlags); // тип фрагмента

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, содержащую информацию о создаваемом фрагменте

wFlags

Если указан флаг MMIO_CREATERIFF , создается фрагмент "RIFF", а если MMIO_CREATELIST - создается фрагмент "LIST"

Возвращаемое значение:

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

Структура MMCKINFO и указатели на нее определены в файле mmsystem.h:

typedef struct _MMCKINFO { FOURCC ckid; DWORD cksize; FOURCC fccType; DWORD dwDataOffset; DWORD dwFlags; } MMCKINFO; typedef MMCKINFO *PMMCKINFO; typedef MMCKINFO NEAR *NPMMCKINFO; typedef MMCKINFO FAR *LPMMCKINFO;

Опишем назначение отдельных полей этой структуры.

Поле Описание
ckid Код, соответствующий четырехбуквенному идентификатору фрагмента
cksize Размер фрагмента в байтах без учета идентификатора фрагмента, поля длины фрагмента и дополнительных байтов выравнивания, которые могут находиться в конце фрагмента
fccType Тип фрагмента
dwDataOffset Смещение области данных относительно начала файла в байтах
dwFlags В этом поле может находиться нулевое значение или флаг MMIO_DIRTY, в последнем случае длина фрагмента может быть изменена, поэтому для ее обновления следует вызвать функцию mmioAscend. Флаг MMIO_DIRTY может быть установлен при создании фрагмента функцией mmioCreateChunk
<


В приведенном ниже фрагменте кода создается новый файл, подготавливается структура MMCKINFO, а затем создается фрагмент "RIFF", для чего вызывается функция mmioCreateChunk:

hFile = mmioOpen(szFileName, NULL, MMIO_CREATE | MMIO_READWRITE); if(hFile != NULL) { ck.ckid = MMIO_CREATERIFF; ck.cksize = waveiocbIn.lpWaveHdr->dwBytesRecorded + sizeof(PCMWAVEFORMAT) + 20; ck.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmioCreateChunk(hFile, (LPMMCKINFO)&ck, MMIO_CREATERIFF); }

Более подробно этот фрагмент кода будет описан позже, когда мы будем рассказывать вам о приложении WAVE, работающим с wav-файлами и звуковым адаптером на низком уровне.

Для поиска нужного фрагмента внутри RIFF-файла у вас нет необходимости выполнять побайтовое чтение файла и анализ его внутренней структуры. Найти нужный фрагмент и выполнить позиционирование относительно этого фрагмента вам помогут функции mmioDescend и mmioAscend.

Функция mmioDescend ищет заданный фрагмент начиная с текущей позиции. Если фрагмент найден, текущая позиция устанавливается на область данных. Напомним, что область данных расположена на 8 байт ближе к концу файла от начала фрагмента (рис. 2.3).

Функция mmioDescend

UINT mmioDescend( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO // для текущего фрагмента LPMMCKINFO lpckParent, // указатель на структуру MMCKINFO // для внешнего фрагмента UINT wFlags); // режим поиска

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, в которую будет записана информация о текущем фрагменте

lpckParent

Указатель на структуру MMCKINFO, описывающую внешний фрагмент, внутри которого выполняется поиск. В качестве внешнего фрагмента могут выступать только фрагменты "RIFF" или "LIST". Этот параметр можно указывать как NULL, если внешний фрагмент отсутствует

wFlags

Если указан флаг MMIO_FINDCHUNK , выполняется поиск фрагмента, заданного своим идентификатором, если MMIO_FINDLIST - выполняется поиск фрагмента внутри фрагмента "LIST", если MMIO_FINDRIFF - внутри фрагмента "RIFF".



Возвращаемое значение:

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

В приведенном ниже фрагменте кода открывается на чтение wav-файл, затем в нем выполняется поиск фрагментов "WAVE" и "fmt ":

hmmio = mmioOpen((LPSTR)lpszFileName, NULL, MMIO_READ | MMIO_ALLOCBUF); if(!hmmio) return WIOERR_FILEERROR;

memset(&ckRIFF, 0, sizeof(MMCKINFO)); ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if(mmioDescend(hmmio, &ckRIFF, NULL, MMIO_FINDRIFF)) { mmioClose(hmmio,0); return WIOERR_BADFORMAT; }

memset(&ckFMT, 0, sizeof(MMCKINFO)); ckFMT.ckid = mmioFOURCC('f', 'm', 't', ' '); if(mmioDescend(hmmio, &ckFMT, &ckRIFF, MMIO_FINDCHUNK)) { mmioClose(hmmio,0); return WIOERR_BADFORMAT; }

Функция mmioAscend предназначена для продвижения текущей позиции к началу следующего фрагмента.

Функция mmioAscend

UINT mmioAscend( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO UINT wFlags); // режим поиска

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, предварительно заполненную функцией mmioDescend или mmioCreatechunk

wFlags

Параметр не используется, необходимо передавать нулевое значение.

Возвращаемое значение:

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


Функции для рисования битовых изображений DIB


Video for Windows добавляет в Windows программный интерфейс, с помощью которого приложения могут рисовать изображения DIB на экране. Имена этих функций начинаются с DrawDib , что, очевидно, говорит об их назначении. Функция DrawDibDraw может все, что может функция StretchDIBits , однако работает быстрее. Дополнительно при отображении вызывается система ICM, выполняющая восстановление сжатых изображений непосредственно перед выводом на экран. Если исходное изображение имеет формат True Color, а устройство вывода обладает средним или низким цветовым разрешением, функции выполняют рисование с использованием смешивания (dithering) цветов.



Функция mciSendCommand


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

Функция mciSendCommand

DWORD mciSendCommand( UINT wDeviceID, // идентификатор устройства UINT wMessage, // код сообщения DWORD dwParam1, // флаги команды DWORD dwParam2); // указатель на структуру параметров

Параметры функции:

wDeviceID

Идентификатор устройства, которому посылается сообщение. Для команды MCI_OPEN не используется, так как идентификатор создается в результате выполнения этой команды

wMessage

Код сообщения. Соответствует требуемой функции. Список кодов сообщений (команд) для звукового адаптера приведен в следующем разделе

dwParam1

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

dwParam2

Указатель на структуру параметров. Формат этой структуры зависит от кода сообщения

Возвращаемое значение:

Нуль при нормальном завершении или код ошибки. Список кодов ошибок для функции mciSendCommand приведен в приложении 1. С помощью функции mciGetErrorString, рассмотренной нами ранее, вы можете преобразовать код ошибки в текстовую строку, передав ей этот код в качестве параметра

Формат структуры параметров (блока параметров) и используемые флаги зависят от кода управляющего сообщения, передаваемого функции mciSendCommand через параметр wMessage.



Функция mciSendString


Как передать устройству управляющую строку?

Очень просто - для этого можно воспользоваться функцией mciSendString . Прототип функции mciSendString находится в файле mmsystem.h:

Функция mciSendString

DWORD mciSendString( LPCSTR lpstrCommand, // управляющая строка LPSTR lpstrReturnString, // буфер для результата UINT wReturnLength, // размер буфера HANDLE hCallback) // идентификатор окна извещения

Параметры функции:

lpstrCommand

Дальний указатель на текстовую управляющую строку

lpstrReturnString

Указатель на буфер, в который будет записан результат выполнения команды (в текстовом виде). Этот параметр можно указать как NULL, если приложение не интересуется результатом выполнения команды

wReturnLength

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

hCallback

Идентификатор окна, которое получит извещение (сообщение MM_MCINOTIFY) после того как устройство завершит операцию. Этот параметр можно указать как NULL, если извещение не используется

Возвращаемое значение:

Нуль при успешном завершении или код ошибки (в младшем слове возвращаемого значения):

MCIERR_BAD_CONSTANT

Указана константа, неправильная для данной команды

MCIERR_BAD_INTEGER

Указано значение, неправильное для данной команды

MCIERR_DUPLICATE_FLAGS

Двойное определение параметра или значения

MCIERR_MISSING_COMMAND_STRING

Не указана управляющая строка

MCIERR_MISSING_DEVICE_NAME

Не указано имя устройства, драйвера, файла или алиас

MCIERR_MISSING_STRING_ARGUMENT

Не указан обязательный параметр команды

MCIERR_NEW_REQUIRED_ALIAS

При использовании параметра new следует указать алиас

MCIERR_NO_CLOSING_QUOTE

В команде отсутствуют закрывающие двойные кавычки

MCIERR_NOTIFY_ON_AUTO_OPEN

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

MCIERR_PARAM_OVERFLOW

Строка параметров не помещается в буфер. Необходимо увеличить размер буфера


MCIERR_PARSER_INTERNAL

Ошибка в драйвере устройства. Следует заменить драйвер на новый, более поздней версии

MCIERR_UNRECOGNIZED_KEYWORD

Драйвер не распознал параметр управляющей строки

Например, для проигрывания wav-файла вы можете использовать следующую последовательность вызовов функции mciSendString :

mciSendString( (LPSTR)"open ding.wav type waveaudio alias snd wait", (LPSTR)szBuf, 256, NULL); mciSendString((LPSTR)"play snd wait", (LPSTR)szBuf, 256, NULL); mciSendString((LPSTR)"close snd", (LPSTR)szBuf, 256, NULL);

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

Функция mciGetErrorString

UINT mciGetErrorString( DWORD dwError, // код ошибки LPSTR lpstrBuffer, // буфер для записи текстовой строки UINT wLength); // размер буфера

Параметры функции:

dwError

Код ошибки, полученный от функции mciSendString или mciSendCommand (функция mciSendCommand предназначена для передачи управляющих сообщений, она будет рассмотрена позже)

lpstrBuffer

Буфер, в который будет записано текстовое описание ошибки

wLength

Размер буфера в байтах

Возвращаемое значение:

TRUE при успешном завершении или FALSE, если переданному коду ошибки не соответствует ни одно текстовое описание


Функция MessageBeep


Ранее, в предыдущих томах "Библиотеки системного программиста", мы упоминали функцию MessageBeep :

void MessageBeep(UINT uAlert);

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

Если же звуковой драйвер установлен, в зависимости от значения параметра uAlert функция MessageBeep может воспроизводить один из звуковых фрагментов, записанных в wav-файле.

Обратите внимание, что в файле win.ini имеется раздел [sound], в котором перечислены различные ситуации. Для ситуации может быть указано имя wav-файла, который должен быть воспроизведен при ее возникновении:

[sounds] SystemAsterisk=chimes.wav,Asterisk SystemHand=ding.wav,Critical Stop SystemDefault=,Default Beep SystemExclamation=ding.wav,Exclamation SystemQuestion=ding.wav,Question SystemExit=bye.wav,Windows Exit SystemStart=,Windows Start

У вас нет необходимости изменять этот раздел вручную, так как это можно сделать при помощи приложения Control Panel (рис. 1.8).

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

Значение Описание
-1 Стандартный звуковой сигнал, который выдается на встроенный в компьютер динамик
MB_ICONASTERISK Проигрывается wav-файл, определенный в строке SystemAsterisk раздела [sound] файла win.ini
MB_ICONEXLAMATION Аналогично для строки SystemExclamation
MB_ICONHAND Аналогично для строки SystemHand
MB_ICONQUESTION Аналогично для строки SystemQuestion
MB_OK Аналогично для строки SystemDefault

Функция MessageBeep пытается проиграть звуковой фрагмент в асинхронном (фоновом) режиме, если это позволяет звуковой драйвер. Если в системе установлен драйвер Sound Driver for PC Speaker, функция MessageBeep возвращает управление только после того, как проигрывание будет закончено. Если же функция не может проиграть нужный фрагмент, будет "исполнен" стандартный системный звук, определенный в строке SystemDefault раздела [sound] файла win.ini. Если же и это невозможно, вы услышите "бип" из встроенного в компьютер динамика.



Функция sndPlaySound


А есть ли простой способ проигрывания произвольного wav-файла?

Есть, и он действительно прост. Этот способ основан на использовании функции sndPlaySound , которая находится в библиотеке mmsystem.dll. Ее прототип определен в файле mmsystem.h:

BOOL sndPlaySound(LPCSTR lpszSoundFile, UINT wFlags);

Через параметр lpszSoundFile этой функции можно передать путь к wav-файлу, идентификатор ресурса, содержащего звуковой фрагмент (вы можете записать звуковой фрагмент в ресурсы приложения), или текстовую строку, определенную в разделе [sound] файла win.ini.

Параметр wFlags определяет способ проигрывания звукового фрагмента. Используются следующие значения (некоторые из них можно комбинировать при помощи операции ИЛИ):

Значение Описание
SND_SYNC Синхронный режим работы. Функция sndPlaySound вернет управление только после завершения проигрывания звукового фрагмента
SND_ASYNC Асинхронный режим работы. Функция вернет управление немедленно, проигрывание звукового фрагмента будет выполняться в фоновом режиме параллельно с работой приложения
SND_NODEFAULT Если указанный файл не найден, функция "тихо" возвращает управление, не проигрывая никаких звуков. Если же этот флаг не указан, и файл не найден, будет проигран стандартный системный звук, определенный в строке SystemDefault раздела [sound] файла win.ini. А если и это невозможно, функция не будет ничего проигрывать и вернет значение FALSE
SND_MEMORY Это значение используется для проигрывания звуковых файлов, загруженных в оперативную память, например, из ресурсов приложения
SND_LOOP Если указано значение SND_ASYNC, проигрывание звукового фрагмента будет зациклено. Для того чтобы остановить проигрывание, необходимо вызвать функцию sndPlaySound, указав ей в качестве параметра lpszSoundFile значение NULL
SND_NOSTOP При указании этого значения функция проверяет, выполняется ли в настоящий момент проигрывание фрагмента. Если да, функция возвращает значение FALSE

Во всех случаях, если не указан параметр SND_NOSTOP, функция sndPlaySound возвращает значение TRUE, если выполняется проигрывание, и FALSE - если нет. Учтите, что при использовании функций MessageBeep и sndPlaySound есть ограничение на размер wav-файла - он должен целиком помещаться в физическую память. Поэтому самые простые способы проигрывания звуковых фрагментов хороши только для относительно небольших файлов.



Info


С помощью команды info можно получить информацию об MCI-устройстве:

info device_id parameter [notify] [wait]

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

product

Текстовое описание звукового адаптера

input

Текстовое описание устройства ввода звуковой информации

output

Текстовое описание устройства вывода звуковой информации

file

Имя текущего wav-файла



Инструментальные средства


В этом разделе мы сделаем небольшой обзор приложений, которые по своему назначению являются инструментальными средствами, предназначенными для работы со звуком. Такие приложения можно приобрести либо в комплекте со звуковым адаптером, либо отдельно.

Заслуживает внимания приложение WinDAT, которое создано фирмой Voyetra Technologies и поставляется вместе со звуковым адаптером Sound Galaxy (рис. 1.11).

Рис. 1.11. Приложение WinDAT

Это приложение работает со звуковыми файлами в стандарте Windows (с расширением имени wav) и в стандарте Sound Blaster (с расширением имени voc). Оно намного мощнее приложения Sound Recorder.

В частности, вы можете выделить звуковой фрагмент на осциллограмме при помощи мыши (выделенный фрагмент отображается инвертированием цвета, что видно на рис. 1.11). Выделенный фрагмент может быть скопирован в Clipboard или удален при помощи стандартного меню "Edit". При помощи строки "Mix Paste" меню "Edit" можно наложить фрагмент, записанный в Clipboard, на любой участок фонограммы, указанный при помощи полосы просмотра. Можно вставить паузу или вырезать ненужный участок фонограммы. Все изменения нетрудно отменить, выбрав в меню "Edit" строку "Undo".

Меню "Transforms" позволяет вносить изменения в выделенный участок фонограммы. Можно, например, изменить громкость, определить расположение и максимальную амплитуду сигнала в выделенном фрагменте.

В отличие от приложения Sound Recorder, приложение WinDAT при записи позволяет выбрать стереофонический или монофонический режим, а также задать частоту дискретизации, выбрав ее из возможных для данного адаптера значений. Для этого следует воспользоваться строкой "Setup..." меню "Windows" (достаточно странное место для строки "Setup...", не правда ли?).

Еще одно интересное приложение для работы со звуковыми файлами разработано фирмой IPI (Interactive Products Inc). Оно называется Audio Server (рис. 1.12).

Рис. 1.12.
Приложение Audio Server

Это приложение может служить звуковым OLE-сервером, при этом оно поддерживает технологию Drag & Drop. С помощью его вы можете записать звуковой фрагмент (воспользовавшись кнопкой с изображением микрофона), а затем вставить этот фрагмент в документ как объект, просто переместив мышью изображение магнитофонной кассеты из окна приложения Audio Server в нужное место документа. При необходимости с помощью меню "Edit" можно вставить фрагмент в Clipboard не как объект, а как звуковой файл.

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

Другая разработка фирмы IPI - приложение Voice Toolkit, предназначенное для тех, кто занимается решением проблемы распознавания речи (рис. 1.13).



Рис. 1.13. Приложение Voice Toolkit

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

Однако наиболее впечатляющая возможность приложения Voice Toolkit - отображение трехмерных энергетических спектров (рис. 1.14).



Рис. 1.14. Трехмерный энергетический спектр

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

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



Рис. 1.15. Поворот участка спектра в пространстве

В приложении Voice Toolkit предусмотрен расширяемый набор фильтров для обработки звуковых фрагментов (звуковые эффекты), такие, как эхо, изменение уровня сигнала, проигрывание в обратном направлении, изменение скорости воспроизведения и т. д. (рис. 1.16).



Рис. 1.16. Звуковые эффекты


Интерфейс низкого уровня


При необходимости иметь непосредственный доступ к буферам, содержащим звуковые данные, приложение должно использовать интерфейс низкого уровня, обеспечиваемый несколькими функциями с префиксом имени wave, например, waveInOpen, waveOutOpen, waveOutWrite, waveAddBuffer и т. д.

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

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

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

Дальнейшее изложение материала будет происходить по следующему плану.

Вначале мы расскажем вам о формате wav-файлов, в которых хранятся звуковые данные. Вы узнаете о функциях, предназначенных для работы с такими файлами. Эти функции экспортируются библиотекой mmsystem.dll. Они сильно облегчают работу с файлами на низком уровне. Попутно вы подробно познакомитесь с форматами звуковых данных.

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

После этого мы перейдем к описанию процесса воспроизведения и записи на низком уровне. В конце раздела мы опишем приложение WAVE, демонстрирующее способы работы со звуковыми данными на низком уровне.



Интерфейс управляющих сообщений MCI


Интерфейс управляющих сообщений более удобен для приложений, составленных на языках программирования С и С++. Он предполагает посылку устройствам мультимедиа управляющих сообщений с помощью функции mciSendCommand .

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


Как правило, большинство приложений, составленных на языках программирования C и C++, управляют устройством чтения CD ROM с помощью интерфейса управляющих сообщений MCI. Напомним, что приложения, использующие этот интерфейс, посылают устройствам мультимедиа управляющие сообщения с помощью функции mciSendCommand .

Рассмотрим особенности команд MCI, предназначенных для устройства чтения компакт-дисков.




Использование интерфейса управляющих сообщений для проигрывания mid-файлов аналогично использованию этого интерфейса для проигрывания wav-файлов. Перечислим кратко допустимые коды управляющих сообщений и самые нужные параметры, специфические для драйвера mciseq.drv.

MCI_OPEN

Устройство sequencer открывается командой MCI_OPEN с использованием структуры MCI_OPEN_PARMS, определенной в файле mmsystem.h.

Поле lpstrDeviceType в этой структуре должно содержать указатель на строку имени устройства, или константный идентификатор устройства. Для устройства sequencer вы можете указать имя "sequencer " или константу MCI_DEVTYPE_SEQUENCER .

Через параметр lpstrElementName передается указатель на путь к проигрываемому mid-файлу.

MCI_CLOSE

Эта команда закрывает устройство. Ее необходимо выдавать после завершения работы с устройством.

MCI_PLAY

Команда MCI_PLAY предназначена для проигрывания. Для mid-файлов она используется точно таким же образом, что и для wav-файлов.

MCI_PAUSE

Команда MCI_PAUSE приостанавливает выполнение операции проигрывания.

MCI_RESUME

Эта команда не поддерживается драйвером mciseq.drv . Используйте вместо нее команду MCI_PLAY без указания позиции (для запуска проигрывания с текущей позиции).

MCI_STOP

Команда MCI_STOP останавливает выполнение операции проигрывания.

MCI_SEEK

Команда MCI_SEEK позволяет выполнять позиционирование в пределах mid-файла.

MCI_BREAK

С помощью команды MCI_BREAK указывается виртуальный код клавиши, с помощью которой можно прервать выполнение операции.

MCI_GETDEVCAPS

С помощью команды MCI_GETDEVCAPS можно определить возможности устройства.

MCI_INFO

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

MCI_SYSINFO

С помощью этой команды можно получить системную информацию об устройстве в виде текстовой строки.

MCI_STATUS

Команда MCI_STATUS используется для определения текущего состояния устройства.

MCI_SET

Команда MCI_SET предназначена для установки режима работы устройства.

MCI_COPY

Команда MCI_COPY предназначена для копирования данных в универсальный буфер обмена Clipboard. Для нее используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.

MCI_PASTE

Команда MCI_PASTE вставляет данные из Clipboard в текущий буфер устройства. Для нее, как и для команды MCI_COPY, используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.

MCI_CUT

Команда MCI_CUT удаляет данные из текущего буфера устройства и копирует их в универсальный буфер обмена Clipboard. Для нее используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.

MCI_DELETE

Команда MCI_DELETE удаляет данные из текущего буфера устройства без копирования их в Clipboard.

MCI_LOAD

Команда MCI_LOAD предназначена для загрузки файла.



Интерфейс управляющих строк MCI


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

Все функции интерфейса MCI экспортируются библиотекой mmsystem.dll . Эти функции обращаются непосредственно к драйверам устройств ввода/вывода, а также к функциям более низкого уровня, определенным в библиотеке mmsystem.dll.

Приложения могут использовать два типа программного интерфейса MCI .

Первый тип называется интерфейс управляющих строк (Command-String Interface ). Он основан на использовании текстовых команд (таких, как open, play, close).

Второй тип - это интерфейс управляющих сообщений (Command-Message Interface ). Для управления устройствам посылаются сообщения, коды которых определены в файле mmsystem.h через символические константы (например, MCI_OPEN, MCI_PLAY, MCI_CLOSE).

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

open ding.wav type waveaudio alias snd wait play snd wait close snd

Не намного сложнее выглядят управляющие строки (команды) для записи звукового фрагмента в wav-файл или для проигрывания видеофрагмента из avi-файла.

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

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

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


Для передачи управляющей строки устройству чтения CD ROM вы должны использовать функцию mciSendString . Вам могут потребоваться и другие функции, описанные во второй главе и предназначенные для работы с интерфейсом MCI.




Для работы с музыкальным синтезатором, входящим в комплект звукового адаптера, используется драйвер mciseq.drv . Свое название он получил от слова sequencer (дословно можно перевести как "устройство задания последовательности"). Именно так в терминологии мультимедиа называется устройство, предназначенное для работы с файлами в стандарте MIDI.

При работе с mid-файлами на уровне управляющих строк MCI вы можете пользоваться практически всеми командами, рассмотренными нами в разделе, посвященном записи и воспроизведению звука при помощи устройства waveaudio (не поддерживаются команды resume, record и save). Например, следующая последовательность команд выполнит проигрывание файла canyon.mid, который поставляется в составе дистрибутива операционной системы Windows:

open g:\win\canyon.mid alias music wait play music wait close music

Если с помощью команды play будет предпринята попытка проиграть mid-файл, не авторизованный для Windows, на экране появится предупреждающее сообщение о том, что при стандартной конфигурации MIDI данный файл может проигрываться неправильно (рис.4.1).

Рис. 4.1. Сообщение о попытке выполнить проигрывание файла MIDI, не авторизованного для Windows

Драйвер mciseq.drv не поддерживает следующие параметры команды set: audio all off, audio all on, audio left on, audio left off, audio right on, audio right off. Дополнительно вы можете использовать параметр time format song pointer, устанавливающий формат времени в единицах "одна шестнадцатая ноты", параметр tempo, позволяющий задать темп исполнения мелодии, и некоторые другие. Полный перечень вы сможете найти в документации, которая поставляется вместе с Microsoft SDK для Windows 3.1.



Использование интерфейса управляющих строк


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

Прежде чем работать с устройством средствами MCI, его следует открыть при помощи команды open. Далее при необходимости можно задать режим работы устройства, послав ему команду set с параметрами. Для включения режима проигрывания или записи используются, соответственно, команды play и record . В любой момент времени можно узнать состояние устройства, если послать ему команду status . После использования устройства его необходимо закрыть при помощи команды close .



Использование класса окна MCI


Приложение может создать окно MCI, указав его параметры, управлять им с помощью передачи сообщений через удобный в использовании набор макрокоманд и функций, а также удалить окно MCI. Этих функций и макрокоманд так много, что мы не можем описать их все подробно из-за ограниченного объема нашей книги. Рассмотрим некоторые, самые полезные на наш взгляд, функции и макрокоманды, предназначенные для работы с окном MCI. Полную информацию вы сможете найти в документации, которая поставляется вместе с Video for Windows Development Kit.



Извещения для родительского окна


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



Коды управляющих сообщений MCI


Коды управляющих сообщений делятся на системные (System), обязательные (Required), базовые (Basic) и расширенные (Extended), точно также как и команды, используемые в интерфейсе управляющих строк, рассмотренном нами в предыдущем разделе.

Приведем список кодов управляющих сообщений (в дальнейшем просто команд), которые используются для управления звуковым адаптером.

Команда Тип Описание
MCI_BREAK Системная Назначение виртуального кода клавиши, с помощью которой можно прервать работу устройства
MCI_SYSINFO - Получение системной информации об устройстве (в виде текстовой строки)
MCI_GETDEVCAPS Обязательная Определение возможностей устройства
MCI_CLOSE - Закрытие устройства
MCI_INFO - Получение текстовой информации об устройстве
MCI_OPEN - Открытие устройства
MCI_STАTUS - Определение состояния устройства
MCI_LOAD Базовая Загрузка данных из файла
MCI_PAUSE - Пауза при проигрывании
MCI_PLAY - Включение режима проигрывания
MCI_RECORD - Включение режима записи
MCI_RESUME - Продолжение проигрывания после паузы
MCI_SAVE - Сохранение данных в файле
MCI_SEEK - Позиционирование
MCI_SET - Установка режима работы устройства
MCI_STOP - Останов проигрывания
MCI_CUE Расширенная Подготовка устройства для проигрывания или записи
MCI_DELETE - Удаление фрагмента данных

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



Команды для воспроизведения, записи и позиционирования


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


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



Команды инициализации и завершения работы


В этой группе всего две команды - open и close, предназначенные, соответственно, для открытия и закрытия устройства ввода/вывода звука.



Команды MCI


Какие бывают команды?

Все команды можно разделить на четыре группы : системные (System), обязательные (Required), базовые (Basic) и расширенные (Extended).

Системные команды не передаются драйверу устройства, они обрабатываются непосредственно системой MCI.

Обязательные команды поддерживаются любыми устройствами. Примером таких команд могут послужить строки open и close .

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

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

Приведем список команд, которые используются для управления звуковым адаптером.

Команда Тип Описание
break Системная Назначение виртуального кода клавиши, с помощью которой можно прервать работу устройства.
sysinfo - Получение системной информации об устройстве (в виде текстовой строки)
capability Обязательная Определение возможностей устройства
close - Закрывание устройства
info - Получение текстовой информации об устройстве
open - Открывание устройства
status - Определение состояния устройства
load Базовая Загрузка данных из файла
pause - Пауза при проигрывании
play - Включение режима проигрывания
record - Включение режима записи
resume - Продолжение проигрывания после паузы
save - Сохранение данных в файле
seek - Позиционирование
set - Установка режима работы устройства
stop - Останов проигрывания
cue Расширенная Подготовка устройства для проигрывания или записи
delete - Удаление фрагмента данных

Далее мы расскажем об использовании этих команд применительно к звуковому адаптеру. Особенности других устройств мультимедиа будут рассмотрены позже.



Команды установки режима работы


Команда break не имеет никаких особенностей. Она позволяет определить код виртуальной клавиши, предназначенной для прерывания процесса выполнения команды. По умолчанию используется комбинация клавиш <Control+Break>.

Для команды set можно указывать следующие параметры:

audio all off

Отключение звукового выхода

audio all on

Включение звукового выхода

audio left off

Отключение левого канала

audio left on

Включение левого канала

audio right off

Отключение правого канала

audio right on

Включение правого канала

door closed

Загрузка компакт-диска и фиксирование его в устройстве. Этот параметр может поддерживаться не всеми устройствами (так же, как и параметр door open)

door open

Извлечение компакт-диска

time format milliseconds

В качестве единицы измерения при позиционировании используются миллисекунды. Строку milliseconds можно также указывать как ms

time format msf

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

time format tmsf

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



Компрессия данных


Для компресии видеоданных можно использовать один из компрессоров , поставляемых вместе с Video for Windows, или приобретенный отдельно.

Если видеоизображение содержит большие площади однотонного цвета, хорошие результаты получаются при использовании метода компресии Microsoft RLE . Этим методом имеет смысл пользоваться для сжатия видеофильмов, записанных с экрана компьютера при помощи приложения Screen Capture. Особенно хорошие результаты получаются в том случае, если изображение меняется от кадра к кадру не очень сильно.

Метод компресии Cinepak Codek дает хорошие результаты при необходимости подготовить avi-файл для записи на компакт-диск со скоростью передачи данных 150 Кбайт в секунду (одинарная скорость). Для хранения видеоданных используется формат True Color (в нем для представления цвета используются 24 бита данных). При необходимости воспроизведения в режимах более низкого цветового разрешения выполняется автоматическое преобразование цветов и, если это нужно, создание цветовых палитр. Учтите, что процесс сжатия изображения может длиться часами даже при использовании высокопроизводительного компьютера.

Более быстро, хотя и не так качественно, как Cinepak Codek, работает метод Microsoft Video 1 . При использовании этого метода вы можете выбрать 8-битовый или 16-битовый формат для храненеия цвета.

Метод Intel Indeo Video R3.1 хранит изображения в формате True Color. Формат видеоданных совместим с видеоадаптером Smart Video Recorder, позволяющим получать при записи сжатые данные в реальном времени.

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

Приложения могут обращаться непосредственно к менеджеру ICM для сжатия и восстановления видеоданных, причем ICM по запросу приложения может вывести восстановленные данные на экран. Как правило, явное обращение к ICM требуется только для приложений, редактирующих видеоданные. Средства записи и воспроизведения видео, предоставляемые окнами AVICap и MCI, выполняют компрессию автоматически в прозрачном для приложения режиме.


Аналогично используется компрессор звуковых данных ACM. Система ACM может выполнять не только компрессию и восстановление звуковых данных, но также преобразование и фильтрацию (например, с помощью соответствующего фильтра можно добавить эхо). ACM устанавливается между приложением и библиотекой mmsystem.dll и работает с помощью механизма перехвата вызовов этой библиотеки. Для выполнения преобразований формата ACM обращается к драйверам преобразования формата, которые устанавливаются в системе вместе с Video for Windows или дополнительно.

Пользователь может управлять системой ACM при помощи приложения Sound Mapper , которое доступно из Control Panel после установки Video for Windows (рис. 5.4).



Рис. 5.4. Настройка параметров приложения Sound Mapper

В поле Sound Mapper Drivers отображается список установленных драйверов и их приоритет (который можно изменить, воспользовавшись кнопкой "Priority..."). Для работы будет выбран первый подходящий по своим возможностям драйвер, причем выбор будет выполняться с учетом приоритетов.

В поле Sound Device Preferences можно выбрать устройство для проигрывания или записи (если их несколько).

Систему ACM можно рассматривать как расширение библиотеки mmsystem.dll, обеспечивающее возможность работы с новыми форматами звуковых данных. Когда приложение пытается открыть устройство, поддерживающее тот или иной формат звуковых данных, ACM либо предоставляет приложению физическое устройство, либо подбирает компрессор или декомпрессор, преобразующий указанный формат в один из форматов, поддерживаемых физическим устройством.

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


Литература


1. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Тома 11-13. Операционная система Microsoft Windows 3.1 для программиста. Часть 1-3. Москва, "Диалог-МИФИ", 1994

2. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 14. Операционная система Microsoft Windows 3.1 для программиста. Графический интерфейс GDI. Москва, "Диалог-МИФИ", 1994

3. Charles Petzold. Programming Windows 3.1. Microsoft Press. One Microsoft Way. Redmont, Washington, 1992

4. Brent Rector. Developing Windows 3.1 Applications with Microsoft C/C++. SAMS, 1992

5. Дж. Кейтер. Компьютеры - синтезаторы речи. Москва, МИР, 1985

6. Р. К. Потапова. Речевое управление роботом. Москва, Радио и связь, 1989

7. Г. Н. Котович, В. Ф. Ламекин. Проектирование дельта-преобразователей речевых сигналов. Москва, Радио и связь, 1986

8. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 6. Защищенный режим процессоров Intel 80286/80386/80486. Москва, "Диалог-МИФИ", 1993

9. Windows. Справочник для программистов. Версия 3.0. Часть 1, 2. Москва, "Научный центр", 1991

10. М. Эллис, Б. Строуструп. Справочное руководство по языку программирования C++ с комментариями. Москва, МИР, 1992

11. Бретт Гласс. Высококачественные звуковые платы. МИР ПК, 2/1994, с. 24

12. Лорианн Маклафлин. Блокнотный ПК с миниатюрным дисководом CD-ROM. МИР ПК, 2/1994, с. 30

13. Анита Амиррежвани. Лучшие CD-ROM 1993 года. МИР ПК, 2/1994, с. 67

14. Джефф Бертолуччи. Утилита Voice User for Windows. МИР ПК, 2/1994, с. 155

15. Дэниел Тайнен. Синтез ПК и ТВ. МИР ПК, 4/1994, с. 11

16. Стефан Фревель, Томас Фей. 12 звуковых плат. МИР ПК, 4/1994, с. 25

17. Средства речевого распознавания. МИР ПК, 4/1994, с. 115

18. Бренди Бартош. Ваш мультимедиа-набор. МИР ПК, 4/1994, с. 126

19. Джефф Бертолуччи. Больше мультимедиа за те же деньги. МИР ПК, 4/1994, с. 133

20. И. Б. Рогожкин. Музыка для начинающих. МИР ПК, 4/1994, с. 140

21. Д.В. Солдатенков. Синтезируем музыку. МИР ПК, 5/1994, с. 90

22. Джефф Бертолуччи. Новинки компьютерного рынка. ATI Video Wonder. МИР ПК, 5/1994, с. 136

23. Джефф Бертолуччи. Новинки компьютерного рынка. Diamond VideoStar и VideoStarPro. МИР ПК, 5/1994, с. 138

24. Михаэль Кирмайер. Мультимедиа. BHV- Санкт-Петербург, Санкт-Петербург, 1994



MCI_BREAK


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

typedef struct tagMCI_BREAK_PARMS { DWORD dwCallback; int nVirtKey; UINT wReserved0; HWND hwndBreak; UINT wReserved1; } MCI_BREAK_PARMS; typedef MCI_BREAK_PARMS FAR * LPMCI_BREAK_PARMS;

Поле nVirtKey определяет виртуальный код клавиши прерывания.

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

Поля wReserved0 и wReserved1 зарезервированы.

Для команды MCI_BREAK можно указывать следующие флаги:

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса позиционирования
MCI_BREAK_KEY Поле nVirtKey содержит виртуальный код клавиши прерывания команды
MCI_BREAK_HWND Поле hwndBreak содержит идентификатор окна, которое должно быть текущим для обеспечения возможности прерывания команды
MCI_BREAK_OFF Используется для отключения прерывания

По умолчанию для прерывания используется комбинация клавиш <Control+Break>.



MCI_CLOSE


Эта команда закрывает устройство. Ее необходимо выдавать после завершения работы с устройством.

Для команды MCI_CLOSE используется блок параметров в виде структуры MCI_GENERIC_PARMS , описанной в файле mmsystem.h:

typedef struct tagMCI_GENERIC_PARMS { DWORD dwCallback; } MCI_GENERIC_PARMS; typedef MCI_GENERIC_PARMS FAR *LPMCI_GENERIC_PARMS;

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

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

MCI_GENERIC_PARMS mcigen; DWORD dwrc; mcigen.dwCallback = 0; dwrc = mciSendCommand(mciOpen.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)(LPMCI_GENERIC_PARMS)&mcigen);



MCI_COPY


Команда MCI_COPY предназначена для копирования данных в универсальный буфер обмена Clipboard. Для нее используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.



MCI_CUE


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

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса



MCI_CUT


Команда MCI_CUT удаляет данные из текущего буфера устройства и копирует их в универсальный буфер обмена Clipboard. Для нее используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.



MCI_DELETE


Команда MCI_DELETE удаляет данные из текущего буфера устройства без копирования их в Clipboard. Для нее используется блок параметров в формате структуры MCI_GENERIC_PARMS.

Вместе с этой командой при работе со звуковым адаптером можно использовать структуру MCI_WAVE_DELETE_PARMS :

typedef struct tagMCI_WAVE_DELETE_PARMS { DWORD dwCallback; DWORD dwFrom; DWORD dwTo; } MCI_WAVE_DELETE_PARMS; typedef MCI_WAVE_DELETE_PARMS FAR *LPMCI_WAVE_DELETE_PARMS;

Поле dwFrom используется для передачи команде начальной позиции для удаления, поле dwTo - для передачи конечной позиции удаления.

Вместе с командой MCI_DELETE используются перечисленные ниже флаги.

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса
MCI_FROM Поле dwFrom содержит начальную позицию для удаления
MCI_TO Поле dwTo содержит конечную позицию для удаления



MCI_GETDEVCAPS


С помощью команды MCI_GETDEVCAPS можно определить возможности устройства мультимедиа. Для нее используется блок параметров в формате структуры MCI_GETDEVCAPS_PARMS , определенной в файле mmsystem.h следующим образом:

typedef struct tagMCI_GETDEVCAPS_PARMS { DWORD dwCallback; DWORD dwReturn; DWORD dwItem; } MCI_GETDEVCAPS_PARMS; typedef MCI_GETDEVCAPS_PARMS FAR * LPMCI_GETDEVCAPS_PARMS;

В поле dwReturn после возврата из функции mciSendCommand будет записано значение требуемого параметра. Код нужного параметра следует записать в поле dwItem перед вызовом функции mciSendCommand.

Приведем возможные значения параметра dwItem:

Значение параметра dwItem Описание
MCI_GETDEVCAPS_CAN_EJECT Если устройство может выталкивать носитель данных (например, компакт-диск), после возврата из функции mciSendCommand в поле dwReturn будет ненулевое значение TRUE
MCI_GETDEVCAPS_CAN_PLAY Устройство может проигрывать
MCI_GETDEVCAPS_CAN_RECORD Устройство может записывать
MCI_GETDEVCAPS_CAN_SAVE Устройство может сохранять записанные данные в файле
MCI_GETDEVCAPS_COMPOUND_DEVICE Устройство может работать с файлами
MCI_GETDEVCAPS_DEVICE_TYPE Требуется определить тип устройства. Для звукового адаптера возвращается константа MCI_DEVTYPE_WAVEFORM_AUDIO
MCI_GETDEVCAPS_HAS_AUDIO Устройство имеет звуковой выход
MCI_GETDEVCAPS_HAS_VIDEO Устройство имеет видеовыход
MCI_GETDEVCAPS_USES_FILES При открытии устройства требуется указывать имя файла
MCI_WAVE_GETDEVCAPS_INPUT Количество звуковых входов
MCI_WAVE_GETDEVCAPS_OUTPUT Количество звуковых выходов (каналов)

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

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса
MCI_GETDEVCAPS_ITEM Поле dwItem содержит константу, соответствующую определяемому параметру устройства



MCI_INFO


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

Используется блок параметров в формате структуры MCI_INFO_PARMS :

typedef struct tagMCI_INFO_PARMS { DWORD dwCallback; LPSTR lpstrReturn; DWORD dwRetSize; } MCI_INFO_PARMS; typedef MCI_INFO_PARMS FAR * LPMCI_INFO_PARMS;

Поле lpstrReturn должно содержать дальний указатель на буфер, в который будет записана строка информации. Размер этого буфера следует передать через поле dwRetSize.

Приведем набор флагов для команды MCI_INFO:

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса
MCI_INFO_PRODUCT Требуется получить описание аппаратуры устройства
MCI_INFO_FILE Требуется получить имя текущего файла, связанного с устройством
MCI_WAWE_INPUT Имя текущего устройства ввода
MCI_WAVE_OUTPUT Имя текущего устройства вывода



MCI_LOAD


Команда MCI_LOAD предназначена для загрузки файла. Она использует блок параметров в формате структуры MCI_LOAD_PARMS :

typedef struct tagMCI_LOAD_PARMS { DWORD dwCallback; LPCSTR lpfilename; } MCI_LOAD_PARMS; typedef MCI_LOAD_PARMS FAR * LPMCI_LOAD_PARMS;

Через поле lpfilename передается указатель на буфер, содержащий путь к файлу.

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

Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса
MCI_LOAD_FILE Поле lpfilename содержит указатель на строку пути к файлу



MCI_OPEN


Перед использованием устройства мультимедиа вы должны его открыть, вызвав функцию mciSendCommand и указав ей в качестве второго параметра код команды MCI_OPEN .

Первый параметр (идентификатор устройства) можно указать как 0, так как пока мы не открыли устройство, ему не присвоен никакой идентификатор.

Через последний (четвертый) параметр нужно передать функции адрес заполненной структуры MCI_OPEN_PARMS , определенной в файле mmsystem.h:

typedef struct tagMCI_WAVE_OPEN_PARMS { DWORD dwCallback; UINT wDeviceID; UINT wReserved0; LPCSTR lpstrDeviceType; LPCSTR lpstrElementName; LPCSTR lpstrAlias; } MCI_OPEN_PARMS; typedef MCI_OPEN_PARMS FAR *LPMCI_OPEN_PARMS;

В этой структуре младшее слово поля dwCallback должно содержать идентификатор окна, которому после выполнения команды будет посылаться извещение в виде сообщения MM_MCINOTIFY . Если извещение не посылается, значение этого поля игнорируется.

В поле wDeviceID после возвращения из функции mciSendCommand будет записан идентификатор, присвоенный устройству при открытии. Все последующие команды MCI должны ссылаться на этот идентификатор.

Поле wReserved0 зарезервировано, в него следует записать нулевое значение.

Поле lpstrDeviceType содержит указатель на строку имени устройства, или константный идентификатор устройства. Для звукового адаптера вы можете указать имя "waveaudio " или константу MCI_DEVTYPE_WAVWFORM_AUDIO .

Через параметр lpstrElementName передается указатель на путь к файлу, если нужно проиграть звуковой фрагмент, записанный в wav-файле.

Дополнительно при открытии устройства ему можно назначить алиасное имя, записав в поле lpstrAlias указатель на строку алиасного имени.

Третий параметр функции mciSendCommand предназначен для флагов, определяющих, какие из полей структуры параметров следует использовать при открытии устройства, а также для флага MCI_WAIT, устанавливающего режим работы функции (с ожиданием или без ожидания). Флаги можно объединять с помощью логической операции ИЛИ.

Для структуры MCI_OPEN_PARMS определены следующие флаги:


Флаг Описание
MCI_NOTIFY Если установлен этот флаг, после завершения команды функции окна, адрес которой передан через поле dwCallback, будет послано сообщение MM_MCINOTIFY
MCI_WAIT Функция mciSendCommand вернет управление только после завершения процесса открытия устройства
MCI_OPEN_ALIAS Используется алиасное имя, адрес строки имени должен быть указан в поле lpstrAlias
MCI_OPEN_SHAREABLE Устройство открывается в режиме совместного использования несколькими приложениями одновременно
MCI_OPEN_ELEMENT Поле lpstrElementName содержит указатель на строку, в которой находится путь к файлу
MCI_OPEN_TYPE Поле lpstrDeviceType содержит указатель на строку имени устройства, например, адрес строки "waveaudio"
MCI_OPEN_TYPE_ID Поле lpstrDeviceType содержит константный идентификатор устройства, например, константу MCI_DEVTYPE_WAVWFORM_AUDIO
Приведенный ниже фрагмент кода открывает устройство "waveaudio", причем будет открыт файл, адрес пути к которому записан в переменной szFileName:

MCI_OPEN_PARMS mciOpen; DWORD dwFlags; mciOpen.lpstrDeviceType = (LPSTR)"waveaudio"; mciOpen.lpstrElementName = (LPSTR)szFileName; mciOpen.dwCallback = 0; mciOpen.wDeviceID = 0; mciOpen.wReserved0 = 0; mciOpen.lpstrAlias = NULL; dwFlags = MCI_OPEN_TYPE | MCI_OPEN_ELEMENT | MCI_WAIT; dwrc = mciSendCommand(0, MCI_OPEN, dwFlags, (DWORD)(LPVOID)&mciOpen);

После выполнения этого фрагмента в переменную dwrc, будет записан код результата завершения. При успешном завершении в поле wDeviceID структуры mciOpen будет находиться идентификатор открытого устройства.

Для звукового адаптера вы можете использовать расширенную структуру MCI_WAVE_OPEN_PARMS , также определенную в файле mmsystem.h:

typedef struct tagMCI_WAVE_OPEN_PARMS { DWORD dwCallback; UINT wDeviceID; UINT wReserved0; LPCSTR lpstrDeviceType; LPCSTR lpstrElementName; LPCSTR lpstrAlias; DWORD dwBufferSeconds; } MCI_WAVE_OPEN_PARMS; typedef MCI_WAVE_OPEN_PARMS FAR *LPMCI_WAVE_OPEN_PARMS;

По сравнению со структурой MCI_OPEN_PARMS в ней есть дополнительное поле dwBufferSeconds. Это поле определяет размер внутреннего буфера системы MCI для звукового драйвера. Численно размер буфера должен быть равен длительности звучания в секундах.

Чтобы задействовать это дополнительное поле, следует указать функции mciSendCommand флаг MCI_WAVE_OPEN_BUFFER .


MCI_PASTE


Команда MCI_PASTE вставляет данные из Clipboard в текущий буфер устройства. Для нее, как и для команды MCI_COPY, используется блок параметров в формате структуры MCI_GENERIC_PARMS, флаги MCI_NOTIFY и MCI_WAIT.