Программирование мультимедиа-систем

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

Рубрика Программирование, компьютеры и кибернетика
Вид учебное пособие
Язык русский
Дата добавления 28.06.2009
Размер файла 2,0 M

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

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

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

Аудиоинфоpмация, сжатая по такой технологии, может передаваться потоком (streaming), а может храниться в файлах формата MP3 или WAV-MP3. Отличие второго от первого состоит в наличии дополнительного заголовка WAV-файла, что позволяет при наличии MP3 - кодека (codec, кодер и декодер в комплексном исполнении) в системе использовать для работы с таким файлом стандартные средства Windows. Параметры компрессии при кодировании файла можно варьировать в широких пределах. Качество, неотличимое большинством рядовых слушателей от качества CD, достигается при скорости передачи (bitrate, битрейт) 112128 Кбайт в секунду; при этом сжатие составляет примерно 14:1 относительно исходного объема. Специалисты обычно требуют скорости передачи 256320 Кбайт/сек (это соответствует всего лишь двойной скорости CD-проигрывателя, но для большинства отечественных InterNet - линий недоступна).

Принципиальной особенностью MPEG-кодирования (как видео-, так и аудиоинформации) является компрессия с потерями. После упаковки и распаковки звукового файла методом MP3 результат не идентичен оригиналу `бит в бит'. Напротив, упаковка целенаправленно исключает из упаковываемого сигнала несущественные компоненты, что и приводит к чрезвычайному возрастанию коэффициента сжатия (сжатие до 96:1 при качестве телефонного канала).

Для MP3 также написано множество удобного программного обеспечения. Налажено производство аппаратных (карманных и автомобильных) MP3 плееров (MP3 поддерживает до 5 каналов).

На рубеже 19981999 г. фирма XingTech (www.xingtech.com) первая использовала технологию переменного битрейта (VBR, Variable Bite Rate). В случае VBR задается максимальный допустимый уровень потерь, а кодер выбирает минимальный битрейт, достаточный для выполнения поставленной задачи. Стоящие рядом в конечном потоке фреймы могут оказаться в итоге закодированными с разными параметрами.

По расчетам специалистов MP3 останется актуальным в ближайшее десятилетие (даже несмотря на существование форматов AAG и VQF и продвигаемого MS формата WMA). О существовании иных кодеров (преобразователей информации из одного формата в другой) см. www.sulaco.org/mp3/free.html и www.xiph.org.

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

Для кодирования аудиообъектов MPEG-4 предлагает наборы инструментов как для `живых' звуков, так и для синтезированных. MPEG-4 устанавливает синтаксис двоичных потоков и процесс декодирования в терминах наборов инструментов, что позволяет применять различные алгоритмы сжатия. Диапазон предлагаемых стандартом скоростей потока для кодирования живых звуков - от 2 до 128 Кбайт/сек и выше. При кодировании с переменным потоком минимальная средняя скорость может оказаться еще меньше (порядка 1,2 Кбайт/сек). Для звука высшего качества применяется алгоритм AAC, который дает качество лучше, чем у CD при потоке в 10 с лишним раз меньше. Другой возможный алгоритм кодирования живого звука - TwinVQ. Для кодирования речи предлагаются алгоритмы HVXC (Harmonic Vector eXcitation Coding) для скоростей потока 24 Кбайт/сек и CELP (Code Excited Linear Predictive) для скоростей 424 Кбайт/сек.

MPEG-4 предполагает возможность синтеза речи. На входы синтезатора поступает проговариваемый текст, а также различные параметры `окраски' голоса - ударения, изменения высоты тона, скорости произнесения фонем и т. п. Можно также задать для `говорящего' пол, возраст, акцент и др. В текст можно вставлять управляющую информацию, обнаружив которую синтезатор синхронно с произнесением соответствующей фонемы передаст параметры или команды другим компонентам системы (например, параллельно с голосом может генерироваться поток параметров для анимации лица). Как и всегда, MPEG-4 задает правила работы, интерфейс синтезатора, но не его внутреннее устройство.

Интересная часть `звуковой' составляющей - средства синтеза произвольных звуков и музыки. MPEG-4 предлагает в качестве стандарта подход, разработанный в колыбели многих передовых технологий - MIT Media Lab. и названный SA (Structured Audio, Структурированный Звук). Это не конкретный метод синтеза, а формат описания методов синтеза, в котором можно задать любой из существующих методов (а также, как утверждается, будущих). Для этого предлагаются два языка - SAOL (Structured Audio Orchestra Language) и SASL (Structured Audio Score Language). Первый задает оркестр, а второй - то, что этот оркестр должен играть. Оркестр состоит из инструментов, каждый инструмент представлен сетью элементов цифровой обработки сигналов - синтезаторов, цифровых фильтров, которые все вместе и синтезируют нужный звук. С помощью SAOL можно запрограммировать практически любой нужный инструмент, природный или искусственный звук. Сначала в декодер загружается набор инструментов, а затем поток данных SASL заставляет этот оркестр играть, управляя процессом синтеза; таким образом обеспечивается одинаковое звучание на всех декодерах при очень низком входном потоке и высокой точности управления. С появлением MPEG-4 фактически обретает более реальные и понятные очертания идея ITV (Interactive TeleVision, Интерактивное Телевидение), о котором спорят уже несколько лет и под которым каждый понимает нечто свое (от простого `видео-по-запросу' до детективов с многовариантным развитием сюжета и участием зрителя).

Данные о MPEG-4 приведены в основном для информации о современных тенденциях записи и синтеза медиаданных, интересующихся отсылаем к cselt.it/mpeg и www.mpeg.org. В конце 2000 г. группа разработчиков MPEG планировала объявить об окончании работы над стандартом MPEG-7 (официальное название - Multimedia Content Description Interface).

3.3 Простые способы воспроизведения звука

В простейшем случае приложение должно выдавать звуковые сигналы или проигрывать небольшие звуковые сообщения; для этих целей можно воспользоваться API-Windows функциями MessageBeep и sndPlаySound.

Первая из упомянутых функций имеет прототип

void

MessageBeep(UINT uAlert);

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

Числовой параметр определяется значениями строк ключа HKEY_CURRENT_USER\AppEvents\Schemes\Apps\Default системного реестра, связь событий с нужными звуками производится с помощью приложения Control Panel; связь параметра функции с описанием некоторых событий приведены в нижерасположенной таблице

Значения параметра

функции MessageBeep

Описание

-1

Стандартный звуковой сигнал, выдаваемый на встроенный динамик

MB_ICONASTERISK

Проигрывается WAV-файл, описанный строкой Sys-

temAsterisk

MB_ICONEXLAMATION

Аналогично, строка SystemExclamation

MB_ICONHAND

Аналогично, строка SystemHand

MB_ICONQUESTION

Аналогично, строка SystemQuestion

MB_OK

Аналогично, строка SystemDefault

Функция MessageBeep пытается проиграть звуковой фрагмент в асинхронном (фоновом) режиме; в случае невозможности этого управление возвращается только после окончания проигрывания.

Произвольный звуковой файл проигрывается функцией sndPlaySound, находящейся в библиотеке mmsystem.dll

BOOL

sndPlaySound(LPSTR lpszSoundFile,

UINT wFlags);

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

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

Значения параметра wFlag

Описание

SND_SYNC

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

SND_SAYNS

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

SND_NODEFAULT

Если указанный фрагмент не найден, функция sndPlaySound сразу вернет управление приложению. Если флаг SYNC_NODEFAULT не указан и файл не найден, будет воспроизведен стандартный системный звук (соответствующий строке SystemDefault); если и это невозможно - звучания а не будет, а функция вернет FALSE

SND_MEMORY

Используется для проигрывания загруженных в оперативную память звуковых файлов (например, из ресурсов приложения)

SND_LOOP

При указании SND_ASYNC проигрывание зацикливается (останов возможен только вызовом sndPlaySound с первым нулевым параметром)

SND_NOSTOP

При осуществлении проигрывания в данный момент возвращается FALSE

В работе [6] приведен полный С-код приложения SNDPLAY, демонстрирующего различные способы использования функции sndPlaySound.

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

MCI (Media Control Interface) представляет собой универсальный, независимый от особенной аппаратуры интерфейс, предназначенный для управления устройствами мультимедиа (звуковые и видеоадаптеры, устройства чтения звуковых компакт-дисков и лазерных видеодисков). Возможности интерфейса MCI удовлетворяют практически всем потребностям любого приложения мультимедиа, предназначенного для записи и воспроизведения звуковой или видеоинформации; при необходимости обработки данных на низком уровне или в реальном времени (редактирование и преобразование WAV-файлов, распознавание речи и/или образов, преобразование речи в режиме реальном времени) может использоваться нижеописанным интерфейсом низкого уровня. Ниже подробно описано использование интерфейса MCI при работе со звуком, однако MCI также эффективен при работе с видео; известный Delphi- и C++Builder-компонент MediaPlayer (подробнее см. подраздел 5.3.4) является всего лишь надстройкой над уровнем MCI-инструкций.

Достаточно подробное описание интерфейса MCI приведено в работе [5]; там же дано множество фрагментов исходного кода и готовых (несложных) приложений. Все функции интерфейса MCI экспортируются из библиотеки mmsystem.dll; эти функции непосредственно обращаются к драйверам устройств ввода/вывода и к функциям низкого уровня, определенным в той же библиотеке. Заметим, что не все команды могут быть выполнены конкретным устройством мультимедиа (например, не все устройства работы с лазерными дисками имеют возможность их записи), поэтому перед использованием устройства необходимо программно выяснить его возможности (для чего имеются специальные функции).

Приложения могут использовать два типа программного интерфейса MCI - основанный на использовании текстовых команд интерфейс управляющих строк (Command-String Interface) и основанный на посылке сообщений интерфейс управляющих событий (Command-Message Interface, см. подраздел 3.5 данной работы).

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

open ding.wav type waveaudio alias snd wait

play snd wait

close snd

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

DWORD

mciSendString(LPSTR lpstrCommand, // строка управления

LPSTR lpstrReturnString, // буфер для результата

UINT wReturnLength, // размер этого буфера

HANDLE hCallback); // идентификатор окна извещения

Здесь lpstrCommand - дальний указатель на текстовую управляющую строку, lpstrReturnLength - размер буфера для занесения результата выполнения команды (в текстовом виде, для игнорирования результата можно использовать NULL), wReturnLength - размер этого буфера, hCallback - идентификатор получающего сообщение MM_MCINOTIFY окна (сообщение посылается после завершения операции устройством, для игнорирования сообщения можно использовать NULL).

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

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

UINT

mciGetErrorString(DWORD dwError, // код ошибки

LPSTR lpstrBuffer, // буфер для записи текстовой

// строки ошибки

UINT wLength); // размер этого буфера

При успешном завершении функция mciGetErrorString возвращает TRUE; при невозможности сопоставить заданному коду текстового описания возвращается FALSE.

В работе [6] приведен полный С-код приложения MCISTRRVW, демонстрирующего использование строчного интерфейса MCI для воспроизведения звукового файла; использование команд интерфейса управляющих строк для управления CD ROM и проигрывания MIDI-файлов поясняется также в подразделах 3.7.1 и 3.8.1 данной работы.

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

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

Прототип функции mciSendCommand (см. файл mmsystem.h) приведен ниже

DWORD

mciSendCommand(UINT wDeviceID, // идентификатор устройства

UINT wMessage, // код сообщения

DWORD dwParam1, // флаги команды

DWORD dwParam2); // указатель на структуру

// параметров

Здесь wDeviceID - идентификатор управляемого устройства (для сообщения MCI_OPEN не используется, т.к. идентификатор создается в результате выполнения именно этой команды), wMessage - код сообщения, dwParam1 - флаги команды, dwParam2 - указатель на структуру параметров (формат коей зависит от кода сообщения).

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

Нижеприведенный фрагмент кода открывает устройство `waveaudio' (будет открыт файл, путь к которой записан в переменной szFileAudio)

// определение переменных

MCI_OPEN_PARMS mciOpen;

DWORD dwFlags, dwRc;

// заполнение полей структуры mciOpen

mciOpen.lpstrDeviceID = (LPSTR) waveaudio;

mciOpen.lpstrElementName = (LPSTR) szFileName;

mciOpen.dwCallback = 0;

mciOpen.wDeviceID = 0;

mciOpen.wReserved = 0;

mciOpen.lpstrAlias = NULL;

dwFlags = MCI_OPEN_TYPE | MCI_OPEN_ELEMENT | MCI_WAIT;

// собственно открытие файла с помощью функции mciSendCommand

dwRc = mciSendCommand(0, MCI_OPEN, dwFlags,

(DWORD) (LPVOID) &mciOpen);

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

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

// определение переменных

MCI_GENERIC_PARMS mciGen;

DWORD dwRc;

// заполнение полей структуры mciOpen

mciGen.dwCallback = 0;

// собственно выполнение функции mciSendCommand

dwRc = mciSendCommand(mciOpen.wDeviceID, MCI_CLOSE, MCI_WAIT,

(DWORD) (LPMCI_GENERIC_PARMS) &mciGen);

В работе [6] приведен полный С-код приложения MCIWAVER, демонстрирующего использование интерфейса управляющих сообщений MCI для воспроизведения звуковых WAV-файлов; использование этого интерфейса для управления CD ROM и проигрывания MIDI-файлов приведено также в подразделах 3.7.2 и 3.8.2 данной работы.

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

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

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

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

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

3.6.1 Формат wav-файла, информация о RIFF-структуре файлов

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

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

Рис.3.9.Внешний фрагмент RIFF

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

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

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

Обозначенная на рис.3.9 как `Данные' область может содержать внутри себя другие фрагменты. Для содержащего звуковые данные файла (WAV-файл) эта область содержит идентификатор данных `WAVE', фрагмент формата звуковых данных `fmt' (три символа `fmt' и пробел в конце), а также фрагмент звуковых данных (рис.3.10).

Рис. 3.10.Формат WAV-файла (в структуре RIFF)

Файл может дополнительно содержать фрагменты других типов, поэтому не следует предполагать, что заголовок WAV-файла имеет фиксированный формат. Например, в формате могут присутствовать фрагменты `LIST' или `ABOUT', содержащие информацию о правах копирования и описание самого мультимедиа-файла.

Означенная на рис. 3.10 как `Формат данных' область описывает звуковые данные. Формат этой области для файлов 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 wFormat Tag; // тип формата

WORD nChannels; // количество каналов (моно или стерео)

DWORD nSanplesPerSec; // частота дискретизации

DWORD nAvgBytesPerSec; // скорость потока данных

WORD nBlockAlign; // выравнивание блока данных

} WAVEFORMAT;

typedef WAVEFORMAT *PWAVEFORMAT;

typedef WAVEFORMAT NEAR *NPWAVEFORMAT;

typedef WAVEFORMAT FAR *LPWAVEFORMAT;

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

#define WAVE_FORMAT_PCM 1

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

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

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

nAvgBytePerSec=(nChannel nSamples wBitsPerample) / 8

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

nBlockAlign=(nChannels wBitsPerSample) / 8

Поле wBitPerSample определяет дискретность сигнала (количество бит, используемое для одной выборки сигнала); обычно используются значения 8 или 16.

Формат самих звуковых данных зависит от количества каналов и от дискретности.

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

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

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

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

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

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

Открытие файла совершается функцией mmioOpen. Эта функция может открыть файл для буферизованного или небуферизованного ввода или для работы с файлом в оперативной памяти (полностью возможности указанной функции приведены в поставляемой совместно с MS SDK документации). Ниже приведен прототип функции mmioOpen

HMMIO

mmioOpen(LPSTR szFilename,

LPMMIOINFO lpmmioinfo,

DWORD dwOpenFlags);

Здесь szFilename - дальний указатель на текстовую строку, содержащую путь к открываемому файлу, lpmmioinfo - указатель на содержащую дополнительные параметры для операции открытия файла структуру MMIOINFO (может быть задан как NULL), dwOpenFlags - определяющие режим открытия файла флаги.

При успехе функция mmioOpen возвращает (нестандартный) идентификатор открытого файла, который можно использовать только в функциях с префиксом mmio. Код ошибки можно определить, анализируя поле wErrorRet структуры MMIOINFO.

Формат структуры MMINFO описан в файле mmsystem.h как

typedef struct _MMIOINFO

{

// поля общего назначения

DWORD dwFlags; // общий флаг состояния

FOURCC fccIOProc; // код идентификации процедуры

// ввода - вывода

LPMMIOPROC pIOProc; // указатель на процедуру

// ввода - вывода

UINT wErrorRet; // код завершения

HTASK htask; // идентификатор локальной процедуры

// ввода - вывода

// поля для буферизированного ввода - вывода

LONG ccBuffer; // размер буфера (или 0L)

HPSTR pchBuffer; // указатель на буфер (или NULL)

HPSTR pchNext; // указатель на следующий байт при

// операциях чтении или записи

HPSTR pchEndRead; // указатель на последний прочитанный байт

HPSTR pchEndWrite; // указатель на последний записанный байт

LONG lBufOffset; // дискового смещение начала буфера

// поля для процедур ввода - вывода

LONG lDiskOffset; // дисковое смещение для следующей

// операции чтения или записи

DWORD adwInfo[3]; // дополнительные данные

// для типа MMIOPROC

// прочие поля

DWORD dwReserved1; // зарезервировано

DWORD dwReserved2; // зарезервировано

HMMIO hmmio; // идентификатор открытого файла

} MMIOINFO;

typedef MMIOINFO *PMMIOINFO:

typedef MMIOINFO NEAR *NPMMIOINFO;

typedef MMIOINFO FAF *LPMMIOINFO;

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

hmmio=mmioOpen((LPSTR)lpszFilename, NULL,

MMIO_READ | MMIO_ALLOCBUF);

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

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

Описание режима открытия файла

MMIO_READ

Чтение

MMIO_WRITE

Запись

MMIO_READWRITE

Чтение и запись

MMIO_CREATE

Создание нового файла (если файл с таким именем уже существует, он обрезается до нулевой длины)

MMIO_DELETE

Удаление файла (если удаление выполнено корректно, возвращается TRUE, в противном случае - FALSE)

MMIO_PARSE

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

MMIO_EXIST

Определяет существование указанного файла (при существовании создается текстовая строка, содержащая полный путь к файлу)

MMIO_ALLOCBUF

Файл открывается для буферизованного ввода - вывода (по умолчанию размер буфера равен 8 Кбайт; изменить размер буфера можно заданием его в поле cchBuffer структуры MMIOINFO)

MMIO_COMPAT

Файл открывается в режиме совместимости (файл может быть открыт несколько раз)

MMIO_EXCLUSIVE

Файл будет открыт в монопольном режиме

MMIO_DENYWRITE

Запрещает другим приложения открывать этот файл на запись

MMIO_DENYREAD

Запрещает другим приложения открывать этот файл на чтение

MMIO_DENYNONE

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

MMIO_GETTEMP

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

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

hFile=mmioOpen(szFileName, NULL,

MMIO_CREATE | MMIO_READWRITE);

Закрытие файла, открытого функцией mmioOpen (после завершения работы с ним) должно осуществляться функцией mmioClose.

UINT

mmioClose(HMMIO hmmio, UINT wFlags);

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

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

LONG

mmioWrite(HMMIO hmmio, // идентификатор открытого файла

HPSTR hpBuff, // указатель на буфер данных

LONG dwBytes); // размер буфера

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

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

LONG

mmioRead(HMMIO hmmio, // идентификатор открытого файла

HPSTR hpBuff, // указатель на буфер данных

LONG dwBytes); // размер буфера

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

Позиционирование в открытом с помощью функции mmioOpen файла выполняется функцией mmioSeek.

LONG

mmioSeek(HMMIO hmmio, // идентикатор открытого файла

LONG dwOffset, // смещение для текущей позиции

int nOrigin); // код отсчета смещения

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

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

При формировании нового фрагмента удобна функция 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=mmmioFOURCC(`W', `A', `V', `E');

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

FOURCC

mmioStringToFOURCC(LPCSTR szString, UINT wFlags);

Здесь szString - указатель на преобразуемую строку, закрытую двоичным нулем, при wFlags=MMIO_TOUPPER все символы строки будут преобразованы в заглавные. Функция mmioStringToFOURCC возвращает значение четырехбуквенного идентификатора, могущего быть использованным при формировании нового фрагмента; пример использования функции приведен ниже

FOURCC fourccWaveID;

fourccWaveID=mmioStringToFOURCC(wave, MMIO_TOUPPER);

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

UINT

mmioCreateChunk(HMMIO hmmio, // идентификатор файла

LPMMCKINFO lpck, // указатель на

// структуру MMCKINFO

UINT wFlags); // тип фрагмента

При wFlags=MMIO_CREATERIFF создается фрагмент RIFF, при wFlags=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=waveioocbIn.lpWaveHdr->dwBytesRecorded

+ sizeof(PCMWAVEFORMAT) + 20;

ck.fccType=mmioFOURCC(`W', `A', `V', `E');

mmioCreateChunk(hFile, (LPMMCKINFO) &ck, MMIO_CREATERIFF);

}

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

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

UINT

mmioDescend(HMMIO hmmio, // идентификатор файла

LPMMCKINFO lpck, // указатель на структуру

// MMCKINFO для

// текущего фрагмента

LPMMCKINFO lpckParent, // указатель на стр-ру

// MMCKINFO для

// внешнего фрагмента

UINT wFlags); // режим поиска

Здесь lpckParent - указатель на структуру MMCKINFO, описывающую внешний фрагмент, внутри которого выполняется поиск. В качестве внешнего фрагмента могут выступать только фрагменты `RIFF' или `LIST'; если внешний фрагмент отсутствует, этот параметр можно указывать как NULL. Если указан wFlags=MMIO_FINDCHUNK, выполняется поиск фрагмента, заданного своим идентификатором, если wFlags=MMIO_FINDLIST - выполняется поиск фрагмента внутри фрагмента `LIST', при wFlags=MMIO_FINDRIFF - внутри фрагмента `RIFF'.

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

В нижеприведенном примере кода открывается на чтение 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 предназначена для продвижения текущей позиции к началу следующего фрагмента.

UINT

mmioAscend(HMMIO hmmio, // идентификатор открытого файла

LPMMCKINFO lpck, // указатель на стр-ру MMCKINFO

UINT wFlags); // режим поиска

Структура MMCKINFO должна быть предварительно заполнена функцией mmioDescend или mmioCreateChunk, параметр wFlags не используется и должен быть нулевым.

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

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

В системе могут быть установлены устройства для записи и воспроизведения звука методом импульсно-кодовой модуляции PCM (waveform audio), устройства для записи и проигрывания музыкальных MIDI-файлов, дополнительные (auxiliary) устройства (например, проигрыватель звуковых компакт-дисков) и другие.

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

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

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

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

Для определения возможностей устройств используются функции waveOutGetDevCaps (возможности устройств вывода данных, записанных методом импульсно-кодовой модуляции), waveInGetDevCaps (возможности устройств записи данных методом импульсно-кодовой модуляции), midiOutGetDevCaps (возможности устройств воспроизведения в формате MIDI) и auxGetDevCaps (возможности дополнительных устройств).

Для вышеперечисленных функций с суффиксом GetDevCaps в качестве первого параметра указывается идентификатор устройства, изменяющийся от нуля (для первого устройства) до полученного с помощью функций waveOutGetNumDevs, waveInGetNumDevs, midiOutGetNumDevs, midiInGetNumDevs и auxGetNumDevs значения.

Второй параметр является дальним указателем на структуру, формат которой зависит от типа устройства. Это может быть структура AUXCAPS (дополнительное устройство), MIDIINCAPS (устройство для ввода данных MIDI), MIDIOUTCAPS (устройство вывода MIDI-данных), WAVEINCAPS (устройство ввода данных, записанных методом импульсно-кодовой модуляции) или WAVEOUTCAPS (устройство вывода данных, записанных методом импульсно-кодовой модуляции).

Третий параметр определяет размер соответствующей структуры в байтах.

Структура AUXCAPS определяется следующим образом

typedef struct auxcaps_tag

{

UINT wMid; // код разработчика драйвера

UINT wPID; // код устройства

VERSION vDriverVersion; // версия драйвера

char szPname[MAXPNAMELEN]; // название устройства

UINT wTechnology; // тип устройства

DWORD dwSupport; // поддерживаемые функции

} AUXCAPS;

typedef AUXCAPS *PAUXCAPS;

typedef AUXCAPS NEAR *NPAUXCAPS;

typedef AUXCAPS FAR *LPAUXCAPS;

Поля wMid, wPid, vDriverVersion и szPname определены во всех структурах, используемых для определения возможностей устройств мультимедиа.

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


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

  • Области применения мультимедиа. Основные носители и категории мультимедиа-продуктов. Звуковые карты, CD-ROM, видеокарты. Программные средства мультимедиа. Порядок разработки, функционирования и применения средств обработки информации разных типов.

    контрольная работа [528,8 K], добавлен 14.01.2015

  • Использование профессиональных графических примеров. Применение продуктов мультимедиа. Линейное и структурное представление информации. Мультимедиа ресурсы сети Интернет. Программное обеспечение мультимедиа-компьютера. Создание и обработка изображения.

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

  • Создание информационной мультимедиа системы (медиа-плеера) для презентации аудио-видео информации о факультете КТАС, представленной в специально отснятых и смонтированных avi-файлах. Разработка модуля пользовательского интерфейса, выходные данные.

    курсовая работа [41,5 K], добавлен 21.11.2014

  • Мультимедиа презентация - это уникальный и самый современный на сегодняшний день способ представления информации. Важнейшей особенностью мультимедиа технологии является интерактивность – способность пользователя влиять на работу информационного средства.

    курсовая работа [106,5 K], добавлен 28.06.2008

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

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

  • Характерные особенности мультимедиа-технологий и их возможности. Применение мультимедиа-технологий в обучении. Объединение многокомпонентной информационной среды в однородном цифровом представлении, долговечное хранение и простота переработки информации.

    курсовая работа [77,8 K], добавлен 15.07.2012

  • Стандартное устройство вывода графической информации в компьютере IBM - система из монитора и видеокарты. Основные компоненты видеокарты. Графическое и цветовое разрешение экрана. Виды мониторов и видеокарт. Мультимедиа-проекторы, плазменные панели.

    контрольная работа [38,7 K], добавлен 09.06.2010

  • Исследование видов программного обеспечения для мультимедиа и средств редактирования. Описания редакторов векторной и растровой графики. Анализ методов преобразования изображений. Технологии баз данных, требуемые для графики. Преобразование текста в речь.

    презентация [154,7 K], добавлен 11.10.2013

  • Различные виды определения термина "мультимедиа". Мультимедиа-технологии как одно из наиболее перспективных и популярных направлений информатики. Мультимедиа в сети Internet. Компьютерная графика и звуки. Различные области применения мультимедиа.

    курсовая работа [43,5 K], добавлен 19.04.2012

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

    курсовая работа [386,3 K], добавлен 21.12.2010

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