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. In a large RF64 file the data chunk’s own size is
0xFFFFFFFF, and its real size is dataSize in the
ds64 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.
Four numbers follow from the format chunk and ds64, for PCM, float and
G.711:
- bytes per frame is
nBlockAlign, which isnChannels×wBitsPerSample/ 8; - the number of frames is the data size,
dataSizefromds64when the chunk’s own size is0xFFFFFFFF, divided 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).
Offsets past 4 GB 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. A reader that ignores the valid bit count still plays the
audio at the right level.
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 RF64 files as a rule, so the explorer decodes the samples itself, up to about 16 million samples; for a longer file it shows the start.
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 | 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 |
The 24-bit file on RF64 header and chunks stores three such samples a frame, 3 bytes each.
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.
Microsoft’s 1994 revision of the WAVE specification says wBitsPerSample
should be 8 for these formats; McGill’s notes point out an example table that says 16.
They also need a fact
chunk.
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 left, right.
- 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, or 0xFFFFFFFF there and the count in
ds64’s sampleCount. The explorer takes the frame count of an
ADPCM file from it.
With the Ogg Vorbis format codes the data chunk holds a complete Ogg stream, pages
starting OggS. The explorer shows these and the other codecs as bytes and
does not decode them.
Padding
When the data size is odd, as with 8-bit or 24-bit audio when both the channel count
and the number of frames are odd, one zero pad byte follows the samples. It is not part of the audio and is not
counted in the size. This holds for a size taken from ds64 too.
Wave lists and silence
The 1991 RIFF specification also allows the samples to be held in a LIST
of type wavl, a run of data chunks and slnt chunks.
A slnt chunk is a u32 count of samples of silence, “not necessarily a
repeated zero volume or baseline sample”. A file with a wave list needs a
fact chunk. No file seen uses one; the explorer shows such a list’s items as
bytes.