Format chunk
The fmt chunk says how the samples in the data chunk are encoded. It
comes in three sizes, each extending the one before, and its first field decides how the
rest of the file is read.
Fields
Offsets are from the start of the chunk’s data, after the eight-byte chunk header. In the usual 44-byte layout the data starts at file offset 20.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 2 | u16 | wFormatTag | the format code: 1 for PCM, 3 for float, 0xFFFE for extensible |
| 2 | 2 | u16 | nChannels | the number of channels |
| 4 | 4 | u32 | nSamplesPerSec | sample frames per second, such as 44,100 or 48,000 |
| 8 | 4 | u32 | nAvgBytesPerSec | bytes per second: nSamplesPerSec × nBlockAlign for PCM |
| 12 | 2 | u16 | nBlockAlign | bytes per frame: nChannels × bytes per sample for PCM, or the codec’s block size |
| 14 | 2 | u16 | wBitsPerSample | bits per sample: 8, 16, 24, 32 or 64 for PCM and float |
| 16 | 2 | u16 | cbSize | the number of extra bytes after this field: 0, 22 for extensible, or a codec’s own data |
| 18 | 2 | u16 | wValidBitsPerSample | extensible only: how many bits of each sample are used, such as 20 in a 24-bit container |
| 20 | 4 | u32 | dwChannelMask | extensible only: which speaker each channel feeds, see channel mask |
| 24 | 16 | GUID | SubFormat | extensible only: the real format code, inside a GUID, see SubFormat |
Three sizes
The chunk size tells which version a file uses.
| Size | Structure | Used for |
|---|---|---|
| 16 | PCMWAVEFORMAT | plain PCM: the six fields up to wBitsPerSample |
| 18 or more | WAVEFORMATEX | adds cbSize; non-PCM formats should use it, and codecs put their own data after it |
| 40 | WAVEFORMATEXTENSIBLE | wFormatTag is 0xFFFE and cbSize is 22; needed for more than two channels, more than 16 bits, or a channel mask |
Readers should accept all three, and should read cbSize only when the
chunk is long enough to hold it.
Format codes
Microsoft registered hundreds of codes. These are the ones commonly met in WAV files.
| Code | Name | Audio |
|---|---|---|
| 0x0001 (1) | WAVE_FORMAT_PCM | integer PCM |
| 0x0002 (2) | WAVE_FORMAT_ADPCM | Microsoft ADPCM |
| 0x0003 (3) | WAVE_FORMAT_IEEE_FLOAT | 32 or 64-bit floating point |
| 0x0006 (6) | WAVE_FORMAT_ALAW | G.711 A-law, 8-bit codes |
| 0x0007 (7) | WAVE_FORMAT_MULAW | G.711 µ-law, 8-bit codes |
| 0x0011 (17) | WAVE_FORMAT_DVI_ADPCM | IMA ADPCM, 4 bits per sample |
| 0x0031 (49) | WAVE_FORMAT_GSM610 | GSM 6.10 speech |
| 0x0050 (80) | WAVE_FORMAT_MPEG | MPEG audio layer 1 or 2 |
| 0x0055 (85) | WAVE_FORMAT_MPEGLAYER3 | MP3 |
| 0xFFFE (65534) | WAVE_FORMAT_EXTENSIBLE | see SubFormat |
Channel mask
In an extensible format chunk, each set bit of dwChannelMask names a
speaker. The channels in each frame appear in the order of the set bits, lowest first.
A mask of 0 means the channels have no particular speaker.
| Bit | Speaker | Bit | Speaker |
|---|---|---|---|
0x1 | front left | 0x200 | side left |
0x2 | front right | 0x400 | side right |
0x4 | front centre | 0x800 | top centre |
0x8 | low frequency (LFE) | 0x1000 | top front left |
0x10 | back left | 0x2000 | top front centre |
0x20 | back right | 0x4000 | top front right |
0x40 | front left of centre | 0x8000 | top back left |
0x80 | front right of centre | 0x10000 | top back centre |
0x100 | back centre | 0x20000 | top back right |
Common masks are 0x4 for mono, 0x3 for stereo,
0x3F for 5.1 (front left, front right, centre, LFE, back left, back
right) and 0x63F for 7.1 with side speakers.
SubFormat
An extensible chunk carries its real format as a GUID. For the classic formats, the
first two bytes are the old format code and the rest is fixed:
0000xxxx-0000-0010-8000-00AA00389B71. A GUID is stored with its first
three groups little-endian, so on disk PCM is 01 00 00 00 00 00 10 00 80 00 00
AA 00 38 9B 71 and float starts 03 00 instead.
An example
The format chunk of a 24-bit, 48 kHz, 5.1 surround file.
00000000 66 6D 74 20 28 00 00 00 FE FF 06 00 80 BB 00 00 fmt (...........
00000010 00 2F 0D 00 12 00 18 00 16 00 18 00 3F 00 00 00 ./..........?...
00000020 01 00 00 00 00 00 10 00 80 00 00 AA 00 38 9B 71 .............8.q
| Field | Bytes | Value |
|---|---|---|
ckSize | 28 00 00 00 | 40 |
wFormatTag | FE FF | 0xFFFE, extensible |
nChannels | 06 00 | 6 |
nSamplesPerSec | 80 BB 00 00 | 48,000 |
nAvgBytesPerSec | 00 2F 0D 00 | 864,000 |
nBlockAlign | 12 00 | 18 bytes per frame: 6 channels × 3 bytes |
wBitsPerSample | 18 00 | 24 |
cbSize | 16 00 | 22 |
wValidBitsPerSample | 18 00 | 24 |
dwChannelMask | 3F 00 00 00 | 5.1 |
SubFormat | 16 bytes | PCM |