Every frame holds the same number of samples, except the last. Frames are independent: the codec’s state starts afresh, so a decoder can begin at any of them. The compressed samples of each channel are interleaved in order, one value per channel for each sample position.
Frame layout
| Size | Field | Meaning |
|---|---|---|
| varies | Bit stream | The Rice-coded values, ending on a byte boundary |
| 4 | CRC-32 | Of the frame’s bytes before this field, little-endian |
Bits are read from the least significant end of each byte first.
Two-parameter Rice code
Each channel keeps two parameters, k0 and k1, each with a running
sum. Both start at k = 10, with the sum set to shift_16[k].
To read one value:
- Count the 1 bits up to a 0 bit: this is the unary count.
- A count of 0 uses
k0. Otherwise subtract 1 from the count and usek1. - The value is
(count << k) + the next k bits. - When
k1was used, updatesum1andk1, then addshift_1[k0]to the value. - Update
sum0andk0with the value (in every case). - Map to a signed value:
1 + ((value >> 1) ^ ((value & 1) − 1)).
Updating a parameter
sum += value − (sum >> 4)
if k > 0 and sum < shift_16[k]: k −= 1
else if sum > shift_16[k + 1]: k += 1
The shift tables
shift_1[n] is 1 << n for n up to 31, then
0x80000000 up to entry 39, then 0xFFFFFFFF at entry 40. shift_16[n] is
shift_1[n + 4].
After the Rice code
Each signed value goes through the hybrid filter and predictor. When every channel of one sample position is done, the channels are rebuilt from their differences.