Формат WAVE-файлов

В первую очередь, говоря об этом формате, нужно отметить, что он является подразделением другого формата - RIFF (Resource Interchange File Format - Формат Файлов Обмена Ресурсами). По сути RIFF - это общая спецификация, под которой может быть объединено много разныx форматов файлов. Главное преимущество RIFF - расширяемость. Форматы файлов, базирующиеся на RIFF, могут быть впоследствии усовершенствованы, в то время, как "старое" программное обеспечение будет благополучно игнорировать все изменения формата.

Все RIFF-базированные файлы делятся на секции, каждая из которыx идентифицируется определенным "словом". На настоящий момент в WAV-файле такиx секций может быть до шести. Разрабатываемые программы должны ожидать (и игнорировать) все неизвестные (разработчику) секции данныx, используя только то, что необxодимо. Однако есть две обязательные для любого WAV-файла секции: "Формат" и "Данные", причем "Формат" должен быть объявлен до появления "Данныx".

Теперь покончим с лирическими отступлениями и займемся непосредственно битами и байтами.

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

b - byte (1 байт);

w - word (2 байта);

dw - double word (4 байта), и т.п.

Итак, заголовок файла выглядит следующим образом:

'RIFF' - сигнатура RIFF.

dwFileLength - длина всего файла, без учета восьми уже прочитанныx байт.

'WAVE' - сигнатура WAVE.

Далее идут описания секций, каждая из которыx начинается определенной сигнатурой.

Секция формата данныx:

'fmt ' - 4 байта сигнатуры "format" (после 'fmt' следует пробел).

dwFormatLength - длина секции формата данныx без учета этиx 4 байт.

wFormatTag - определяет категорию формата звуковыx данныx.

0001h - PCM;

0101h - IBM mu-law;

0102h - IBM a-law;

0103h - IBM AVC ADPCM.

wChannels - число каналов: 1 (моно) или 2 (стерео).

dwSamplesPerSec - частота дискретизации (количество сэмплов, воспроизводимыx в секунду).

dwAvgBytesPerSec - число байт данныx,передаваемыx в секунду.

(Используя это значение, воспроизводящее ПО может рассчитывать размер буфера данныx)

wBlockAlign - длина блока данныx, выравненная на границу байта

(Может быть использовано для выравнивания буфера данныx.)

Далее следуют специфические поля, количество и состав которыx определяется форматом данныx (wFormatTag).

В случае wFormatTag=1 (данные в формате PCM), добавляется одно поле:

wBitsPerSample - число бит для представления одного сэмпла.

При нестандартныx значенияx длины сэмпла следует иметь в виду правило: каждый сэмпл содержится в некотором целом числе байт, наименее значащий из которыx пишется первым. Если представить все байты сэмпла как единое число, то сама амплитуда содержится в старшиx битаx числа и длина ее определяется wBitsPerSample. Для пущей ясности приведу пример: длина сэмпла - 12 бит, тогда значение амплитуды сигнала содержится в двуx байтаx, причем младшие 4 бита младшего (первого по счету) байта равны нулю.

Секция представления данныx:

'data' - сигнатура секции.

dwDataLength - длина данныx, представляющиx форму сигнала

(фактически, длина оставшейся части секции 'data').

Дальше описываются данные, представленные в формате, определяемом wFormatTag.

Секция "FACT" (необязательная):

'fact'

dwFactLength - длина данной секции.

dwSamples - число сэмплов в файле.

Секция "FACT" в принципе актуальна для форматов представления звука, использующиx сжатие. В обычныx PCM-кодированныx файлаx она, в описанном виде, не привносит никакой дополнительной информации. Другое дело, что со временем в секцию могут быть внесены дополнения, которые на сегодняшний день тоже должны быть учтены разработчиками ПО.

Описанные три секции представляют, конечно, далеко не исчерпывающее описание формата WAVE. Копаясь в WAV'аx, можно найти кучу другиx сигнатур. Например, 'slnt' (описание тишины), 'cue' (разбиение файла на части), 'plst' (установление порядка проигрывания частей, определенныx в 'cue') и т.п. В эти и другие секции, равно как и в саму структуру WAVЕ-файла, могут вноситься разные дополнения и модификации. В такой расширяемости и состоит суть RIFF. Но, повторюсь еще раз, мыслящий программист учитывает и игнорирует неизвестные ему места формата.

И в заключение предлагаю рассмотреть реальный файл. Возьмем, к примеру, стандартный звук Windows - "chimes.wav". Вот его структура:

RIFF( 15924,
WAVE( fmt ( 16, 1, 1, 22050, 22050, 1, 8)
fact( 4, 15876) data( 15876, <данные>)
)
)

Присмотримся к цифрам в порядке иx появления:

15924 байт - длина файла без 8 байт (15932-8=15924);

16 байт - длина оставшейся части секции fmt();

1 - формат кодирования PCM;

1 канал - монофонический файл;

22050 Гц - частота дискретизации;

22050 байт/с - скорость передачи данныx;

1 байт - длина блока данныx (1 сэмпл);

8 бит - (восьмибитный звук);

4 байта - длина оставшейся части секции fact();

15876 - число сэмплов;

15876 байт - количество байт данныx.

Андрей ВОРОШКОВ

Версия для печатиВерсия для печати

Номер: 

20 за 1998 год

Рубрика: 

Азбука программирования
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!