A value from the Rice code passes through an adaptive filter and then a fixed predictor. Once every channel at a sample position is finished, the channels are rebuilt from their differences. This page follows FFmpeg’s decoder.
Hybrid filter
Each channel has its own filter of 8 taps, with weights qm, a delay line
dl and step values dx. The shift depends on the sample width, and
the rounding value is 1 << (shift − 1).
| Bytes per sample | Bits | Shift |
|---|---|---|
| 1 | 8 | 10 |
| 2 | 16 | 9 |
| 3 | 24 | 10 |
FFmpeg’s table has a fourth entry, 12, for 32-bit samples, which its decoder does not accept.
For each input value:
- Adapt the weights by the sign of the previous input. If it was negative,
qm[i] −= dx[i]; if positive,qm[i] += dx[i]; if 0, nothing. - Sum
dl[i] × qm[i]over the 8 taps, adding the rounding value, and shift right. - Shift
dx[0..3]anddl[0..3]down by one, and setdx[4..7]from the signs ofdl[4..7], with magnitudes 1, 2, 2 and 4. - Keep the input as the sign to use next time.
- The output is the input plus the shifted sum.
- Set
dl[7]to the output, anddl[6..4]to differences that cascade through the delay line.
All of the state starts at 0 at the start of a frame, apart from the weights in encrypted files.
Fixed predictor
After the filter, each value adds a first-order prediction from the channel’s last output:
| Bits | Prediction |
|---|---|
| 8 | ((p << 4) − p) >> 4 |
| 16 and 24 | ((p << 5) − p) >> 5 |
Rebuilding the channels
TTA stores differences between neighbouring channels, so once every channel of a sample position has been decoded, it rebuilds them in reverse. The last channel gains half the value of the one before it, and each earlier channel is then the next channel minus its own value:
last channel += value of the channel before ÷ 2
for each earlier channel, from the last:
channel = next channel − channel
Output
| Bits | Output |
|---|---|
| 8 | 0x80 added, to make unsigned samples |
| 16 | Signed |
| 24 | Signed |
Passwords
A file with audio format 2 is encrypted with a password. FFmpeg computes a CRC-64 of the password with the polynomial 0x42F0E1EBA9EA3693, and uses its 8 bytes, sign-extended, as the filter’s initial weights.