The data chunk holds the audio. It has no header of its own: how to read
it comes entirely from the format
chunk, which must come before it. Its 32-bit size is usually
0xFFFFFFFF, and the real size is the dataSize field of the
ds64 chunk. A small
file may give its real size in the chunk header instead; the explorer then uses it, and
reports it when ds64 disagrees.
Frames and interleaving
A frame is one sample for every channel at the same moment. Frames follow one another
in time order, and inside a frame the channels are interleaved, in the order of the
tracks that the chna
chunk numbers from 1.
Four numbers follow from the format chunk, for PCM, float and G.711:
- bytes per frame is
nBlockAlign, which isnChannels×wBitsPerSample/ 8; - the number of frames is the data size from
ds64divided bynBlockAlign; - the length in seconds is the number of frames divided by
nSamplesPerSec; - sample c of frame f starts at the data start plus
f ×
nBlockAlignplus c × (nBlockAlign/nChannels).
These offsets can pass 4 GB, so they need 64-bit arithmetic. A data size that is not a whole number of frames leaves a partial frame at the end, which the explorer reports.
Sample encodings
The format code and bits per sample together decide how each sample is stored. As in every WAV file, the least significant byte is stored first.
| Bits | Format code | Stored as | Silence | Range |
|---|---|---|---|---|
| 1 to 8 | 1 | unsigned integer | 128 (0x80) | 0 to 255 |
| 16 | 1 | signed integer | 0 | −32,768 to 32,767 |
| 24 | 1 or 0xFFFE | signed integer, 3 bytes | 0 | −8,388,608 to 8,388,607 |
| 32 | 1 or 0xFFFE | signed integer | 0 | −2,147,483,648 to 2,147,483,647 |
| 32 | 3 or 0xFFFE | IEEE 754 single | 0.0 | −1.0 to 1.0, louder values allowed |
| 64 | 3 or 0xFFFE | IEEE 754 double | 0.0 | −1.0 to 1.0, louder values allowed |
| 8 | 6 or 7 | A-law or µ-law code | see G.711 | a 13- or 14-bit value, compressed |
Up to 8 bits a sample is unsigned: subtract 128 to get a signed value. From 9 bits up
every integer is signed two’s complement. A sample always fills whole bytes, and when it
has fewer bits than its container the bits sit at the top with the rest zero: a 20-bit
recording is stored in 24-bit slots, with wValidBitsPerSample set to 20 in
an extensible format chunk.
The explorer scales every sample to −1 to 1 for the waveform: 8-bit as (b − 128) / 128, 16-bit as v / 32,768, 24-bit as v / 8,388,608, 32-bit as v / 2,147,483,648, and float as it is. Browsers do not play BW64 files as a rule, so the explorer decodes the samples itself, up to a limit, and shows the first part of a long file.
A worked example
Four frames of 16-bit stereo audio, 4 bytes per frame:
00 00 00 00 FF 7F 01 80 FF FF 01 00 00 01 00 FF
| Frame | Track 1 | Track 2 |
|---|---|---|
| 0 | 00 00 = 0 | 00 00 = 0 |
| 1 | FF 7F = 32,767, the loudest positive value | 01 80 = −32,767 |
| 2 | FF FF = −1 | 01 00 = 1 |
| 3 | 00 01 = 256 | 00 FF = −256 |
G.711 A-law and µ-law
Format codes 6 and 7 store one byte a sample, each byte a code for a 13-bit (A-law) or 14-bit (µ-law) value from ITU-T G.711. The common reference decoders, which the explorer follows, give the value on a 16-bit scale:
- A-law. a = code XOR
0x55; exponent e = (a >> 4) & 7; mantissa m = a & 15. The value is (m << 4) + 8 when e is 0, otherwise ((m << 4) +0x108) << (e − 1). It is negative when bit 7 of a is clear. The range is ±32,256: code0xD5gives +8 and0x2Agives −32,256. - µ-law. u = NOT code; e = (u >> 4)
& 7; m = u & 15. The value is
(((m << 3) +
0x84) << e) −0x84, negative when bit 7 of u is set. The range is ±32,124:0xFFgives 0,0x00gives −32,124 and0x80gives 32,124.
wBitsPerSample should be 8 for these formats, and a
fact chunk
goes with them.
IMA ADPCM
Format code 0x11 stores 4 bits a sample in blocks of
nBlockAlign bytes, each of which decodes on its own. This is how libsndfile
decodes WAV IMA ADPCM, using the shift-and-add form of the IMA’s recommended algorithm;
the explorer does the same.
- Each block starts with a 4-byte header for each channel: the first sample (i16), output as it is; the step index (u8), 0 to 88, which libsndfile clamps when it is larger; and a reserved byte, zero (libsndfile logs “IMA ADPCM synchronisation error” when it is not).
- Then come groups of 4 bytes for each channel in turn: channel 0’s 4 bytes, then channel 1’s, and so on. Each group holds 8 codes for its channel, the low nibble of each byte first.
- For each 4-bit code n: step = STEP[index]; diff = step >> 3; if n & 4, add step; if n & 2, add step >> 1; if n & 1, add step >> 2. If n & 8 the sample decreases by diff, otherwise it increases; clamp it to −32,768 to 32,767. Then index += INDEX[n & 7] and clamp the index to 0 to 88.
- A block decodes to 2 × (
nBlockAlign− 4 ×nChannels) /nChannels+ 1 frames: 505 for a 256-byte mono block, 1,017 for 512-byte mono and for 1,024-byte stereo.
INDEX, for n & 7 from 0 to 7, is −1, −1, −1, −1, 2, 4, 6, 8. STEP has 89 values: 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767.
A worked example: a mono block whose header is 00 00 00 00 (sample 0,
index 0) and whose codes start 77. The first code, 7, has step 7: 0 + 7 + 3
+ 1 = 11, so the sample is 11 and the index becomes 8. The second, also 7, has step 16:
2 + 16 + 8 + 4 = 30, giving 41 and index 16. A third 7, at step 34, adds 4 + 34 + 17 + 8
= 63, giving 104. The output starts 0, 11, 41, 104.
FFmpeg’s general IMA decoder works out the difference as ((2n′ + 1) × step) >> 3 instead, which can differ in rounding.
Microsoft ADPCM
Format code 2 also stores 4 bits a sample in blocks of nBlockAlign bytes,
for one or two channels. The coefficient pairs are in the
format chunk. This is
how libsndfile decodes it, and the explorer with it:
- The block header holds, for each channel,
bPredictor(u8, an index into the coefficient pairs),iDelta(i16),iSamp1(i16) andiSamp2(i16): 7 bytes a channel, all of one field before the next, so a stereo header is 2 + 4 + 4 + 4 = 14 bytes. - The first two output frames are
iSamp2, theniSamp1. - Then come 4-bit codes, the high nibble of each byte first; with two channels the nibbles alternate between them.
- For each code: predict = (sample1 × coef1 + sample2 × coef2) >> 8; take n as signed (8 to 15 mean −8 to −1); the new sample is predict + n × delta, clamped to 16 bits; then delta = (ADAPT[n unsigned] × delta) >> 8, at least 16; sample2 = sample1; sample1 = the new sample.
- A block decodes to 2 × (
nBlockAlign− 7 ×nChannels) /nChannels+ 2 frames: 500 for a 256-byte mono block.
ADAPT is 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230.
A worked example: the mono block 00 10 00 64 00 32 00 10 00 has predictor
0, the pair (256, 0); delta 16; iSamp1 100 and iSamp2 50; and
the codes 1, 0, 0, 0. The output is 50, 100, then 100 + 1 × 16 = 116, and 116 three
more times, since a code of 0 adds nothing and the delta stays at its floor of 16.
Compressed formats
For ADPCM and other codecs, the data chunk is a run of blocks of
nBlockAlign bytes, each decoding to a fixed number of frames given in the
codec’s format data. The last block is often shorter than nBlockAlign and
holds fewer frames. The number of frames cannot be worked out from the size, so these
files carry a fact
chunk with the exact count, and the explorer takes the frame count of an ADPCM file from
it. Other codecs, such as MP3 or Ogg Vorbis, are shown as bytes and not decoded.
Padding
When the data chunk’s size is odd, as with 8-bit mono or 24-bit mono audio with an odd
number of frames, one zero pad byte follows the samples. It is not part of the audio and
is not counted in the size, whether that size is in the chunk header or in
ds64.
Wave lists and silence
The 1991 WAV specification also allows the samples to be held in a LIST
of type wavl, a run of data chunks and slnt
chunks, each slnt a u32 count of samples of silence. No source used here
mentions it in BW64 files; the explorer shows such a list’s items as bytes.