A packet is a bit stream read most significant bit first. It holds a sequence of
elements, each beginning with a 3-bit type, and the last is an END element. A packet holds
frameLength samples per channel, unless a partial-frame flag says otherwise.
Element types
| Value | Name | Element | In the reference decoder |
|---|---|---|---|
| 0 | SCE | Single channel element | One channel |
| 1 | CPE | Channel pair element | Two channels |
| 2 | CCE | Coupling channel element | An error |
| 3 | LFE | Low-frequency effects element | One channel, read exactly as an SCE |
| 4 | DSE | Data stream element | Skipped |
| 5 | PCE | Program config element | An error |
| 6 | FIL | Fill element | Skipped |
| 7 | END | End of the packet | Aligns to a byte and stops |
Elements for each channel count
| Channels | Elements, in order |
|---|---|
| 1 | SCE |
| 2 | CPE |
| 3 | SCE CPE |
| 4 | SCE CPE SCE |
| 5 | SCE CPE CPE |
| 6 | SCE CPE CPE SCE |
| 7 | SCE CPE CPE SCE SCE |
| 8 | SCE CPE CPE CPE SCE |
This is the order Apple’s encoder writes. The channels fill in the order of the layout tag, so a final SCE carries the low-frequency channel in the 5.1, 6.1 and 7.1 layouts.
SCE, LFE and CPE
These three share one layout. An SCE or LFE carries one channel; a CPE carries two, called U and V, and repeats the per-channel fields.
| Bits | Field | Meaning |
|---|---|---|
| 3 | Element type | 0, 1 or 3 |
| 4 | Element instance tag | Identifies the element |
| 12 | Unused | Must be 0, or the decoder reports an error |
| 1 | partialFrame | 1 means a sample count follows |
| 2 | bytesShifted | Whole low-order bytes split off each sample, 0 to 2. The value 3 is an error |
| 1 | escapeFlag | 1 means the samples are stored uncompressed |
| 32 | numSamples | Only if partialFrame is 1: samples per channel in this packet, as two 16-bit halves, high first |
Compressed data (escapeFlag 0)
| Bits | Field | Meaning |
|---|---|---|
| 8 | mixBits | Fractional bits of the stereo matrix. Used by a CPE |
| 8 | mixRes | Signed stereo matrix weight; 0 means the channels are stored separately |
| 4 | modeU | 0 runs the predictor once; anything else adds a first-order pass first |
| 4 | denShiftU | Fractional bits of the predictor coefficients |
| 3 | pbFactorU | Scales the entropy coder’s adaptation rate; 4 is the encoder’s default |
| 5 | numU | Number of predictor coefficients |
| 16 × numU | coefsU | The signed coefficients |
| modeV to coefsV | The same five fields for V, in a CPE only | |
| varies | Shifted bits | Only if bytesShifted is not 0. See below |
| varies | Compressed samples | Entropy-coded predictor residuals for U, then for V |
Apple’s decoder reads mixBits and mixRes for an SCE as well, and ignores them. Its encoder’s
fast path writes mixBits 2 and mixRes 0, and uses 8 coefficients; its full search tries
mixRes 0 to 4 and 4 or 8 coefficients. modeU is 0 in everything the encoder
writes.
Shifted bits
Deep samples have their low bytes split off before prediction, because noise in the low
bits does not compress. Apple’s encoder uses bytesShifted 1 for 24-bit audio, 2 for 32-bit
and 0 otherwise. The bits come first, bytesShifted × 8 bits per sample, in
sample order, with U and V interleaved in a CPE. After decoding, each sample is shifted
left by that many bits and the stored bits are placed in the gap.
The number of bits predicted for each sample is
bitDepth − bytesShifted × 8, plus 1 in a CPE to make room for the stereo
matrix.
Uncompressed data (escapeFlag 1)
The samples follow directly at bitDepth bits each, with U and V interleaved in
a CPE. There is no shifting and no matrix.
DSE
| Bits | Field | Meaning |
|---|---|---|
| 3 | Element type | 4 |
| 4 | Element instance tag | Identifies the element |
| 1 | data_byte_align_flag | 1 means the stream aligns to a byte before the data |
| 8 | count | Bytes of data. 255 means another 8-bit value is added to it |
| 8 × count | Data | Skipped |
FIL
| Bits | Field | Meaning |
|---|---|---|
| 3 | Element type | 6 |
| 4 | count | Bytes of filler. 15 means an 8-bit value follows, and the count is 15 plus that value minus 1 |
| 8 × count | Filler | Skipped |
END
Three bits, the value 7. The stream then aligns to the next byte, which ends the packet.