Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Operatsionnye_sistemy.doc
Скачиваний:
151
Добавлен:
12.03.2015
Размер:
4.94 Mб
Скачать

§ 9.3. Технология обработки формата riff

9.3.1. Структура формата RIFF

В целом следует отметить, что мультимедийные файлы соответствуют стандарт-

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

необходимо разбираться в структуре RIFF-файлов и знать особенности MMIO-функций,

предназначенных для записи и чтения этих файлов.

Протокол RIFF (Resource Interchange File Format - формат обмена файлами ресур-

сов) описывает файловую структуру с теговой организацией. Это означает, что файл

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

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

пример RIFF, INFO или PAL. (Четвертым символом тега PAL является пробел.) Каждый

тег начинает блок данных (chunk). Наиболее важные блоки начинаются с тега RIFF и

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

начинаются с блока RIFF, а все остальные данные организованы в виде вложенных бло-

ков первого блока.

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

Тег сообщает о типе последующих данных. Значение размера, имеющее тип DWORD,

указывает объем данных, содержащихся в блоке. В конце данных находится тег сле-

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

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

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

230

вах и номере версии или содержаться список признаков (cues), т.е. позиций в файле, свя-

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

Блоки RIFF отличаются от большинства блоков тем, что их поля данных (т.е. раз-

дел двоичных данных) всегда начинаются с четырехсимвольного кода, обозначающего

тип содержимого файла: звукозапись (WAVE), MIDI-файл (RMID), DIB-файл (RDIB),

видеоклип (RMMP) или палитра (PAL).

Поскольку в RIFF-файлах содержится так много четырехсимвольных кодов, суще-

ствует специальная макрокоманда mmioFOURCC, предназначенная для создания этих

кодов. Приведенная ниже команда записывает тег RIFF в одно из полей информацион-

ной структуры:

MMCKINFO mmckinfo.ckid = mmioFOURCC ( 'R', 'I', 'F', 'F' );

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

данных. При чтении данных система заполняет поля описанием текущего блока. При

записи данных вы заполняете информацию, которая необходима системе для сохране-

ния-блока.

typedef struct _MMCKINFO

{

FOURCC ckid;

DWORD cksize;

FOURCC fccType;

DWORD dwDataOffset;

DWORD dwFlags;

} MMCKINFO;

/* структура блока данных RIFF-файла */

// идентификатор блока

// размер блока

// тип или список типов

// смещение блока данных в файле

// флаги, используемые MMIO-функциями

FOURCC представляет собой новый тип данных, основанный на типе DWORD

(каждый символ кода записывается в один из четырех байтов). Третье поле, fccType,

представляет собой тег типа содержимого, который следует после каждого тега RIFF.

Поле fccType отсутствует в блоках, не имеющих идентификатора RIFF. На рис. 9.1 пока-

зана связь между родительским и вложенным блоками RIFF-файла [12].

Рис. 9.1.Структура RIFF-файла

Как ранее указывалось, специализированный набор API-функций для мультимедиа

содержится в подсистеме WinMM. Эти функции ориентированы на работу с блочной

структурой RIFF-файлов. Кроме того, они обеспечивают буферизацию доступа к фай-

лам. Рассмотрим основные функции интерфейса.

9.3.1. API-функции для обработки RIFF-файла

231

Функция mmioOpen() открывает файл и управляет параметрами его буфера.

HMMIO mmioOpen( LPTSTR lpszFilename,

LPMMIOINFO lpmmioinfo,

DWORD fdwOpen );

// имя открываемого файла

// место для размещения

// информации о файле

// флаги

Первый параметр содержит имя файла, второй - информацию о его текущем со-

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

размер буфера ввода/вывода (8 Кб), параметр lpmmioinfo должен содержать значение

NULL. Третий параметр содержит набор флагов. Ниже представлены некоторые из них.

MMIO_READ- Допускает только чтение файла.

MMIO_WRITE- Допускает только запись файла.

MMIO_READWRIТЕ- Допускает чтение и запись файла.

MMIO_CREATE- Создает новый файл.

MMIO_DELETE- Удаляет существующий файл.

MMIO_EXCLUSIVE- Предотвращает использование файла другими программами.

MMIO_DENYWRITE- Предотвращает изменение файла другими программами.

MMIO_ALLOCBUF- Обеспечивает буферизацию ввода/вывода.

В библиотеках языка С функция fopen начинает буферизованный ввод/вывод, а

функция _open - небуферизованный ввод/вывод. Аналогичные действия можно задать с

помощью флага MMIO_ALLOCBUF. Система откликается на соответствующую ко-

манду выделением буфера, размер которого задан по умолчанию (8 Кб). Чтобы увели-

чить или уменьшить размер буфера, нужно указать соответствующее значение в струк-

туре MMIOINFO или вызвать функцию mmioSetBuffer().

Функция mmioOpen() возвращает дескриптор мультимедийного файла. Такие деск-

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

другими файловыми функциями С-библиотек или функциями подсистемы Win32.

Функции mmioRead(), mmioWrite() и mmioClose() выполняют с мультимедийными

файлами операции чтения, записи и закрытия соответственно.

Ряд функций ввода/вывода специально ориентирован на выполнение операций с

блоками данных. Чтобы добавить в файл новый блок, следует вызвать функцию mmio-

CreateChunk(). Эта команда записывает заголовок блока, включающий тег, размер, а

также (для блоков RIFF и LI ST) код содержимого и устанавливает позицию указателя

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

mmioWrite().

MMRESULT mmioCreateChunk( HMMIO hmmio,

LPMMCKINFO lpmmcki,

UINT uOptions );

// дескриптор RIFF-файла

// описание нового блока

// параметры создания

Для записи блоков RIFF и LIST установите флаги MMIO_CREATERIFF и

MMIO_CREATELIST соответственно.

Для перемещения указателя файла от блока к блоку служат функции

mmioDescend() и mmioAscend(). Первая перемещает указатель на начало блока данных, а

вторая - на его конец.

MMRESULT mmioDescend( HMMIO hmmio,

// дескриптор RIFF-файла

LPMMCKINFO lpmmcki, // место для записи

// информации о блоке

232

LPMMCKINFO lpnunckiParent, // необязательная структура

// родительского блока

UINT uSearch );

MMRESULT mmioAscend( HMMIO hmmio,

// флаги поиска

// дескриптор RIFF-файла

LPMMCKINFO lpmmcki, // место для записи

// информации о блоке

UINT uReserved );

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

// должен содержать 0

Функция mmioDescend() возвращает информацию о блоке в параметре lpmmcki.

Можно также заставить ее выполнять поиск блоков определенного типа. Для инициации

такого поиска последний параметр должен содержать значение MMIO_FINDCHUNK,

MMIO_FINDLIST или MMIO_FINDRIFF. Поиск начинается с текущей позиции в

файле и завершается в конце файла. Функция mmioAscend(), помимо перемещения к

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

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

ка.

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

(Теги, состоящие из символов нижнего регистра, обозначают вложенные блоки.) Струк-

тура PCMWAVEFORMAT определяет содержимое этого блока:

/* универсальный формат файла звукозаписи (информация, общая для всех форматов) */

typedef struct waveformat_tag

{

WORD wFormatTag;

WORD nChannels;

// тип формата

// количество каналов (1= моно; 2 = стерео)

DWORD nSamplesPerSec; // частота оцифровки

DWORD nAvgBytesPerSec; //необходимо для оценки размера буфера

WORD nBlockAlign;

} WAVEFORMAT;

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

/* структура формата звукозаписи, специфичная для РСМ-данных */

typedef struct pcmwaveformat_tag

{

WAVEFORMAT wf;

WORD wBitsPerSample;

}

PCMWAVEFORMAT;

В настоящее время для WAV-файлов определен только один формат - импульсно-

кодовая модуляция РСМ, поэтому поле wFormatTag структуры WAVEFORMAT должно

содержать значение WAVE_FORMAT_PCM.

В структуре PCMWAVEFORMAT к общему формату WAV-данных добавлено по-

ле wBitsPerSample, указывающее разрядность выборки. Это поле определяет объем па-

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

битов. Монофоническая звукозапись длительностью в 1 секунду, оцифрованная с часто-

той 11 кГц и разрядностью 8 битов, содержит 11000 выборок, т.е. занимает объем при-

мерно 11 Кб. При стереофонической звукозаписи происходит одновременная оцифровка

сигналов в двух каналах. Если разрядность выборок в каждом из них равна 8 битам, то

разрядность суммарной выборки составляет 16 битов. Объем стереофонической звуко-

233

записи длительностью в 1 секунду, с частотой оцифровки 11 кГц и разрядностью 8 би-

тов, составляет 22 Кб.

§ 9.4. API-функции интерфейса DirectSound

Программно-аппаратный комплекс DirectSound представляет собой компонент

технологии DirectX, обеспечивающий работу приложений с аудиоинформацией. Этот

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

ускорение выполнения функций и прямой доступ к устройствам вывода аудиоинформа-

ции. Технология DirectSound построена на нескольких интерфейсах API функций, каж-

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

ком. Рассмотрим основные интерфейсы комплекса DirectSound [4].

Для воспроизведения аудиоинформации DirectSound использует интерфейс IDi-

rectSound. Для записи звука средствами DirectSound используется интерфейс IDirect-

SoundCapture. Он позволяет получить информацию о возможностях, предоставляемых

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

мещаться записываемая аудиоинформация. Для создания интерфейса IDirectSoundCap-

ture предназначена функция IDirectSoundCaptureCreate(), возвращающая адрес указателя

на объект интерфейса IDirectSoundCapture. Для определения возможностей устройства

записи аудиоинформации следует вызвать функцию GetCaps(), аргументом которого яв-

ляется объект структуры DSCCAPS. После вызова GetCaps() в объекте структуры

DSCCAPS содержится информация о возможностях устройства записи аудиоинформа-

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

формата записи. Стандартные форматы записи приведены в структуре WAVEINCAPS:

WAVE_FORMAT_1M08 – монофонический звук с частотой дискретизации 11,025 КГц

и 8-битовым кодированием отсчета;

WAVE_FORMAT_1M16 – монофонический звук с частотой дискретизации 11,025 КГц

и 16-битовым кодированием отсчета;

WAVE_FORMAT_1S08 – стереофонический звук с частотой дискретизации 11,025 КГц

и 8-битовым кодированием отсчета;

WAVE_FORMAT_1S16 – стереофонический звук с частотой дискретизации 11,025 КГц

и 16-битовым кодированием отсчета;

WAVE_FORMAT_2M08 – монофонический звук с частотой дискретизации 22,05 КГц и

8-битовым кодированием отсчета;

WAVE_FORMAT_2M16 – монофонический звук с частотой дискретизации 22,05 КГц и

16-битовым кодированием отсчета;

WAVE_FORMAT_2S08 – стереофонический звук с частотой дискретизации 22,05 КГц

и 8-битовым кодированием отсчета;

WAVE_FORMAT_2S16 – стереофонический звук с частотой дискретизации 22,05 КГц

и 16-битовым кодированием отсчета;

WAVE_FORMAT_4M08 – монофонический звук с частотой дискретизации 44,1 КГц и

8-битовым кодированием отсчета;

WAVE_FORMAT_4M16 – монофонический звук с частотой дискретизации 44,1 КГц и

16-битовым кодированием отсчета;

WAVE_FORMAT_4S08 – стереофонический звук с частотой дискретизации 44,1 КГц и

8-битовым кодированием отсчета;

WAVE_FORMAT_4S16 – стереофонический звук с частотой дискретизации 44,1 КГц и

16-битовым кодированием отсчета.

Для работы с буферами воспроизведения используются интерфейсы IDirectSound-

Buffer и IDirectSound3DBuffer. Для работы с буферами записи используется интерфейс

IDirectSoundCaptureBuffer. Для создания буфера записи аудиоинформации предназна-

234

чен метод CreateCaptureBuffer(). Одним из аргументом данного метода является объект

структуры DSCBUFFERDESC, содержащий параметры создаваемого буфера записи.

После создания объекта буфера DirectSoundCapture вызов метода GetCaps() позволяет

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

ным буфером записи, может быть получена вызовом метода GetFormat(). Определение

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

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

фейс IKsPropertySet. Интерфейс IDirectSoundNotify служит для отметки события о том,

что при воспроизведении или при записи была достигнута определенная позиция в бу-

фере.

235

СПИСОК ЛИТЕРАТУРЫ

1. Вильямс А. Системное программирование в Windows 2000. С.-Пб.: Питер, 2001.-621с.

2. Гордеев А.В. Операционные системы. С.-Пб.: Питер, 2006. - 415 с.

3. Карпов В.Е., Коньков К.А. Основы операционных систем.Интернет-университет ин-

формационных технологий - ИНТУИТ, http://www.intuit.ru/department/os/osintro/,2004

4. Марапулец Ю.В. Основы программирования в Win32 API. П.-Камчатский: Камчат-

ГТУ, 2004. – 148 с.

5. Олифер В.Г., Олифер Н.А. Сетевые операционные системы. С.-Пб.: Питер,2006.-538с.

6. Пэтзолд Ч. Программирование для Windows 95. С.-Пб.:BHV-Санкт-Петербург, 1997.

- 523 с.

7. Рихтер Д. Windows. Создание эффективных Win32-приложений с учетом специфики

64-разрядной версии Windows. С.-Пб.: Питер, 2001. - 624 с.

8. Соломон Д., Русинович М. Внутреннее устройство Windows 2000. С.-Пб.: Питер,

2004г. - 746 с.

9. Финогенов К.Г. Win32. Основы программирования. М.: Диалог-МИФИ, 2002. - 416 с.

10. Харт Дж. М. Системное программирование в среде Win32. М.: Издательский дом

"Вильямс", 2001. - 463 с.

11. Щупак Ю.А. Win32 API. Эффективная разработка приложений. С.-Пб.: Питер, 2007. -

572 с.

12. Эззель Б., Блейни Д. Windows 98. Руководство разработчика. К.: "Ирина", BHV, 1999.

- 672 с.

236

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]