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 |
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.