WavPack rebuilds audio by running residuals back through up to 16 decorrelation passes. The passes’ settings are stored in the first sub-blocks of each block. Terms are stored in reverse order: the first item stored belongs to the last pass.
Terms and deltas (ID_DECORR_TERMS)
One byte per pass, at most 16:
| Bits | Field | Meaning |
|---|---|---|
| 0–4 | Term + 5 | Subtract 5 for the term |
| 5–7 | Delta | The weight’s step size, 0 to 7 |
| Term | Prediction |
|---|---|
| 1 to 8 | The sample that many places back |
| 17 | 2 × s[0] − s[1] |
| 18 | (3 × s[0] − s[1]) ÷ 2 |
| −1 | Stereo only. Channel A from its own history, then B from the new A |
| −2 | Stereo only. Channel B from its own history, then A from the new B |
| −3 | Stereo only. Each channel from its own history, with each result written into the other channel’s history |
Any other term value is invalid, as is a negative term in a mono block.
Weights (ID_DECORR_WEIGHTS)
A signed byte for each pass, or two in a stereo block, for channels A and B. Weights are stored from the last pass backwards, and any pass left over has a weight of 0.
weight = byte × 8
if weight > 0: weight += (weight + 64) >> 7
This gives the range ±1024. The prediction is applied and the weight adapted as follows:
apply(w, s) = (w × s + 512) >> 10
update(w, delta, source, result):
if source and result are both nonzero:
sign = (source ^ result) >> 31 (all 1s when they differ in sign, else 0)
w = (delta ^ sign) + (w − sign)
In other words, the weight moves up by delta when the signs agree, and down when they
differ. The cross-channel terms clip the weight to ±1024.
Sample histories (ID_DECORR_SAMPLES)
Each value is 16 bits, little-endian and signed, in the compact logarithmic form the
wp_exp2s function expands. Passes run from the last backwards, while bytes remain.
| Term | Values |
|---|---|
| 1 to 8 | term values per channel |
| 17 and 18 | 2 values per channel |
| −1, −2, −3 | One value for each of A and B (4 bytes) |
In stream version 0x402 with the hybrid flag, the payload starts with one or two error values. The sub-block must use all of its bytes exactly.
Stereo
With the JOINT_STEREO flag, the samples are reversed from mid and side after all passes:
R = R − (L >> 1)
L = L + R
With the FALSE_STEREO flag, a single channel is decoded and copied to both.
The sample CRC
The header’s crc is a running calculation over the final samples, with 32-bit
wrap-around:
| Block | Update for each sample |
|---|---|
| Mono | crc = crc × 3 + sample |
| Stereo | crc = crc × 9 + L × 3 + R |
| Extra bits | crc = crc × 9 + (x & 0xFFFF) × 3 + (x >> 16) |
The extra-bits form belongs to the extended stream’s own CRC, which is stored at the start of the WVX data.