The fmt chunk says how the samples in the data chunk are encoded. BW64
takes it over from WAV unchanged: its forms grew over the years, each adding fields at the
end, and its first field decides how the rest of the file is read. It is small, so its
size is never 0xFFFFFFFF, and it must come before the data chunk.
Fields
Offsets are from the start of the chunk’s data, after the eight-byte chunk header;
straight after a 36-byte ds64 chunk the data starts at file offset 56. All
numbers are little-endian.
| 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, or tracks |
| 4 | 4 | u32 | nSamplesPerSec | sample frames per second, such as 48,000 |
| 8 | 4 | u32 | nAvgBytesPerSec | bytes per second, for buffering: nSamplesPerSec × nBlockAlign for PCM |
| 12 | 2 | u16 | nBlockAlign | bytes per frame for PCM (nChannels × bytes per sample), or the size of one block for ADPCM and other codecs |
| 14 | 2 | u16 | wBitsPerSample | bits per sample: the container size for PCM (8, 16, 24, 32), 32 or 64 for float, 4 for both ADPCMs, 0 for some codecs such as GSM and MP3 |
| 16 | 2 | u16 | cbSize | the number of bytes of format-specific data that follow (WAVEFORMATEX) |
| 18 | cbSize | bytes | extension | depends on the format code: see extensible, Microsoft ADPCM, IMA ADPCM and MPEG |
The explorer checks the block align and byte rate of PCM, float and G.711 files against the other fields, and reports a channel count or sample rate of 0.
Sizes
The chunk size tells which form a file uses.
| Size | Structure | Used for |
|---|---|---|
| 14 | WAVEFORMAT | the 1991 WAV form for formats other than PCM, without wBitsPerSample; rare |
| 16 | PCMWAVEFORMAT | plain PCM: the six fields up to wBitsPerSample |
18 + cbSize | WAVEFORMATEX | adds cbSize, and codecs put their own data after it |
| 40 | WAVEFORMATEXTENSIBLE | wFormatTag is 0xFFFE and cbSize is 22 |
Microsoft’s 1994 revision of WAV says every format other than PCM must use the extended
chunk, with cbSize present even when it is 0, and must have a
fact chunk.
Readers should accept every size, read cbSize only when the chunk is long
enough to hold it, and not trust a cbSize larger than the chunk; the
explorer reports one.
Format codes
Microsoft registered hundreds of codes, listed in its mmreg.h header and,
as of 1998, in RFC 2361. These are the ones commonly met in WAV files.
| Code | Name | Audio |
|---|---|---|
| 0x0000 | WAVE_FORMAT_UNKNOWN | unknown |
| 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, full scale 1.0 |
| 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 (Intel DVI), 4 bits per sample |
| 0x0031 (49) | WAVE_FORMAT_GSM610 | GSM 6.10 speech |
| 0x0050 (80) | WAVE_FORMAT_MPEG | MPEG-1 audio layer 1 or 2 |
| 0x0055 (85) | WAVE_FORMAT_MPEGLAYER3 | MP3 |
| 0x0092 | WAVE_FORMAT_DOLBY_AC3_SPDIF | AC-3 packed for S/PDIF |
| 0x00FF | WAVE_FORMAT_RAW_AAC1 | raw AAC |
| 0x0160 to 0x0163 | WAVE_FORMAT_MSAUDIO1, WMAUDIO2, WMAUDIO3, WMAUDIO_LOSSLESS | Windows Media Audio |
| 0x1600 | WAVE_FORMAT_MPEG_ADTS_AAC | AAC in ADTS frames |
| 0x1610 | WAVE_FORMAT_MPEG_HEAAC | HE-AAC |
| 0x674F to 0x6751 | WAVE_FORMAT_OGG_VORBIS_MODE_1, _2, _3 | Ogg Vorbis, the whole Ogg stream in the data chunk |
| 0x676F to 0x6771 | WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS, _2_PLUS, _3_PLUS | Ogg Vorbis |
| 0xF1AC | WAVE_FORMAT_FLAC | FLAC |
| 0xFFFE (65534) | WAVE_FORMAT_EXTENSIBLE | see SubFormat |
| 0xFFFF | WAVE_FORMAT_DEVELOPMENT | for codecs in development |
The values of the Ogg Vorbis modes 1 and 3 plus are confirmed in Microsoft’s headers as published in the winapi bindings; the others follow in sequence.
The other registered codes
RFC 2361 lists these as well. Each name starts WAVE_FORMAT_. Few of them
are met today.
| Code | Name | Code | Name |
|---|---|---|---|
| 0x0004 | VSELP (Compaq) | 0x0005 | IBM_CVSD |
| 0x0010 | OKI_ADPCM | 0x0012 | MEDIASPACE_ADPCM |
| 0x0013 | SIERRA_ADPCM | 0x0014 | G723_ADPCM (Antex) |
| 0x0015 | DIGISTD | 0x0016 | DIGIFIX |
| 0x0017 | DIALOGIC_OKI_ADPCM | 0x0018 | MEDIAVISION_ADPCM |
| 0x0019 | CU_CODEC (HP) | 0x0020 | YAMAHA_ADPCM |
| 0x0021 | SONARC | 0x0022 | DSPGROUP_TRUESPEECH |
| 0x0023 | ECHOSC1 | 0x0024 | AUDIOFILE_AF36 |
| 0x0025 | APTX | 0x0026 | AUDIOFILE_AF10 |
| 0x0027 | PROSODY_1612 | 0x0028 | LRC |
| 0x0030 | DOLBY_AC2 | 0x0032 | MSNAUDIO |
| 0x0033 | ANTEX_ADPCME | 0x0034 | CONTROL_RES_VQLPC |
| 0x0035 | DIGIREAL | 0x0036 | DIGIADPCM |
| 0x0037 | CONTROL_RES_CR10 | 0x0038 | NMS_VBXADPCM |
| 0x0039 | ROLAND_RDAC | 0x003A | ECHOSC3 |
| 0x003B | ROCKWELL_ADPCM | 0x003C | ROCKWELL_DIGITALK |
| 0x003D | XEBEC | 0x0040 | G721_ADPCM |
| 0x0041 | G728_CELP | 0x0042 | MSG723 |
| 0x0052 | RT24 | 0x0053 | PAC |
| 0x0059 | LUCENT_G723 | 0x0060 | CIRRUS |
| 0x0061 | ESPCM | 0x0062 | VOXWARE |
| 0x0063 | CANOPUS_ATRAC | 0x0064 | G726_ADPCM |
| 0x0065 | G722_ADPCM | 0x0066 | DSAT |
| 0x0067 | DSAT_DISPLAY | 0x0069 to 0x0081 | mostly Voxware codecs |
| 0x0080 | SOFTSOUND | 0x0082 | MSRT24 |
| 0x0083 | G729A | 0x0084 | MVI_MV12 |
| 0x0085 | DF_G726 | 0x0086 | DF_GSM610 |
| 0x0088 | ISIAUDIO | 0x0089 | ONLIVE |
| 0x0091 | SBC24 | 0x0097 | ZYXEL_ADPCM |
| 0x0098 | PHILIPS_LPCBB | 0x0099 | PACKED |
| 0x0100 | RHETOREX_ADPCM | 0x0101 | IRAT |
| 0x0112 | VIVO_SIREN | 0x0123 | DIGITAL_G723 |
| 0x0200 | CREATIVE_ADPCM | 0x0202 | CREATIVE_FASTSPEECH8 |
| 0x0203 | CREATIVE_FASTSPEECH10 | 0x0220 | QUARTERDECK |
| 0x0300 | FM_TOWNS_SND | 0x0400 | BTV_DIGITAL |
| 0x0680 | VME_VMPCM | 0x1000 to 0x1004 | Olivetti codecs |
| 0x1100 | LH_CODEC | 0x1400 | NORRIS |
| 0x1401 | ISIAUDIO (AT&T) | 0x1500 | SOUNDSPACE_MUSICOMPRESS |
| 0x2000 | DVM |
WAVE_FORMAT_EXTENSIBLE
With the format code 0xFFFE, cbSize is 22 and three fields
follow. The real format is then the SubFormat GUID. The explorer reads
them in a BW64 file as in any WAV file.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 18 | 2 | u16 | wValidBitsPerSample | how many bits of each sample carry the signal, such as 20 in a 24-bit container; for a compressed subformat the same field is wSamplesPerBlock |
| 20 | 4 | u32 | dwChannelMask | which speaker each channel feeds, see channel mask |
| 24 | 16 | GUID | SubFormat | the real format, see SubFormat |
McGill’s notes on WAV give the rules: wBitsPerSample must be the container
size, 8 × nBlockAlign / nChannels, and a multiple of 8;
wValidBitsPerSample is for information, from 1 to the container size. The
extensible form is meant for PCM above 16 bits, for more than two channels, for a
container larger than the bit depth, and whenever the speakers need naming.
Channel mask
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. The explorer reports a mask whose number of set bits differs from
the channel count.
In BW64 the mask matters less. Wikipedia’s account says BW64 no longer relies on these
18 positions, because the ADM metadata in the
axml chunk
describes the loudspeaker positions, and the
chna chunk
says which track is which; this could not be checked against the Recommendation.
| Bit | Speaker | Bit | Speaker |
|---|---|---|---|
0x1 | front left (L) | 0x200 | side left (Sl) |
0x2 | front right (R) | 0x400 | side right (Sr) |
0x4 | front centre (C) | 0x800 | top centre (Tc) |
0x8 | low frequency (LFE) | 0x1000 | top front left (Tfl) |
0x10 | back left (Ls) | 0x2000 | top front centre (Tfc) |
0x20 | back right (Rs) | 0x4000 | top front right (Tfr) |
0x40 | front left of centre (Lc) | 0x8000 | top back left (Trl) |
0x80 | front right of centre (Rc) | 0x10000 | top back centre (Trc) |
0x100 | back centre (Cs) | 0x20000 | top back right (Trr) |
The short names are libsndfile’s. 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 field is the old format code and the rest is fixed:
0000xxxx-0000-0010-8000-00AA00389B71. Microsoft names them
KSDATAFORMAT_SUBTYPE_PCM (1), _IEEE_FLOAT (3),
_ALAW (6), _MULAW (7) and _ADPCM (2).
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. Ambisonic B-format, as libsndfile writes it, uses
00000001-0721-11D3-8644-C8C1CA000000 for PCM and
00000003-0721-11D3-8644-C8C1CA000000 for float.
Microsoft ADPCM
Format code 2. cbSize is 32 with the usual seven coefficient pairs.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 18 | 2 | u16 | wSamplesPerBlock | frames each block decodes to: 2 × (nBlockAlign − 7 × nChannels) / nChannels + 2 |
| 20 | 2 | u16 | wNumCoef | the number of coefficient pairs, 7 as a rule |
| 22 | 4 each | i16, i16 | aCoef | the pairs (iCoef1, iCoef2), in 256ths |
The standard pairs are (256, 0), (512, −256), (0, 0), (192, 64), (240, 0), (460, −208) and (392, −232). How a block uses them is on Sample data.
IMA ADPCM
Format code 0x11. cbSize is 2, and the one field is
wSamplesPerBlock at offset 18: the frames each block decodes to, which
must be 2 × (nBlockAlign − 4 × nChannels) / nChannels
+ 1. libsndfile refuses a file where it is not. A 256-byte mono block gives 505 frames,
a 512-byte mono block 1,017 and a 1,024-byte stereo block 1,017.
wBitsPerSample is 4. The blocks are described on
Sample data.
MPEG
For MP3, format code 0x55, Microsoft’s MPEGLAYER3WAVEFORMAT
has cbSize 12 or more:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 18 | 2 | u16 | wID | MPEGLAYER3_ID_MPEG, 1 |
| 20 | 4 | u32 | fdwFlags | padding: 0 as ISO decides, 1 always, 2 never |
| 24 | 2 | u16 | nBlockSize | the block size in bytes: the frame length × nFramesPerBlock |
| 26 | 2 | u16 | nFramesPerBlock | MP3 frames a block, usually 1 |
| 28 | 2 | u16 | nCodecDelay | the encoder delay in samples, or 0 when unknown |
For MPEG-1 layers 1 and 2, format code 0x50, MPEG1WAVEFORMAT
has cbSize 22; wBitsPerSample is 0:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 18 | 2 | u16 | fwHeadLayer | the layer, as flags ACM_MPEG_LAYER1, LAYER2 and LAYER3 (1, 2 and 4), combined when a stream mixes layers |
| 20 | 4 | u32 | dwHeadBitrate | the bit rate in bits a second, or 0 when it varies |
| 24 | 2 | u16 | fwHeadMode | flags for stereo, joint stereo, dual channel and single channel |
| 26 | 2 | u16 | fwHeadModeExt | the joint stereo mode extensions allowed, 0x01 to 0x08; 0x0F for all |
| 28 | 2 | u16 | wHeadEmphasis | de-emphasis: 1 none, 2 50/15 ms, 3 reserved, 4 CCITT J.17 |
| 30 | 2 | u16 | fwHeadFlags | private, copyright, original, protection and MPEG-1 ID bits |
| 32 | 4 | u32 | dwPTSLow | the low 32 bits of the first frame’s presentation time stamp |
| 36 | 4 | u32 | dwPTSHigh | its top bit |
An example
The format chunk of a real RF64 file, a SciPy test file, which a BW64 file of the same audio would carry unchanged: extensible, 1 channel, 32-bit PCM, 44,100 Hz.
00000000 66 6D 74 20 28 00 00 00 FE FF 01 00 44 AC 00 00 fmt (.......D...
00000010 10 B1 02 00 04 00 20 00 16 00 20 00 00 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 | 01 00 | 1 |
nSamplesPerSec | 44 AC 00 00 | 44,100 |
nAvgBytesPerSec | 10 B1 02 00 | 176,400 |
nBlockAlign | 04 00 | 4 bytes per frame |
wBitsPerSample | 20 00 | 32 |
cbSize | 16 00 | 22 |
wValidBitsPerSample | 20 00 | 32 |
dwChannelMask | 00 00 00 00 | 0: no particular speaker |
SubFormat | 16 bytes | PCM |