Программирование PC Wave File Format - формат звукового файла WAV Tue, March 19 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Wave File Format - формат звукового файла WAV Печать
Добавил(а) microsin   

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

[Форматы данных]

Поскольку формат WAV-файла пришел от операционной системы Windows, в которой традиционно использовались процессоры Intel, все значения данных формата хранятся как Little-Endian, т. е. самый младший значащий байт идет первым.

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

7 'e' 'x' 'a' 'm' 'p' 'l' 'e'

Пример формата строки Wave

[Структура файла]

WAV-файл использует стандартную RIFF-структуру, которая группирует содержимое файла из отдельных секций (chunks) - формат выборок аудиоданных, аудиоданные, и т. п. Каждая секция имеет свой отдельный заголовок секции и отдельные данные секции. Заголовок секции указывает на тип секции и количество содержащихся в секции байт. Такой принцип организации позволяет программам анализировать только необходимые секции, пропуская остальные секции, которые не известны или которые не требуют обработки. Некоторые определенные секции могут иметь в своем составе подсекции (sub-chunks). Например, как можно увидеть на диаграмме, описывающий основной формат WAV-файла, секции "fmt " и "data" являются подсекциями секции "RIFF". 

Chunk ID "RIFF"
Chunk Data Size
RIFF Type ID "WAVE"
Chunk ID "fmt "
Chunk Data Size
Sample Format Info
Chunk ID "data"
Chunk Data Size
Digital Audio Samples
 
Заголовок секции (Chunk Header)
 
Данные секции (Chunk Data Bytes)

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

[Заголовок WAV-файла, секция типа RIFF]

Заголовки WAV-файла используют стандартный формат RIFF. Первые 8 байт файла - стандартный заголовок секции RIFF, который имеет ID секции "RIFF" и размер секции, равный размеру файла минус 8 байт, используемых для RIFF-заголовка. Первые 4 байта данных в секции "RIFF" определяют тип ресурса, который можно найти в секции. WAV-файлы всегда используют тип ресурса "WAVE". После типа ресурса (ID "WAVE") идут все секции звукового файла, которые определяют аудиосигнал.

Смещение Размер Описание Значение
0x00 4 Chunk ID "RIFF" (0x52494646)
0x04 4 Chunk Data Size (file size) - 8
0x08 4 RIFF Type "WAVE" (0x57415645)
0x10
Wave chunks (секции WAV-файла)
Значения полей секции RIFF

[Секции WAV-файла]

Существует довольно много типов секций, заданных для файлов WAV, но большинство WAV-файлов содержат только две из них - секцию формата ("fmt ") и секцию данных ("data"). Это именно те секции, которые необходимы для описания формата выборок аудиоданных, и для хранения самих аудиоданных. Хотя официальная спецификация не задает жесткий порядок следования секций, наилучшей практикой будет размещение секции формата перед секцией данных. Многие программы ожидают именно такой порядок секций, и он наиболее разумен для передачи аудиоданных через медленные, последовательные источники наподобие Интернет. Иначе если формат придет после данных, то перед стартом воспроизведения необходимо считать и запомнить все аудиоданные, только после получения формата запускать воспроизведение.

Все секции формата RIFF и соответственно секции Wave сохраняются в следующем формате (см. диаграмму). Заметьте, что даже вышеупомянутая секция RIFF соответствует этому формату.

Смещение Размер Описание
0x00 4 Chunk ID
0x04 4 Chunk Data Size
0x08 Chunk Data Bytes
Формат секций RIFF и Wave

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

[Секция формата - "fmt "]

Секция формата содержит информацию от том, как сохранены аудиоданные и как они должны воспроизводиться. Информация включает в себя тип используемой компрессии, количество каналов, скорость выдачи выборок (sample rate), количество бит в выборке (bits per sample) и другие атрибуты.

Смещение Размер Описание Значение
0x00 4 Chunk ID "fmt " (0x666D7420)
0x04 4 Chunk Data Size 16 + extra format bytes
0x08 2 Compression code 1 - 65,535
0x0a 2 Number of channels 1 - 65,535
0x0c 4 Sample rate 1 - 0xFFFFFFFF
0x10 4 Average bytes per second 1 - 0xFFFFFFFF
0x14 2 Block align 1 - 65,535
0x16 2 Significant bits per sample 2 - 65,535
0x18 2 Extra format bytes 0 - 65,535
0x1a
Дополнительные данные формата (Extra format bytes) *

Значения секции формата (Wave Format Chunk), * читайте для подробностей текст далее

Идентификатор секции (Chunk ID) и объем данных (Data Size)
Идентификатор секции всегда "fmt " (0x666D7420) и объем данных равен размеру стандартного формата WAV (16 байт) плюс размер всех дополнительных байт формата, необходимых для поддержки специфических форматов звука, если он не содержит несжатых данных PCM. Обратите внимание, что идентификатор секции "fmt " оканчивается на символ пробела (0x20).

Код сжатия (Compression Code)
Первое слово данных формата указывает на тип сжатия, используемого для данных звука. В таблице содержится список кодов сжатия, используемых в настоящее время.

Код Описание
0 (0x0000) Unknown
1 (0x0001) PCM/uncompressed
2 (0x0002) Microsoft ADPCM
6 (0x0006) ITU G.711 a-law
7 (0x0007) ITU G.711 µ-law
17 (0x0011) IMA ADPCM
20 (0x0016) ITU G.723 ADPCM (Yamaha)
49 (0x0031) GSM 6.10
64 (0x0040) ITU G.721 ADPCM
80 (0x0050) MPEG
65,535 (0xFFFF) Experimental

Общеиспользуемые коды сжатия
(Common Wave Compression Codes)

Количество каналов (Number of Channels)
Количество каналов указывает, сколько отдельных аудиосигналов закодировано в секции данных звука (wave data chunk). Значение 1 означает монофонический сигнал, 2 означает стерео, и т. п.

Скорость выборок (Sample Rate)
Число выборок аудиосигнала, приходящихся на секунду. На эту величину не влияет количество каналов.

Среднее количество байт в секунду (Average Bytes Per Second)
Величина, показывающая, сколько байт за секунду данных должно быть пропущено через цифроаналоговый преобразователь (D/A converter, DAC) во время воспроизведения файла. эта информация полезна, чтобы определить - могут ли данные поступать от источника с нужной скоростью, чтобы не отставать от воспроизведения. Эта величина просто вычисляется по формуле:
AvgBytesPerSec = SampleRate * BlockAlign

Выравнивание блока (Block Align)
Количество байт на одну выборку. Эта величина может быть вычислена по формуле:
BlockAlign = SignificantBitsPerSample / 8 * NumChannels

Количество используемых бит на выборку (Significant Bits Per Sample)
Величина указывает количество бит, формирующих каждую выборку сигнала. Обычно эта величина 8, 16, 24 или 32. Если число бит не выравнено по байту (не делится нацело на 8), количество используемых байт на выборку округляется вверх к наименьшему количеству байт. Неиспользуемые биты устанавливаются в 0 и игнорируются. Такие форматы (с числом бит на выборку, некратным 8) встречаются редко.

Дополнительные данные формата (Extra Format Bytes)
Величина указывает, сколько далее идет дополнительных данных, описывающих формат. Она отсутствует, если код сжатия 1 (uncompressed PCM file), но может присутствовать и иметь любую другую величину для других типов сжатия, зависящую от количества необходимых для декодирования данных. Если величина не выравнена на слово (не делится нацело на 2), должен быть добавлен дополнительный байт в конец данных, но величина должна оставаться невыровненной.

Область Extra format bytes очень удобна для добавления дополнительных данных в WAV-файл. Это может понадобиться, например, когда нужно в WAV-файл сохранить какую-то дополнительную информацию, привязанную к записанным звуковым данным. Если Ваш прибор сохраняет измерения в звуковые данные WAV-файла, то он также получает возможность добавить какие-то описательные данные - какой вход прибора использовался, какие были настройки входа (постоянный ток, переменный ток), какой коэффициент усиления был задан и т. п. Ниже на рисунках показаны примеры дампов двух WAV-файлов. В файле слева заголовок чистый (размер области Extra format bytes равен нулю), а в файле справа в секцию "fmt " добавлены 256 байт данных Extra format bytes.

WAV-clear WAV-with-256-header
Пример дампа WAV-файла без дополнительных данных. Пример дампа WAV-файла, где в заголовок "fmt " добавлены 256 байт дополнительных данных Extra Format Bytes.

Для наглядности отдельные секции стандартного заголовка выделены разными цветами. 256 байт в области Extra Format Bytes показаны розовым цветом, а их размер - красным.

[Секция данных - "data"]

Секция данных Wave (Wave Data Chunk) содержит данные цифровых выборок аудиосигнала, которые можно декодировать с использованием формата и метода компрессии, указанных в секции формата Wave (Wave Format Chunk). Если код компрессии 1 (несжатый PCM, Pulse Code Modulation), то данные представлены в виде сырых, непреобразованных (raw) величин выборок. Эта статья описывает, как сохранены несжатые данные PCM, однако не вдается в подробности многих используемых форматов с компрессией.

WAV-файлы обычно содержат только одну секцию данных, но секций может быть несколько, если они содержатся в секции списка Wave (Wave List Chunk "wavl").

Смещение Длина Тип Описание Значение
0x00 4 char[4] chunk ID "data" (0x64617461)
0x04 4 dword chunk size зависит от количества выборок и компрессии
0x08
данные выборок (sample data)

Формат секции данных "data"

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

Время Канал Значение
0 1 (левый) 0x0053
2 (правый) 0x0024
1 1 (левый) 0x0057
2 (правый) 0x0029
2 1 (левый) 0x0063
2 (правый) 0x003C

Чередуемые выборки стерео Wave

Один момент, касающийся данных выборок, который может вызвать некоторое замешательство - когда выборки представлены 8 битами, они определены как значения без знака (unsigned). Все другие битовые размеры указываются как величины со знаком (signed). Например, выборка 16 бит может иметь значение в диапазоне от -32768 до +32767, где средняя точка (напряжение сигнала равно 0) соответствует значению 0.

Как уже было указано ранее, все секции RIFF (включая секции WAVE "data") должны быть выровнены по размеру на слово (2 байта). Если данные выборок содержатся в нечетном количестве байт, в конец данных выборок должен быть добавлен выравнивающий нулевой байт. За заголовке секции "data" размер не должен учитывать этот выравнивающий байт.

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

Секция fact содержит информацию о содержимом WAV-файла, зависящую от кода компрессии. Она требуется для всех форматов WAVE со сжатием, и требуется, если данные сигнала содержатся внутри секции списка (LIST) "wavl", но не требуется для несжатого формата PCM WAVE (код компрессии 1), который содержит аудиоданные в секции "data".

Смещение Размер Описание Величина
0x00 4 Chunk ID "fact" (0x66616374)
0x04 4 Chunk Data Size зависит от формата
0x08
Данные, зависящие от формата (Format Dependant Data)

Формат секции Fact

Данные, зависящие от формата (Format Dependant Data)
В настоящий момент задано только одно поле для данных, зависящих от формата. Это единственное 4-байтное значение, которое указывает число выборок в секции данных аудиосигнала. Эта величина может использоваться вместе с количеством выборок в секунду (Samples Per Second value) указанном в секции формата - для вычисления продолжительности звучания сигнала в секундах.

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

Секция списка wave (wave list chunk) используется для указания нескольких чередований секций "slnt" и "data". Эти секции могут помочь уменьшить размер файла путем указания слышимых сегментов выборок, когда поток аудиоданных содержит несколько интервалов тишины.

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

Смещение Размер Описание Значение
0x00 4 Chunk ID "wavl" (0x736C6E74)
0x04 4 Chunk Data Size зависит от размера секций "data" и "slnt"
0x08 Список чередования секций "slnt" и "data"

Формат секции Wave List

Секция тишины (silent chunk) используется для указания сегмента паузы звучания, которая имеет некоторую продолжительность в выборках сигнала. Секция тишины всегда содержится только внутри секции списка wave (wave list chunk). Когда эта секция объявляет тишину, не нужно задавать нулевую громкость или базовую выборку. Это фактически удерживается последняя выборка сигнала, считанная в предыдущей секции данных ((Wave Data Chunk)) секции списка Wave (wave list chunk). Если не было предыдущих секций данных, должно использоваться базовое значение выборки, равное 127 для 8-битных данных, 0 для 16-битных данных или всех данных с бОльшим количеством бит на выборку. Эти требования могут казаться тривиальными, но если это не выполнить, то могут появится нежелательные щелчки и перепады в аудиосигнале.

Смещение Размер Описание Величина
0x00 4 Chunk ID "slnt" (0x736C6E74)
0x04 4 Chunk Data Size 4
0x08 4 Number of Silent Samples 0 - 0xFFFFFFFF

Silent Chunk Format

Количество выборок тишины (Number of Silent Samples)
Эта величина указывает число выборок тишины, которое должно появиться в аудиосигнале на точке списка wave (wave list chunk).

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

Смещение Размер Описание Значение
0x00 4 Chunk ID "cue " (0x63756520)
0x04 4 Chunk Data Size depends on Num Cue Points
0x08 4 Num Cue Points количество точек cue в списке
0x0c
Список интересующих точек (List of Cue Points)

Формат секции Cue

Идентификатор ID секции и объем данных (Chunk ID and Data Size)
Идентификатор ID секции для секции cue всегда "cue " (0x666D7420). Обратите внимание, что строка ID оканчивается на символ пробела (0x20). Размер данных секции равен размеру Num Cue Points (4) плюс количество последующих точек cue, помноженное на размер данных каждой точки cue (24). Следующая формула может использоваться для вычисления размера данных секции Cue:
ChunkDataSize = 4 + (NumCuePoints * 24)

Количество примечательных точек (Num Cue Points)
Эта величина указывает количество последующих cue-точек в этой секции.

Список примечательных точек (List of Cue Points)
Список точек cue - просто набор описаний последовательных точек, который имеет следующий формат.

Смещение Размер Описание Значение
0x00 4 ID unique identification value
0x04 4 Position play order position
0x08 4 Data Chunk ID RIFF ID of corresponding data chunk
0x0c 4 Chunk Start Byte Offset of Data Chunk *
0x10 4 Block Start Byte Offset to sample of First Channel
0x14 4 Sample Offset Byte Offset to sample byte of First Channel

Формат точки Cue

ID
Каждая примечательная (cue) точка имеет уникальное идентификационное значение, используемое для связи точек cue с информацией в других секциях. Например, секция метки (Label chunk) содержит текст, который описывает точку в WAV-файле со ссылкой на связанную точку cue.

Позиция (Position)
Позиция определяет смещение выборки, связанное точкой cue, с точки зрения позиции выборки в заключительном потоке выборок, сгенерированных списком воспроизведения. Другими словами, если указана секция списка воспроизведения (play list chunk), значение позиции равно номеру выборки, на которой эта точка cue встретится при воспроизведении всего списка (play list) в заданном порядке. Если нет секции списка воспроизведения (play list chunk), то значение позиции должно быть равно 0.

ID секции данных (Data Chunk ID)
Эта величина указывает ID из 4 байт, используемый секцией, содержащей выборку, которая соответствует этой точке cue. WAV-файл без списка воспроизведения (play list chunk) всегда имеет "data". WAV-файл, имеющий список воспроизведения (play list chunk) с секциями данных и тишины, может быть либо "data", либо "slnt".

Начало секции (Chunk Start)
Значение начала секции указывает байтовое смещение в секции списка Wave (Wave List Chunk) секции, содержащей выборку, соответствующую этой точке. Это та же самая секция, описанная значением ID секции данных (Data Chunk ID). Если в WAV-файле нет секции списка Wave (Wave List Chunk), эта величина равна 0, иначе эта величина равна смещению. в секцию "wavl". Первая секция в секции списка (Wave List Chunk) должна быть указана со значением 0.

Начало блока (Block Start)
Значение Block Start указывает смещение в байтах в секцию "data" или секцию "slnt" для начала блока, содержащего выборку. Начало блока задает первый байт несжатых данных звука PCM или последний байт в сжатых данных звука, где декомпрессия может начаться для нахождения значения соответствующего значения выборки.

Смещение выборки (Sample Offset)
Смещение выборки указывает смещение в блок (указанный Block Start) для выборки, соответствующей интересующей точке (cue point). В несжатых данных звука PCM это просто байтовое смещение в секцию "data". В сжатых данных звука это значение равно количеству выборок (которое может и не быть в байтах) от Block Start до выборки, соответствующей интересующей точке (cue point).

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

Смещение Размер Описание Величина
0x00 4 Chunk ID "plst" (0x736C6E74)
0x04 4 Chunk Data Size num segments * 12
0x08 4 Number of Segments 1 - 0xFFFFFFFF
0x0a
List of Segments

Формат секции Playlist

Количество сегментов (Number of Segments)
Это значение задает количество последующих сегментов в секции плейлиста.

Список сегментов (List of Segments)
Список сегментов - просто набор следующих друг за другом описаний сегментов, которые составлены по формату, приведенному в таблице ниже. Сегменты не должны быть ни в каком определенном порядке, потому что для определения порядка воспроизведения используется позиция интересующей точки (cue point position), связанная с каждым описанием списка.

Смещение Размер Описание Величина
0x00 4 Cue Point ID 0 - 0xFFFFFFFF
0x04 4 Length (in samples) 1 - 0xFFFFFFFF
0x08 4 Number of Repeats 1 - 0xFFFFFFFF

Формат сегмента плейлиста

ID интересующей точки (Cue Point ID)
Cue Point ID указывает начальную выборку для этого сегмента путем указания значения Cue Point, заданного в списке Cue Point List. ID связывающий этот сегмент с интересующей точкой (Cue Point), должен быть уникальным по отношению ко всем другим ID интересующих точек (Cue Point ID).

Длина (Length)
Длина сегмента указывает количество выборок для воспроизведения или зацикливания от начальной выборки, заданной в связанной Cue Point.

Количество повторений (Number of Repeats)
Количество повторений определяет, сколько раз сегмент должен повторить свое воспроизведение, перед продолжением воспроизведения на следующем сегменте.

Секция связанного списка данных (Associated Data List Chunk) используется для задания текстовых меток и имен, которые связаны с интересующими точками - для предоставления для каждой позиции текстовой метки или имени.

Смещение Размер Описание Величина
0x00 4 Chunk ID "list" (0x6C696E74)
0x04 4 Chunk Data Size зависит от содержащегося текста
0x08 4 Type ID "adtl" (0x6164746C)
0x0c
список текстовых меток и имен

Формат связанного списка данных

Type ID
Идентификатор типа (type ID) используется для обозначение типа связанного списка данных и всегда имеет значение "adtl".

Список текстовых меток и имен
Список текстовых меток и имен - просто список рассортированных секций, которые определяют текст различными способами. В файлах WAVE используются три основные типы секций - секция метки (Label Chunk), секция примечания (Note Chunk) и секция помеченного текста (Labeled Text Chunk).

Секция метки (Label Chunk) всегда содержится внутри секции связанного списка данных (associated data list chunk). Она используется для связывания текстовой метки с интересующей точкой (Cue Point). Эта информация часто отображается на маркерах или флажках в аудиоредакторах.

Смещение Размер Описание Величина
0x00 4 Chunk ID "labl" (0x6C61626C)
0x04 4 Chunk Data Size зависит от содержащегося текста
0x08 4 Cue Point ID 0 - 0xFFFFFFFF
0x0c
текст

Формат секции метки

Cue Point ID
Идентификатор интересующей точки (Cue Point ID) указывает точку расположения выборки, соответствующей этой текстовой метке, путем предоставления ID интересующей точки (Cue Point), заданной в списке интересующих точек (Cue Point List). ID, который связывает эту метку с интересующей точкой (Cue Point), должен быть уникальным по отношению ко всем другим идентификаторам интересующих точек (Cue Point ID).

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

Секция примечания (Note Chunk) всегда содержится внутри секции связанного списка данных (associated data list chunk). Она используется для связывания текстового комментария с интересующей точкой (Cue Point). Эта информация сохраняется тем же самым способом, как и метки в секции метки.

Смещение Размер Описание Величина
0x00 4 Chunk ID "note" (0x6E6F7465)
0x04 4 Chunk Data Size зависит от содержащегося текста
0x08 4 Cue Point ID 0 - 0xFFFFFFFF
0x0C
текст

Формат секции примечания

Cue Point ID
Идентификатор интересующей точки (Cue Point ID) указывает точку расположения выборки, соответствующей этому текстовому примечанию, путем предоставления ID интересующей точки (Cue Point), заданной в списке интересующих точек (Cue Point List). ID, который связывает это примечание с интересующей точкой (Cue Point), должен быть уникальным по отношению ко всем другим идентификаторам интересующих точек (Cue Point ID).

Text
Текст - строка символов, оканчивающихся нулем. Если количество символов в строке нечетно, к строке должно быть добавлено однобайтовое выравнивание. Добавленное выравнивание не учитывается в поле размера секции примечания (комментария).

Секция помеченного текста (Labeled Text Chunk) всегда содержится внутри секции связанного списка данных (associated data list chunk). Она используется для связывания текстовой метки с регионом или секцией данных звука. Эта информация часто отображается в помеченных регионах звука в аудиоредакторах.

Смещение Размер Описание Величина
0x00 4 Chunk ID "ltxt" (0x6C747874)
0x04 4 Chunk Data Size зависит от содержащегося текста
0x08 4 Cue Point ID 0 - 0xFFFFFFFF
0x0c 4 Sample Length 0 - 0xFFFFFFFF
0x10 4 Purpose ID 0 - 0xFFFFFFFF
0x12 2 Country 0 - 0xFFFF
0x14 2 Language 0 - 0xFFFF
0x16 2 Dialect 0 - 0xFFFF
0x18 2 Code Page 0 - 0xFFFF
0x1A
текст

Формат секции помеченного текста

Cue Point ID
Идентификатор интересующей точки (Cue Point ID) указывает начальную выборку, которая соответствует этой текстовой метке, с помощью предоставления ID интересующей точки, заданного в списке интересующих точек (Cue Point List). ID интересующей точки, связанный с этой меткой, должен быть уникальным по отношению ко всем другим ID интересующих точек.

Sample Length
Длина выборок (sample length) задает, сколько выборок входит в регион или интервал секции, начиная с интересующей точки.

Purpose ID
Поле предназначения указывает, для чего используется текст. Например, значение "scrp" означает текст скрипта, "capt" означает close-caption (поясняющая подпись, субтитр). Имеется несколько большее количество значений purpose ID, но они предназначены для использования с другими типами файлов формата RIFF (которые обычно не используются в файлах WAVE).

Country, Language, Dialect, Code Page
Эти поля (страна, язык, диалект, кодовая страница) используются для указания информации о месторасположении и языке, используемых в тексте. Обычно они нужны для запросов о получении информации от операционной системы.

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

Секция семплера (Sampler Chunk) задает основные параметры инструмента, как например семплер MIDI, который должен использоваться для воспроизведения данных звука. Наиболее важно, что он включает в себя информацию о зацикливаниях звука во время воспроизведения. Конечно, Вы можете найти, что это является дублированием информации, которую можно найти в секциях Cue и Playlist формата WAVE, но, к счастью, в секции семплера это сделано более гибко, непротиворечиво, и лучше задокументированным способом.

Смещение Размер Описание Величина
0x00 4 Chunk ID "smpl" (0x736D706C)
0x04 4 Chunk Data Size 36 + (Num Sample Loops * 24) + Sampler Data
0x08 4 Manufacturer 0 - 0xFFFFFFFF
0x0C 4 Product 0 - 0xFFFFFFFF
0x10 4 Sample Period 0 - 0xFFFFFFFF
0x14 4 MIDI Unity Note 0 - 127
0x18 4 MIDI Pitch Fraction 0 - 0xFFFFFFFF
0x1C 4 SMPTE Format 0, 24, 25, 29, 30
0x20 4 SMPTE Offset 0 - 0xFFFFFFFF
0x24 4 Num Sample Loops 0 - 0xFFFFFFFF
0x28 4 Sampler Data 0 - 0xFFFFFFFF
0x2C
List of Sample Loops

Формат секции семплера

Manufacturer
Поле производителя (manufacturer) указывает код MIDI Manufacturer's Association (MMA) для семплера предназначенного для приема звука этого файла. Каждый производитель продукта MIDI имеет свой уникальный ID, который идентифицирует компанию. Если не указан конкретный производитель, то должно быть подставлено значение 0.

В значении имеется некоторая дополнительная информация, которую можно использовать для трансляции в величину, используемую в передаче на семплер формата MIDI System Exclusive. Старший байт показывает количество младших байт (1 или 3), которые значимы для кода производителя. Например, значение для Digidesign будет 0x01000013 (0x13) и значение для Microsoft будет 0x30000041 (0x00, 0x00, 0x41). См. список MIDI Manufacturers List.

Product
Поле продукта указывает ID модели MIDI, заданный производителем. Для получения идентификаторов продукта связывайтесь с производителем семплера. Если не указан конкретный продукт производителя, то должно быть подставлено значение 0.

Sample Period
Период выборки указывает длительность времени воспроизведения одной выборки в наносекундах (обычно равно 1 / [количество выборок в секунду], где [количество выборок в секунду] равно величине, указанной в секции формата).

MIDI Unity Note
MIDI unity note (что-то типа тональности MIDI, решил этот термин не переводить) - величина, имеющая то же самое значение как и MIDI Unshifted Note секции инструмента (instrument chunk). Поле MIDI Unshifted Note указывает музыкальную ноту, на которой выборка будет воспроизведена на её оригинальной скорости выборок sample rate (sample rate указано в секции формата).

MIDI Pitch Fraction
MIDI pitch fraction (тоже какой-то специфический музыкальный термин, что-то типа "доля высоты звука") указывает доли полутона вверх от величины, указанной в поле MIDI unity note. Значение 0x80000000 означает 1/2 полутона (50 cents) и значение 0x00000000 означает неточную настройку между полутонами (лично для меня это все звучит как китайская грамота).

SMPTE Format
SMPTE формат указывает формат времени Society of Motion Pictures and Television E, используемый в следующем поле SMPTE Offset. Если установлено значение 0, SMPTE Offset также должно быть равно 0.

Значение SMPTE Format
0 нет смещения SMPTE offset
24 24 фрейма в секунду
25 25 фреймов в секунду
29 30 фреймов в секунду с выпадением фрейма (30 выпадает)
30 30 фреймов в секунду

Значения формата SMPTE

SMPTE Offset
Смещение SMPTE Offset - величина, указывающая на смещение времени, используемое для синхронизации / калибровки первой выборки звука. Здесь используется форма 0xhhmmssff, где hh - число со знаком, указывающее количество часов (-23 .. 23), mm - беззнаковая величина количества минут (0 .. 59), ss - (0 .. 59) беззнаковая величина количества секунд и ff - беззнаковая величина количества фреймов (0 .. -1).

Sample Loops
Поле циклов выборок указывает количество определений зацикливания выборок в последующем списке (см. list of sample loops). Это значение может быть установлено в 0, что означает отсутствие последующих зацикливаний.

Sampler Data
Величина данных семплера (sampler data value) указывает количество байт, которые последуют за этой секцией (включая весь список sample loop list). Эта величина больше, чем 0, когда приложение нуждается в сохранении дополнительной информации. Эта величина отражена в значении chunks data size.

List of Sample Loops
Список зацикливаний (list of sample loops) - простой набор последовательных описаний циклов, которые следуют нижеописанному формату. Зацикливания не имеют какой-либо определенный порядок, поскольку каждый цикл выборок, связанный с интересующей точкой, используется для определения порядка воспроизведения. Секция семплера не является обязательной.

Смещение Размер Описание Величина
0x00 4 Cue Point ID 0 - 0xFFFFFFFF
0x04 4 Type 0 - 0xFFFFFFFF
0x08 4 Start 0 - 0xFFFFFFFF
0x0C 4 End 0 - 0xFFFFFFFF
0x10 4 Fraction 0 - 0xFFFFFFFF
0x14 4 Play Count 0 - 0xFFFFFFFF

Формат цикла выборок

Cue Point ID
Идентификатор интересующей точки (Cue Point ID) - указывает уникальный ID, который соответствует одной из заданных интересующих точек в списке (cue point list). Кроме того, этот ID соответствует любой из меток, заданных в связанной секции данных (data list chunk), которая позволяет назначать текстовые метки различным циклам выборок.

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

Значение Loop Type (тип зацикливания)
0 Цикл вперед (обычный)
1 Альтернативный цикл (вперед/назад, известный также как Ping Pong)
2 Цикл назад (обратный)
3 - 31 Зарезервировано для будущих стандартных типов
32 - 0xFFFFFFFF Специфические типы, относящиеся к семплеру (задаются производителем)

Значения Loop Type

Start
Значение старта указывает байтовое смещение в данные звука первой выборки, проигрываемой в цикле.

End
Значение окончания указывает байтовое смещение в данные звука последней выборки, проигрываемой в цикле.

Fraction
Дробное (fractional) значение указывает дробную часть выборки, которая принадлежит циклу. Это позволяет точно настроить длительность цикла с точностью выше, чем позволяет одна выборка. Величина может находиться в диапазоне 0x00000000 .. 0xFFFFFFFF. Значение 0 означает отсутствие дробной части, значение 0x80000000 означает 1/2 от длительности выборки. Значение 0xFFFFFFFF соответствует минимальной дробной части выборки, которую можно задать.

Play Count
Значение счетчика воспроизведений (play count) определяет количество проигрываний цикла. 0 означает постоянный бесконечный цикл, который не прервется, пока не произойдет принудительное внешнее вмешательство (например, музыкант отпустит клавишу). Все другие значения указывают абсолютное количество проигрываний цикла.

Секция инструмента (instrument chunk) используется для описания - каким образом звук должен быть проигран как звук инструмента. Эта информация полезна для обмена музыкальной информацией между музыкальными редакторами-семплерами, основанными на выборках (семплах), трекерами или программными таблицами звука. Эта секция является необязательной, и не может встречаться в WAVE-файле больше одного раза.

Смещение Размер Описание Величина
0x00 4 Chunk ID "ltxt" (0x6C747874)
0x04 4 Chunk Data Size 7
0x08 1 Unshifted Note 0 - 127
0x09 1 Fine Tune (dB) -50 - +50
0x0A 1 Gain -64 - +64
0x0B 1 Low Note 0 - 127
0x0C 1 High Note 0 - 127
0x0D 1 Low Velocity 1 - 127
0x0E 1 High Velocity 1 - 127

Формат секции инструмента

Unshifted Note
Поле несмещенной ноты (unshifted note) имеет то же самое предназначение, что и у MIDI Unity Note секции семплера - указывает музыкальную ноту, на которой выборка будет проиграна с её оригинальной скоростью (sample rate, указывается в секции формата).

Fine Tune
Значение точной настройки (fine tune) указывает, насколько подача выборки должна быть изменена, когда звук воспроизведен в центах (1/100 полутона). Отрицательная величина означает, что высота тона должна быть снижена, а позитивная величина означает, что высота тона должна быть повышена.

Gain
Значение усиления (gain) указывает количество децибел для настройки выхода при проигрывании. Значение 0 dB означает отсутствие изменений, 6 dB означает удвоение амплитуды каждой выборки, -6 dB означает уменьшение амплитуды каждой выборки вдвое. Каждые дополнительные +/- 6 dB удваивают или делят амплитуду надвое соответственно.

Low Note и High Note
Поля нот указывают диапазон нот MIDI, в которых звук должен быть проигран, когда происходит событие приема ноты MIDI (от программного обеспечения или команды контроллера MIDI. Контроллером может выступать, например, клавиатура MIDI). Этот диапазон необязательно должен включать значение Unshifted Note.

Low Velocity и High Velocity
Поля скорости (velocity) указывают диапазон скоростей MIDI (MIDI velocity), с которыми должен проигрываться звук. 1 относится к самому легкому проигрыванию, 127 к самому жесткому.

[Изменения формата]

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

    * Некорректная величина блока выравнивания (Block Alignment) - с этим можно иметь дело, вычисляя Block Alignment по указанной ранее формуле.
    * Некорректная величина среднего количества выборок в секунду (Average Samples Per Second) - с этим можно иметь дело, вычисляя Average Samples Per Second по указанной ранее формуле.
    * Отсутствие пустых байт для выравнивания на слово (Missing word alignment padding) - с этим трудно бороться, но можно давать пользователю предупреждение, если имеется нераспознанный ID блока, и одно смещение побайтового чтения дает возможность распознать ID блока. Это не полное решение, но оно обычно работает, даже если у программы нет полного списка легальных ID.

[Ссылки]

1. Пример простейшей обработки WAV-файла (допускается только несжатый PCM).
2. Простой SD/microSD звуковой плеер на 8-выводном микроконтроллере ATtiny85.
3. Библиотека Petit FatFS: модуль файловой системы FAT.
4Почему у секции "fmt " размер не равен 16 байтам?
5. Audio File Format Specifications site:ece.mcgill.ca.

 

Комментарии  

 
-2 #7 Имярек 19.06.2021 11:52
Не понимаю, почему при том, что величина "дополнительные данные формата" указывает, сколько далее идёт дополнительных данных, описывающих формат, но она отсутствует, если код сжатия 1 (uncompressed PCM file), в приведённом примере добавления произвольных данных в область Extra format byte сосуществует код сжатия 1 с добавлением произвольных данных. Да и вообще, разве и в примере без добавления не должна длина фрагмента fmt быть равной 16, а не 18, раз код сжатия равен 1?
Цитировать
 
 
-3 #6 user 03.05.2017 14:14
Небольшая неточность 65,536 (0xFFFF) Experimental. На самом деле 65,536 == 0х10000.

microsin: благодарю, исправил.
Цитировать
 
 
-2 #5 Рахат 29.04.2017 02:44
Дополнительные данные, где они находятся? До 44 байта, как я понял, заголовок, а после сырые аудиоданные.

microsin: в статье достаточно подробно этот момент описан (см. также врезку, где показан пример). Дополнительные данные могут появляются после заголовка, а могут и не появляться. Если этих данных нет, то да, после заголовка сразу идут сырые аудиоданные.
Цитировать
 
 
+1 #4 Олег 14.06.2016 13:12
Что-то не указано самое важное, а именно: где записан сам сигнал, его частоты, амплитуды и в каком виде.

microsin: в формате WAV ничего подобного не предусмотрено. Однако можно определить пользовательски е секции данных, где Вы можете указать нужную информацию.
Цитировать
 
 
+2 #3 shaman 09.06.2011 17:52
Хороший, технически грамотный перевод вот отсюда:
http://www.sonicspot.com/guide/wavefiles.html
Спасибо!
Цитировать
 
 
+5 #2 nva 26.05.2011 03:15
Интересно, автор сам-то понимает, что написал?... Судя по тому, что терминологией он не владеет, вряд ли...

microsin: наверное, Вы просто не весь материал поняли. Мне кажется - наоборот, автор отлично разбирается в вопросе, и очень подробно и доходчиво излагает структуру формата WAV-файла.
Цитировать
 
 
+9 #1 frenzy 18.03.2011 02:05
сверхкрутая статья
Цитировать
 

Добавить комментарий


Защитный код
Обновить

Top of Page