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 RIFX file the samples are big-endian too:
libsndfile’s source says “RIFX signifies big-endian format for all header and data”, and
SciPy writes its samples that way.
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. Byte order changes the bytes inside each sample, not the order of the samples.
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 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 ×
nBlockAlignplus c × (nBlockAlign/nChannels).
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. Every sample wider than one byte is stored most significant byte first.
| Bits | Format code | Stored as | Silence | Range |
|---|---|---|---|---|
| 1 to 8 | 1 | unsigned integer, one byte | 128 (0x80) | 0 to 255 |
| 16 | 1 | signed integer, big-endian | 0 | −32,768 to 32,767 |
| 24 | 1 or 0xFFFE | signed integer, 3 bytes, big-endian | 0 | −8,388,608 to 8,388,607 |
| 32 | 1 or 0xFFFE | signed integer, big-endian | 0 | −2,147,483,648 to 2,147,483,647 |
| 32 | 3 or 0xFFFE | IEEE 754 single, big-endian | 0.0 | −1.0 to 1.0, louder values allowed |
| 64 | 3 or 0xFFFE | IEEE 754 double, big-endian | 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, as in any WAV file: byte order does not touch a single byte, so 8-bit RIFX audio is the same as 8-bit RIFF audio. 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; in a RIFX file the top is the first byte, so a 12-bit sample in a 16-bit container has the low four bits of its second byte zero.
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.
A worked example
The four frames at the end of the complete file example: 16-bit stereo, so 4 bytes per frame, each sample big-endian.
0000002C 00 00 00 00 7F FF 80 01 FF FF 00 01 01 00 FF 00
| Frame | Left | Right |
|---|---|---|
| 0 | 00 00 = 0 | 00 00 = 0 |
| 1 | 7F FF = 32,767, the loudest positive value | 80 01 = −32,767 |
| 2 | FF FF = −1 | 00 01 = 1 |
| 3 | 01 00 = 256 | FF 00 = −256 |
The same values in a RIFF file are stored with the two bytes of each sample the other way round.
G.711 A-law and µ-law
Format codes 6 and 7 store one byte a sample, so byte order does not affect them. Each byte is 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
should be present.
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, reading the 16-bit header sample big-endian in a RIFX file.
The order of the 4-bit codes within each byte does not change.
- Each block starts with a 4-byte header for each channel: the first sample (i16, big-endian), 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, built for this page: 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.
A header starting sample of 256 would be stored 01 00 here, where a RIFF
file has 00 01.
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; the explorer does the same, reading the 16-bit header fields
big-endian in a RIFX file.
- 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, built for this page: the mono block
00 00 10 00 64 00 32 10 00 has predictor 0, the pair (256, 0); delta 16
(00 10); iSamp1 100 (00 64) and
iSamp2 50 (00 32); 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; the 1991 specification requires it for every compressed
format. The explorer takes the frame count of an ADPCM file from it, and shows other
codecs as bytes without decoding them. How a codec’s own bit stream is affected by the
RIFX byte order is not defined anywhere; the files seen held only PCM and float.
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.
Wave lists and silence
The 1991 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”, big-endian here. 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.