Sample data
The data chunk holds the audio. It has no header of its own: how to read
it comes entirely from the format
chunk.
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: left then right for stereo, or the order of the channel mask for more channels.
Three numbers follow from the format chunk:
- bytes per frame is
nBlockAlign, which isnChannels×wBitsPerSample/ 8 for PCM and float - the number of frames is the data chunk’s size divided by
nBlockAlign - the length in seconds is the number of frames divided by
nSamplesPerSec
Sample c of frame f starts at the data start plus
f × nBlockAlign plus c × wBitsPerSample / 8.
Sample encodings
The format code and bits per sample together decide how each sample is stored. All multi-byte values are little-endian.
| Bits | Format code | Stored as | Silence | Range |
|---|---|---|---|---|
| 8 | 1 | unsigned integer | 128 | 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 | code for 0 | a 13 or 14-bit value, compressed |
8-bit PCM is the one unsigned case: subtract 128 to get a signed value. Every larger integer size is signed two’s complement.
Bit depths in between
A sample always fills whole bytes. A 20-bit recording is stored in 24-bit slots, with
wBitsPerSample set to 24. An extensible format chunk then sets
wValidBitsPerSample to 20. The real bits sit at the top of each slot and
the unused low bits are zero, so a reader that ignores the valid bit count still plays
the audio at the right level.
A worked example
The four frames at the end of the complete file example: 16-bit stereo, so 4 bytes per frame.
0000002C 00 00 00 00 FF 7F 01 80 FF FF 01 00 00 01 00 FF
| Frame | Left | Right |
|---|---|---|
| 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 |
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 extra format data. The number of frames cannot be worked out from the size, so
these files carry a fact
chunk with the frame count.
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 chunk size.