Enhanced AC-3 keeps the AC-3 filter bank, exponents and bit allocation, and adds four tools, each switched on in the audio frame or block: the Adaptive Hybrid Transform for steady sounds, spectral extension and enhanced coupling for cheaper high frequencies, and transient pre-noise processing after the transform. This page follows clause E.2 of ETSI TS 102 366.
Adaptive Hybrid Transform (AHT)
For steady signals a second transform, a six-point DCT-II across the six blocks of a
frame, is applied to each bin’s MDCT coefficients, so one bin covers 1,536 samples
instead of 256. It needs six-block frames (ahte exists only then) and
exponents sent once in the frame: a channel may use it (chahtinu) only if
exactly one of its six exponent strategies is new (so block 0), the coupling channel
(cplahtinu) only if coupling is on in all six blocks and its strategy or
exponents are new in just one block, and the LFE likewise (lfeahtinu).
All six blocks’ mantissas for such a channel come in block 0, where the channel’s
mantissas would be.
High-efficiency bit allocation
The bit allocation runs as in AC-3 up to the masking curve and its delta adjustments,
but the last look-up uses hebaptab instead of baptab, giving
a pointer from 0 to 19:
| Address | hebap | Address | hebap | Address | hebap |
|---|---|---|---|---|---|
| 0 to 7 | same as the address | 19–22 | 11 | 35–38 | 15 |
| 8–11 | 8 | 23–26 | 12 | 39–42 | 16 |
| 12–14 | 9 | 27–30 | 13 | 43–46 | 17 |
| 15–18 | 10 | 31–34 | 14 | 47–54 | 18 |
| 55–63 | 19 |
| hebap | Quantiser | Bits | hebap | Quantiser | Levels | Bits |
|---|---|---|---|---|---|---|
| 0 | none | 0 | 10 | symmetric + GAQ | 31 | 5 |
| 1 | vector, 4 rows | 2 for six | 11 | symmetric + GAQ | 63 | 6 |
| 2 | vector, 8 rows | 3 for six | 12 | symmetric + GAQ | 127 | 7 |
| 3 | vector, 16 rows | 4 for six | 13 | symmetric + GAQ | 255 | 8 |
| 4 | vector, 32 rows | 5 for six | 14 | symmetric + GAQ | 511 | 9 |
| 5 | vector, 128 rows | 7 for six | 15 | symmetric + GAQ | 1,023 | 10 |
| 6 | vector, 256 rows | 8 for six | 16 | symmetric + GAQ | 2,047 | 11 |
| 7 | vector, 512 rows | 9 for six | 17 | symmetric + GAQ | 4,095 | 12 |
| 8 | symmetric + GAQ | 3 (7 levels) | 18 | symmetric + GAQ | 16,383 | 14 |
| 9 | symmetric + GAQ | 4 (15 levels) | 19 | symmetric + GAQ | 65,535 | 16 |
Vector quantisation
A bin with hebap 1 to 7 carries one index for all six of its values. The index picks a
row of six 16-bit two’s complement values (fractions of 32,768) from the table for that
hebap: Tables E.3.1 to E.3.7, with 4, 8, 16, 32, 128, 256 and 512 rows, 956 in all. The
encoder sends the row nearest its six values. The tables are printed in full in Annex
E.3 of TS 102 366, and this site’s decoder holds them in
explorer/formats/shared/audio/ac3-vq.js; the first row of the hebap 1 table,
for example, is 1BFF 1283 0452 10AD 28AC 12D4.
Gain-adaptive quantisation (GAQ)
Bins with hebap 8 or more carry six separate mantissas. Each AHT channel sends a 2-bit
mode (chgaqmod, cplgaqmod or lfegaqmod) and then,
for the bins in the mode’s range, gains: a gain Gk of 2 or 4 lets the encoder send the
small values of that bin with fewer bits.
| gaqmod | Gains | Bins with a gain | Gain words |
|---|---|---|---|
| 0 | no GAQ | none | none |
| 1 | Gk 1 or 2 | hebap 8 to 11 | 1 bit a bin: 0 for 1, 1 for 2 |
| 2 | Gk 1 or 4 | hebap 8 to 16 | 1 bit a bin: 0 for 1, 1 for 4 |
| 3 | Gk 1, 2 or 4 | hebap 8 to 16 | 5 bits for three bins: M1 = g / 9, M2 = (g % 9) / 3, M3 = g % 3; 0, 1, 2 mean 1, 2, 4 |
The gains come first, in bin order, then the mantissas of every bin: nothing for hebap 0, one index for 1 to 7, six values for 8 to 19. With m bits for the hebap:
| Gk = 1 (or no gain) | Gk = 2: small | Gk = 2: large | Gk = 4: small | Gk = 4: large | |
|---|---|---|---|---|---|
| Bits | m | m − 1 | m − 1 more | m − 2 | m more |
| Levels | 2m − 1 | 2m−1 − 1 | 2m−1 | 2m−2 − 1 | 2m |
| Step | 2 / (2m − 1) | 1 / (2m−1) | 1 / (2m−1 − 1) | 1 / (2m−1) | 3 / (2m+1 − 2) |
With a gain of 2 or 4, a small codeword equal to the most negative value (100…0) is a tag: a large mantissa follows. A small value is divided by Gk. A large one, and every value coded with Gk = 1, is remapped as y = x + a·x + b, x being the codeword as a signed fraction and a and b 16-bit fractions; b depends on the sign of x.
| hebap | Gk 1: a (b = 0) | Gk 2: a | Gk 2: b, x ≥ 0 | Gk 2: b, x < 0 | Gk 4: a | Gk 4: b, x ≥ 0 | Gk 4: b, x < 0 |
|---|---|---|---|---|---|---|---|
| 8 | 1249 | D555 | 4000 | EAAB | EDB7 | 2000 | FB6E |
| 9 | 0889 | C925 | 4000 | D249 | E666 | 2000 | ECCD |
| 10 | 0421 | C444 | 4000 | C889 | E319 | 2000 | E632 |
| 11 | 0208 | C211 | 4000 | C421 | E186 | 2000 | E30C |
| 12 | 0102 | C104 | 4000 | C208 | E0C2 | 2000 | E183 |
| 13 | 0081 | C081 | 4000 | C102 | E060 | 2000 | E0C1 |
| 14 | 0040 | C040 | 4000 | C081 | E030 | 2000 | E060 |
| 15 | 0020 | C020 | 4000 | C040 | E018 | 2000 | E030 |
| 16 | 0010 | C010 | 4000 | C020 | E00C | 2000 | E018 |
| 17 | 0008 | no gains | |||||
| 18 | 0002 | no gains | |||||
| 19 | 0000 | no gains | |||||
The inverse DCT
The six values X(k, j) of bin k become the bin’s MDCT coefficient in each block m:
C(k, m) = √2 × Σj=0…5 Rj × X(k, j) × cos(π(2m + 1)j / 12), R0 = 1/√2, Rj = 1 otherwise
then each is scaled by the bin’s exponent and goes on through coupling, rematrixing and the filter bank as in AC-3. (The radicals in this equation are hard to read in the published PDF; the form here is the one FFmpeg’s decoder implements.)
Spectral extension (SPX)
Above a chosen frequency, a channel’s coefficients are not sent but made up: lower coefficients are copied up, blended with noise, and scaled to a coarse envelope the encoder sends. Bins 25 to 228 form 17 sub-bands of 12 bins:
| Sub-band | Bins | spxbegf | spxendf | Sub-band | Bins | spxbegf | spxendf |
|---|---|---|---|---|---|---|---|
| 0 | 25–36 | 9 | 133–144 | 6 | 3 | ||
| 1 | 37–48 | 10 | 145–156 | ||||
| 2 | 49–60 | 0 | 11 | 157–168 | 7 | 4 | |
| 3 | 61–72 | 1 | 12 | 169–180 | |||
| 4 | 73–84 | 2 | 13 | 181–192 | 5 | ||
| 5 | 85–96 | 3 | 0 | 14 | 193–204 | ||
| 6 | 97–108 | 4 | 1 | 15 | 205–216 | 6 | |
| 7 | 109–120 | 5 | 2 | 16 | 217–228 | ||
| 8 | 121–132 | (17) | from 229 | 7 |
spx_begin_subbnd = spxbegf < 6 ? spxbegf + 2 : spxbegf × 2 − 3 (first synthesised sub-band)
spx_end_subbnd = spxendf < 3 ? spxendf + 5 : spxendf × 2 + 3 (one past the last)
copy start = sub-band spxstrtf (bin 25 + 12 × spxstrtf)
Sub-bands are joined into bands by spxbndstrc, 1 joining a sub-band to the
band before. The default structure, used when the first block with spectral extension
sends none, joins sub-bands 8, 10, 12, 14 and 16 to the ones before them. With coupling
also in use, coupling ends where spectral extension begins (cplendf is then
derived from spxbegf: spxbegf − 2, or spxbegf × 2 − 7, and may be
negative), and a channel in spectral extension but not in coupling ends at the start bin
of spx_begin_subbnd, sending no chbwcod.
Coordinates are a 4-bit exponent and a 2-bit mantissa with an implied leading 1, ranged
by mstrspxco (×1, ×2−3, ×2−6, ×2−9):
spxco = (spxcoexp == 15 ? spxcomant / 4 : (spxcomant + 4) / 8) × 2^−(spxcoexp + 3 × mstrspxco)
For each band the decoder then:
- copies coefficients from the copy start upwards into the band, wrapping back to the copy start when it reaches the first synthesised bin (a band that would not fit is started again from the copy start, and marked as a wrap point);
- measures the band’s RMS energy;
- if the channel has spectral extension attenuation (
chinspxatten), applies a five-bin notch centred on the first synthesised bin and on each wrap point, the three values from Table E.2.12 forspxattencodmirrored about the centre (a0, a1, a2, a1, a0); - blends with zero-mean, unit-variance noise: with nratio = clamp((first bin of the band + size / 2) / (bin of spx_end_subbnd) − spxblnd / 32, 0, 1), each coefficient becomes tc × √(1 − nratio) + noise × RMS × √nratio;
- scales the result by spxco × 32.
| Code | a0 | a1 | a2 | Code | a0 | a1 | a2 |
|---|---|---|---|---|---|---|---|
| 0 | 0.954841604 | 0.911722489 | 0.870550563 | 16 | 0.455861244 | 0.207809474 | 0.094732285 |
| 1 | 0.911722489 | 0.831237896 | 0.757858283 | 17 | 0.435275282 | 0.189464571 | 0.082469244 |
| 2 | 0.870550563 | 0.757858283 | 0.659753955 | 18 | 0.415618948 | 0.172739110 | 0.071793647 |
| 3 | 0.831237896 | 0.690956440 | 0.574349177 | 19 | 0.396850263 | 0.157490131 | 0.062500000 |
| 4 | 0.793700526 | 0.629960525 | 0.500000000 | 20 | 0.378929142 | 0.143587294 | 0.054409410 |
| 5 | 0.757858283 | 0.574349177 | 0.435275282 | 21 | 0.361817309 | 0.130911765 | 0.047366143 |
| 6 | 0.723634619 | 0.523647061 | 0.378929142 | 22 | 0.345478220 | 0.119355200 | 0.041234622 |
| 7 | 0.690956440 | 0.477420802 | 0.329876978 | 23 | 0.329876978 | 0.108818820 | 0.035896824 |
| 8 | 0.659753955 | 0.435275282 | 0.287174589 | 24 | 0.314980262 | 0.099212566 | 0.031250000 |
| 9 | 0.629960525 | 0.396850263 | 0.250000000 | 25 | 0.300756259 | 0.090454327 | 0.027204705 |
| 10 | 0.601512518 | 0.361817309 | 0.217637641 | 26 | 0.287174589 | 0.082469244 | 0.023683071 |
| 11 | 0.574349177 | 0.329876978 | 0.189464571 | 27 | 0.274206245 | 0.075189065 | 0.020617311 |
| 12 | 0.548412490 | 0.300756259 | 0.164938489 | 28 | 0.261823531 | 0.068551561 | 0.017948412 |
| 13 | 0.523647061 | 0.274206245 | 0.143587294 | 29 | 0.250000000 | 0.062500000 | 0.015625000 |
| 14 | 0.500000000 | 0.250000000 | 0.125000000 | 30 | 0.238710401 | 0.056982656 | 0.013602353 |
| 15 | 0.477420802 | 0.227930622 | 0.108818820 | 31 | 0.227930622 | 0.051952369 | 0.011841536 |
Enhanced coupling
Enhanced coupling can start lower than ordinary coupling, from bin 13. Its 22 sub-bands
are six bins wide up to bin 36 and twelve above; sub-bands 0 to 7 always stand alone,
and ecplbndstrc can join the higher ones, with a default structure (Table
E.1.13) that joins sub-bands 9, 11, 13, 15, 16, 17, 19, 20 and 21 to the ones before
them.
| Sub-band | Bins | ecplbegf | ecplendf | Sub-band | Bins | ecplbegf | ecplendf |
|---|---|---|---|---|---|---|---|
| 0 | 13–18 | 0 | 11 | 121–132 | 9 | 4 | |
| 1 | 19–24 | 12 | 133–144 | 10 | 5 | ||
| 2 | 25–30 | 1 | 13 | 145–156 | 11 | 6 | |
| 3 | 31–36 | 14 | 157–168 | 12 | 7 | ||
| 4 | 37–48 | 2 | 15 | 169–180 | 8 | ||
| 5 | 49–60 | 3 | 16 | 181–192 | 13 | 9 | |
| 6 | 61–72 | 4 | 17 | 193–204 | 10 | ||
| 7 | 73–84 | 5 | 0 | 18 | 205–216 | 14 | 11 |
| 8 | 85–96 | 6 | 1 | 19 | 217–228 | 12 | |
| 9 | 97–108 | 7 | 2 | 20 | 229–240 | 15 | 13 |
| 10 | 109–120 | 8 | 3 | 21 | 241–252 | 14 | |
| (22) | from 253 | 15 |
ecpl_begin_subbnd = ecplbegf < 3 ? ecplbegf × 2 : ecplbegf < 13 ? ecplbegf + 2 : ecplbegf × 2 − 10
ecpl_end_subbnd = ecplendf + 7; with spectral extension: spxbegf < 6 ? spxbegf + 5 : spxbegf × 2
Each coupled channel has a 5-bit amplitude per band, sent in the first block with
enhanced coupling and when ecplparam1e is 1. Codes 0 to 30 are 0 dB down to
−45 dB in steps of about 1.5 dB (Table E.2.10: a mantissa 0x20, 0x1B, 0x17, 0x13 or 0x10
over 32, shifted right by 0 to 7), and 31 is silence:
amp = ecplamp == 31 ? 0 : (ecplampmanttab[ecplamp] / 32) × 2^−ecplampexptab[ecplamp]
chmant[ch][bin] = ecplmant[bin] × amp[ch][band of bin]
| ecplamp | Exponent | Mantissa | Gain | ecplamp | Exponent | Mantissa | Gain |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 0x20 | 0 dB | 16 | 3 | 0x10 | −24.1 dB |
| 1 | 0 | 0x1B | −1.5 dB | 17 | 4 | 0x1B | −25.6 dB |
| 2 | 0 | 0x17 | −2.9 dB | 18 | 4 | 0x17 | −27.0 dB |
| 3 | 0 | 0x13 | −4.5 dB | 19 | 4 | 0x13 | −28.6 dB |
| 4 | 0 | 0x10 | −6.0 dB | 20 | 4 | 0x10 | −30.1 dB |
| 5 | 1 | 0x1B | −7.5 dB | 21 | 5 | 0x1B | −31.6 dB |
| 6 | 1 | 0x17 | −8.9 dB | 22 | 5 | 0x17 | −33.0 dB |
| 7 | 1 | 0x13 | −10.5 dB | 23 | 5 | 0x13 | −34.6 dB |
| 8 | 1 | 0x10 | −12.0 dB | 24 | 5 | 0x10 | −36.1 dB |
| 9 | 2 | 0x1B | −13.5 dB | 25 | 6 | 0x1B | −37.6 dB |
| 10 | 2 | 0x17 | −14.9 dB | 26 | 6 | 0x17 | −39.0 dB |
| 11 | 2 | 0x13 | −16.6 dB | 27 | 6 | 0x13 | −40.7 dB |
| 12 | 2 | 0x10 | −18.1 dB | 28 | 6 | 0x10 | −42.1 dB |
| 13 | 3 | 0x1B | −19.5 dB | 29 | 7 | 0x1B | −43.6 dB |
| 14 | 3 | 0x17 | −20.9 dB | 30 | 7 | 0x17 | −45.0 dB |
| 15 | 3 | 0x13 | −22.6 dB | 31 | – | 0x00 | silence |
Every channel but the first coupled one also has a rsvdfieldse bit; when it
is 1, 9 × (bands − 1) reserved bits follow, and each such channel ends with one more
reserved bit. TS 102 366 defines only the amplitudes; whatever these reserved fields
carry is not public, and a decoder skips them.
Transient pre-noise processing
Coarse quantisation smears a sharp attack backwards in time, as noise before it. The
encoder finds the transient and sends, per channel and frame
(chintransproc), its position transprocloc (in units of four
samples from the frame’s first output sample, possibly in a later frame) and a length
transproclen in samples. The decoder overwrites the noisy stretch with a
copy of earlier, clean audio:
TC1 = 256, TC2 = 128
transloc = 4 × transprocloc; pnlen = transloc − (start of the block before the transient’s block)
total = pnlen + transproclen + TC1
synth[s] = pcm[transloc − (2 × TC1 + 2 × pnlen) + s] s = 0 … 2 × TC1 + pnlen − 1
from transloc − total: cross-fade from the original to synth over TC1 samples,
then synth, then cross-fade back over the last TC2 samples before transloc
Any pair of constant-amplitude cross-fade windows will do; Hann windows work well.