Other
- §4.3.7.1 pitch post-filter response (celt_post_filter)
- §4.3.4.2 PVQ shape read path (index read + unit-L2 normalization)
- fix clippy assertions-on-constants in celt_deemphasis test
- §4.3.7.2 de-emphasis filter (round 48)
- §4.3.7 inverse-MDCT overlap window (round 47)
- §4.1.2 public two-step range-coder symbol API (ec_decode + ec_dec_update)
- §4.3.2.1 per-LM inter-mode (alpha, beta) prediction coefficients (round 45)
- §4.3.4.3 spreading rotation (round 44)
- §4.3.4.2 PVQ index-to-vector decode (round 43)
- clean-room round 42 — §4.3.2.2 fine-energy quantization
- §4.3.4.2 PVQ codebook-size function V(N, K) (round 41)
- §4.3.3 1/64-step interpolated allocation search (round 40)
- §4.3.3 static allocation table (Table 57) (round 39)
- §4.5.3 normative + recommended-non-normative transition table (round 38)
- drop release-plz.toml — use release-plz defaults across the workspace
- RFC 6716 Appendix B self-delimiting framing (round 37)
- §4.3.3 per-band allocation-trim offsets (round 36)
- §4.3.3 per-band minimum-allocation vector (round 35)
- §4.3.3 reservation block (round 34)
- §4.3.3 band-boost decoder (round 33)
- §4.3.3 allocation-trim Table-58 PDF + signalling gate (round 32)
- §4.3.3 CACHE_CAPS50 per-band maximum-allocation parameter surface (round 31)
- §4.3.3 LOG2_FRAC_TABLE intensity-stereo reservation parameter surface (round 30)
- §4.3.2.1 CELT coarse-energy Laplace-model parameter surface (round 29)
- §4.5.1.4 redundant-CELT-frame decode parameters + cross-lap placement (round 28)
- §4.5.2 SILK + CELT state-reset policy across mode transitions (round 27)
- §4.5.1 CELT redundancy / mode-transition side information (round 26)
Added
-
Clean-room round 50 (2026-06-15): §4.3.7.1 pitch post-filter
response (celt_post_filter). The pitch comb filter the CELT decoder
applies to the inverse-MDCT / overlap-add output (§4.3.7) just before
the round-48 §4.3.7.2 de-emphasis; the post-filter parameters landed
incelt_headerat round 20, this round owns their application. RFC
6716 §4.3.7.1 (p. 121) states the five-tap symmetric comb response
y(n) = x(n) + G*(g0*y(n-T) + g1*(y(n-T+1)+y(n-T-1)) + g2*(y(n-T+2)+y(n-T-2)))— recursive over past output samples (state
= the trailingT + 2outputs, carried across frames, reset only on a
§4.5.2 CELT state reset). The ASCII equation prints each pair term with
a repeated index; the symmetricy(n-T±1)/y(n-T±2)reading is the
only one consistent with the "g0, g1, g2" symmetric-tap-set prose, and
the module documents the slip. New surface:POST_FILTER_TAPS(the
three §4.3.7.1(g0, g1, g2)tapsets) +tapset_coefficients+
post_filter_gain(G = 3*(gain_index+1)/32) + the formula constants;
PostFilterCoeffs { period, a0, a1, a2 }(gain folded into each tap)
vianew/from_header;PostFiltercarrying the output history
(new/reset/step/process_in_place/process/
process_gain_transition— the §4.3.7.1 squared-MDCT-window gain
crossfade pushing the mixed value into the shared feedback history per
"interpolated one at a time"); the standalonecrossfade_transition;
andPostFilterError::{TapsetOutOfRange, PeriodOutOfRange, GainIndexOutOfRange, OutputBufferTooSmall, TransitionLengthMismatch, Window}withFrom<MdctWindowError>. Twenty-six new unit tests (1064
lib tests, up from 1038; 20 integration unchanged): the tapset decimalsg2 = 0for tapsets 1/2, the gain formula + monotonicity, the
gain-fold, period bounds, header round-trip, fresh-history
pass-through, a hand-expanded impulse response placing each tap at its
exact lag, impulse-response symmetry aboutT, history carry across
split blocks, the buffer paths,reset, the gain-transition endpoints- old==new identity + length checks, the standalone crossfade
convexity, and every errorDisplay. Provenance: §4.3.7.1 comb
response, tapsets, gain map, and squared-window transition rule in the
stageddocs/audio/opus/rfc6716-opus.txt; the squared window reuses
the round-47celt_mdct_window; no external library source consulted.
-
Clean-room round 49 (2026-06-15): §4.3.4.2 PVQ shape read path
(celt_pvq_decode). Composes the three steps RFC 6716 §4.3.4.2
(p. 116–117) states in sequence: the up-front
i = ec_dec_uint(V(N, K))codeword-index read
(RangeDecoder::dec_uint), the round-43 five-step index-to-vector
walk, and the final normalization — "The decoded vector X is then
normalized such that its L2-norm equals one." New surface:
pvq_unit_normalize(&[i32], &mut [f64])(the unit-L2 scaling, with
theK = 0no-direction case left all-zeros);decode_pvq_shape(rd, n, k) -> Vec<f64>anddecode_pvq_shape_into(rd, n, k, &mut [f64])
(the full read path returning the unit-normf64shape the §4.3.4.3
spreading rotation operates on and §4.3.6 denormalization later
scales by the band energy); andPvqShapeError::{CodebookSize, RangeDecoder, PulseVector, OutputBufferTooSmall}withFrom<PvqVError>
/From<PvqDecodeError>. Fourteen new unit tests (1038 lib tests, up
from 1024; 20 integration unchanged): the unit-L2 norm over every
codeword of(N, K) ∈ 1..=6 × 1..=6, direction preservation,
single-pulse ±1, the zero-vector carve-out, the buffer paths;
decode_pvq_shape↔decode_pvq_vector+pvq_unit_normalize
consistency from fixed buffers, the_intoparity, theK = 0
no-bit-consumption edge,N = 1signed-unit, codebook-size error
propagation, and the error conversions/Display. -
Clean-room round 48 (2026-06-14): §4.3.7.2 de-emphasis filter
(celt_deemphasis). The final stage of the CELT decode pipeline,
applied after the inverse MDCT + overlap-add (§4.3.7) and the
§4.3.7.1 pitch post-filter. RFC 6716 §4.3.7.2 (p. 122) states it as
the inverse of the encoder's pre-emphasis filter,
1/A(z) = 1/(1 - alpha_p*z^-1)withalpha_p = 0.8500061035;
inverting the one-pole transfer function gives the time-domain
recurrencey(n) = x(n) + alpha_p*y(n-1). The single state element
carries across frame boundaries (the recurrence is continuous over
the whole stream, reset only on a §4.5.2 CELT state reset). New
surface:DEEMPHASIS_ALPHA_P = 0.8500061035constant;
DeemphasisFilterwithnew()/with_memory(mem)/memory()/
reset()/step(x)(one-sample recurrence) /
process_in_place(&mut [f64])/process(input, output); and
DeemphasisError::OutputBufferTooSmall. Fifteen new unit tests
(1024 lib tests, up from 1009; 20 integration unchanged): the
alpha_pconstant + stability bound, fresh-filter zero memory,
first-sample pass-through, hand-computed recurrence, constant-input
convergence to the DC gain1/(1 - alpha_p), the
pre-emphasis-round-trip inverse property, memory carry across split
blocks,with_memoryseeding,reset, theprocess_in_place↔
stepparity, output-buffer write + over-long acceptance +
short-buffer rejection (state unchanged on error), empty-input
no-op, and the errorDisplay. Provenance: §4.3.7.2 transfer
function +alpha_pconstant in the staged
docs/audio/opus/rfc6716-opus.txt; the recurrence is the textbook
inverse of the stated one-pole filter; no reference source
consulted. -
Clean-room round 47 (2026-06-14): §4.3.7 inverse-MDCT overlap
window (celt_mdct_window). RFC 6716 §4.3.7 (p. 121) states the
basic full-overlap 240-sample Vorbis-derived window directly:
W(n) = sin( (pi/2) * sin( (pi/2) * (n + 1/2) / L )^2 )(the2
superscript squares the inner sine — the only nesting that
satisfies the §4.3.7 power-complementarity / Princen-Bradley
requirementW(n)^2 + W(L-1-n)^2 = 1, which the module proves
algebraically and pins in tests). New surface:window_tap(n, len)
(the amplitude tap for window lengthL = len),basic_window()
(the 240-tap full-overlap window),mdct_window(overlap)(the
§4.3.7 "low-overlap" ramp for an arbitrary even overlap, built by
evaluating the same shape withL = overlap— the "zero-pad +
insert ones in the middle" construction expressed as a per-overlap
rising ramp),celt_overlap_window()(the fixed CELT 120-sample
overlap at 48 kHz — the 2.5 ms look-ahead "fixed by the decoder",
RFC 6716 §1), constantsBASIC_WINDOW_LEN = 240/
CELT_OVERLAP_48K = 120, andMdctWindowError::{PositionOutOfRange, ZeroLength, OddOverlap}. Eighteen new unit tests (1009 lib tests,
up from 991; 20 integration unchanged): the formula spot-check,
unit-interval bound, monotone-increasing ramp, power complementarity
on both the basic window and arbitrary overlaps, the half-power
centre pair, endpoint shape,mdct_window↔window_tapparity,
thecelt_overlap_window↔mdct_window(120)parity, and every
error path. The inverse MDCT itself and the weighted overlap-add
that consumes this ramp run at the §4.3.7 consumer site.
Provenance: §4.3.7 window equation + low-overlap narrative + §1
fixed-overlap statement, all in the staged
docs/audio/opus/rfc6716-opus.txt; no reference source consulted. -
Clean-room round 46 (2026-06-13): public two-step range-coder
symbol APIRangeDecoder::ec_decode(ft) -> fsand
RangeDecoder::ec_dec_update(fl, fh, ft)per RFC 6716 §4.1.2,
promoting the previously-privatedecode/dec_updatehelpers to a
validated public surface.ec_decodecomputes the §4.1.2 symbol
proxyfs = ft - min(val/(rng/ft) + 1, ft)and rejectsft == 0
(division by zero) by latching the sticky error flag;ec_dec_update
narrows the range to the chosen symbol's[fl, fh)sub-interval of
[0, ft)and rejects malformed tuples (ft == 0,fh > ft,
fl >= fh) with the same error-latch-and-no-op guard, so a corrupt
search result cannot underflowvalor zerorng. This is the
generic symbol path required when the frequency model is computed at
run time rather than baked into a fixedicdf[]table — the building
block for the deferred §4.3.2.1 CELT coarse-energy Laplace decoder and
the §4.3.3 allocation interpolation search. Five new unit tests (991
lib tests, up from 986; 20 integration unchanged): split-path ↔
fused-dec_icdflockstep over a uniform 8-way PDF, split-path ↔
dec_uintlockstep in the small (ftb <= 8) regime,fs ∈ [0, ft)
forftup to2**16,ec_decode(0)error latch, and the three
malformed-tuple rejections forec_dec_update. Provenance: §4.1.2
prose (theec_decode/ec_dec_updateequations) is fully normative
in the stageddocs/audio/opus/rfc6716-opus.txt; no reference source
was consulted. Note: the §4.3.2.1ec_laplace_decodecontrol flow
remains a docs gap — the RFC defers its algorithm tolaplace.cin
the Appendix A tarball (reference source, off-limits to the
Implementer); this round lands the documented primitive that decoder
will consume once a clean-room §4.3.2.1 Laplace trace is staged. -
Clean-room round 45 (2026-06-12): RFC 6716 §4.3.2.1 per-LM
inter-mode(alpha, beta)coarse-energy prediction coefficients,
closing the round-29 deferral.celt_e_prob_modelgains
INTER_PRED_ALPHA_Q15 = [29440, 26112, 21248, 16384]and
INTER_PRED_BETA_Q15 = [30147, 22282, 12124, 6554](Q15 numerators
againstQ15_ONE = 32768, indexed byLM = log2(frame_size/120) ∈ 0..=3), theEnergyPredCoef { alpha_q15, beta_q15 }pair type with
exactalpha()/beta()binary-fraction float views, and the
range-checkedenergy_pred_coef(lm, mode)accessor unifying the
§4.3.2.1 p. 108 intra carve-out ((0, 4915), LM-independent) with
the per-LM inter pairs. Provenance: the RFC prose states the inter
coefficients "depend on the frame size in use" and defers the
numbers to the normative Appendix A reference code; the values are
numeric facts read from thepred_coef[4]/beta_coef[4]
declarations inquant_bands.cof the Appendix A source embedded in
the stageddocs/audio/opus/rfc6716-opus.txt(extracted via the
RFC's own §A.1 procedure, tarball SHA-1 verified against §A.1;
§A.2 keeps the in-document code normative;beta_intra = 4915in
the same file confirms the p. 108 intra constant). Ten new unit
tests (986 lib tests, up from 976; 20 integration unchanged): value
pins, the exact-halfLM = 3alpha, strict monotone decrease of
both arrays in LM, inter-beta > intra-beta, accessor↔table
agreement, intra LM-independence,lmrange rejection in both
modes, exact float views, and the doc-comment approximations.
Follow-up note: the same Appendix A grounding stages the normative
pulse-cache construction (rate.c), making the §4.3.4.1
cache-bits50/cache-index50run-layout gap recorded in round 44
reachable for a future round. -
Clean-room round 44 (2026-06-11): RFC 6716 §4.3.4.3 spreading
(rotation) — a newcelt_spreadingmodule applying the §4.3.4.3
anti-tonal rotation to the §4.3.4.2-decoded shape vector. Implements
the RFC prose verbatim: the Table 56 per-frame "spread" symbol
(decode_spread, PDF{7, 2, 21, 2}/32asSPREAD_PDF/
SPREAD_ICDF/SPREAD_FTB = 5); the Table 59spread → f_rmap
(spread_f_r/SPREAD_F_R: 0 → infinite/no rotation, 1 → 15,
2 → 10, 3 → 5); the rotation gaing_r = N/(N + f_r*K)
(rotation_gain) and angletheta = pi*g_r^2/4(rotation_angle,
composed asspread_theta); the back-and-forth adjacent-pair 2-D
rotation series (rotate_in_place, orthogonal /
L2-norm-preserving); the multi-block interleave stride
round(sqrt(N/nb_blocks))(spreading_stride, round-half-up
documented since the RFC leaves the tie rule open); the per-set
strided variant (rotate_strided, setsS_k = {stride*n + k});
and the composedapply_spreading(per-blockthetarotation +
the(pi/2 − theta)strided pre-rotation whennb_blocks > 1and
blocks span ≥ 8 samples —SPREAD_PRE_ROTATION_MIN_BLOCK_LEN; the
module doc records the documented reading of the §4.3.4.3
multi-block paragraph, whose prose reusesNfor the full vector
and a block).SpreadingError::{SpreadOutOfRange, ZeroDimensions, ZeroBlocks, ZeroStride, BlocksDoNotDivideLength}covers
caller-side bookkeeping. Twenty-eight new unit tests (976 lib
tests, up from 948; 20 integration tests unchanged): Table 56
PDF/iCDF consistency + exhaustive first-byte decode sweep, the
Table 59 map, workedg_r/thetapoints and monotonicities, the
2-D step against the RFC definition, theN = 3series against an
explicit-matrix composition, norm-preservation / zero-angle /
sign-linearity properties, stride worked points including the
2.5-tie, strided-rotation gather-scatter equivalence + set
independence, and every composed path + error path. Docs-gap note:
§4.3.4.1 Bits-to-Pulses stays blocked — the staged
cache-bits50.csv/cache-index50.csvcarry the pulse-cache
values but no staged trace describes the run layout /
permitted-Kmapping, and RFC 6716 §4.3.4.1 prose (p. 116) does
not pin it. Source: RFC 6716 §4.3.4.3 (pp. 117–118) + Tables 56/59. -
Clean-room round 43 (2026-06-11): RFC 6716 §4.3.4.2 PVQ
index-to-vector decoding — a newcelt_pvq_decodemodule that
turns a decoded codeword indexi ∈ 0..V(N, K)into the
integer-magnitude pulse vectorXwithsum |X[j]| == K, the
consumer of the round-41celt_pvq_v::pvq_codebook_sizeprimitive.
Implements the §4.3.4.2 five-step recovery verbatim: per coordinate
j,p = (V(N-j-1,k) + V(N-j,k)) / 2, sign selection oni < p,
then thep -= V(N-j-1,k)magnitude-walk loop, yielding
X[j] = sgn*(k0 - k). New public surface:
decode_pvq_vector(n, k, index) -> Result<Vec<i32>, PvqDecodeError>
(allocating) anddecode_pvq_vector_into(n, k, index, &mut [i32]) -> Result<usize, PvqDecodeError>(in-place);pvq_l1_norm(&[i32]) -> u64andpvq_l2_norm_squared(&[i32]) -> u64invariant helpers (the
§4.3.4.2 final "L2-norm equals one" normalization is a
floating-point step left to the §4.3.4 consumer site); constants
PVQ_DECODE_N_MAX/PVQ_DECODE_K_MAXmirrored fromcelt_pvq_v;
andPvqDecodeError::{CodebookSize(PvqVError), IndexOutOfRange, OutputBufferTooSmall}. Twenty-seven new unit tests including a
full-index-range bijection proof (L1 == Kfor every codeword over
(N, K) ∈ 1..=6 × 0..=6, plus injectivity giving surjectivity onto
the K-pulse lattice by a counting argument), hand-enumerated
codebooks at(1,1)/(1,3)/(2,1)/(2,2)/(3,2), the index-0 leading-
positive-pulse property, error-path and buffer-handling coverage,
and the §4.1.5 overflow propagation atV(176,176). The up-front
ec_dec_uint(V(N, K))index read and the §4.3.4.1 Bits-to-Pulses
search that suppliesKremain deferred to the consumer site. -
Clean-room round 42 (2026-06-10): RFC 6716 §4.3.2.2 fine-energy
quantization — a newcelt_fine_energymodule that converts an
already-read fine-energy refinementf ∈ [0, 2**B_i - 1]into the
§4.3.2.2 correction(f + 1/2) / 2**B_i - 1/2 = (2f + 1 - 2**B_i) / 2**(B_i + 1), a zero-mean fraction of a 6 dB coarse-energy step,
and plans the §4.3.2.2 final fine-energy bit allocation (one extra
bit per band per channel, priority-0 bands band-0-upward then
priority-1 bands band-0-upward, leftover bits unused). New public
surface:fine_correction_ratio(bits, f) -> Result<(i32, i32), …>
(exact reduced(numerator, denominator));fine_correction_q15(bits, f) -> Result<i32, …>(correction in Q15, exact for every reachable
B_i, strictly within(-16384, +16384));fine_correction_q(bits, f, shift) -> Result<i64, …>(arbitrary Q-format, e.g. CELT's
DB_SHIFT = 10);fine_energy_levels(bits) -> Result<u32, …>
(2**B_i);plan_final_fine_bits(priorities, channels, leftover_bits) -> FinalFineBitPlan { granted, bits_used, bits_unused }; the
FineEnergyChannels::{Mono, Stereo}/FinalBitPriority::{Priority0, Priority1}enums; constantsFINE_ENERGY_MAX_BITS = 14,
FINE_ENERGY_Q15_ONE = 32768,FINE_ENERGY_HALF_Q15 = 16384; and
FineEnergyError::{BitsOutOfRange, RefinementOutOfRange}for
caller-side bookkeeping bugs. The range-decoderdec_bits(B_i)/
dec_bits(channels)reads and the addition of the correction onto
the §4.3.2.1 reconstructed log-energy run at the consumer site.
Thirty-three new unit tests pin the correction at worked(B_i, f)
points, the odd-numerator-lowest-terms / zero-mean-symmetry /
uniform-step / strictly-within-±1/2invariants, the Q15 exactness
against the ratio form, theDB_SHIFT = 10parity, and the
final-bit priority sweep (priority ordering, band order within a
priority, stereo two-bit cost, leftover-unused, None-band exclusion,
and thebits_used + bits_unused == leftoverconservation law).
Source: RFC 6716 §4.3.2.2 (p. 109). -
Clean-room round 41 (2026-06-08): RFC 6716 §4.3.4.2 PVQ
codebook-size functionV(N, K)— a newcelt_pvq_vmodule
evaluating the bivariate recurrence the RFC states directly:
V(N, K) = V(N - 1, K) + V(N, K - 1) + V(N - 1, K - 1)with base
casesV(N, 0) = 1andV(0, K) = 0 (K != 0).V(N, K)counts
the integer-magnitude lattice points `{ x ∈ Z^N : |x_0| + |x_1|- ... + |x_{N-1}| = K }
— the size of the §4.3.4 PVQ codebook forNMDCT bins andKpulses. The §4.3.4.2 PVQ index is decoded withec_dec_uint(V(N, K))(§4.1.5 capsec_dec_uint'sftparameter at232 − 1), and §4.3.4.1 *Bits to Pulses* picksKby searching the codebook size at the §4.3.3 per-band allocation; both consume this primitive. New public surface:pvq_codebook_size(n, k) -> Result<u32, PvqVError>evaluating the recurrence inu64over two rolling rows of lengthK + 1and short-circuiting when any intermediate cell crosses232 − 1;PVQ_V_N_MAX = 352(caller-side bookkeeping bound covering joint-stereo bands at 20 ms:2 × CELT_MAX_BINS_PER_BAND
= 2 × 176 = 352);PVQ_V_K_MAX = 4096(conservative caller-side upper bound onKso fuzz callers can sweep wide envelopes);PVQ_V_MAX = 232 − 1(the §4.1.5ec_dec_uintceiling inherited as the overflow guard); andPvqVError::{NOutOfRange,
KOutOfRange, OverflowsDecUintRange}for caller-side bookkeeping errors and stream-impossibility reports. Twenty-three new unit tests (888 lib tests total, up from 865 at round-40 close; 20 integration tests unchanged) pin the four §4.3.4.2 base cases (V(0, 0) = 1,V(N, 0) = 1,V(0, K) = 0,V(1, K) = 2,V(N, 1) = 2N), cross-check the bivariate recurrence over the N, K ∈ 1..=12 sweep, pin a 7×7 hand-computed table ofV(N, K)values, pin two specific worked points (V(3, 3) = 38,V(4, 2) = 32) showing theV(N, K) ≠ V(K, N)asymmetry, validate the monotone-non-decreasing-in-Ninvariant (for every fixedK), validate the monotone-non-decreasing-in-Kinvariant forN ≥ 2, exercise the §4.1.5 overflow guard onV(176, 176)(well above232), confirm the guard does *not* trip on values just under the ceiling (V(2, K) = 4Kfor the fullK ∈ 0..=100window), exercise the boundaryPVQ_V_N_MAXandPVQ_V_K_MAXrejection paths, validate the three module constants (PVQ_V_N_MAX = 352,PVQ_V_K_MAX = 4096,PVQ_V_MAX
= 4_294_967_295`), and pin every error-Display message at the
failing input.
- ... + |x_{N-1}| = K }
-
Clean-room round 40 (2026-06-08): RFC 6716 §4.3.3 1/64-step
interpolated static-allocation search — a newcelt_alloc_search
module that closes the interpolation + search gap round 39 noted
as the natural next step on top ofcelt_static_alloc. RFC 6716
§4.3.3 (p. 111, lines 6223–6230) is explicit: "The allocation is
obtained by linearly interpolating between two values of q (in
steps of 1/64) to find the highest allocation that does not
exceed the number of bits remaining." This module owns the
interpolation + search half; the orchestrated §4.3.3 allocator
that folds in the round-31 per-band cap, the round-33 boosts,
the round-34 reservations, the round-35 per-band minimum, the
round-36 trim offsets, and the skip / dual-stereo / intensity-
stereo flag reads runs at the consumer site. New public surface:
Q_FP_MAX = 640(the fixed-point quality bound packingq'_fp = q_lo * 64 + fracwithq_lo ∈ 0..=9,frac ∈ 0..=63, plus the
saturation endpoint(q_lo = 9, frac = 64)representing
q' = 10.0);STATIC_ALLOC_INTERP_RIGHT_SHIFT = 8(the
combined>> 2Q5→Q3 fold plus>> 6Q6 step-weight reduction);
the typed decompositionQFpComponents { q_lo, frac }and the
invertibleq_fp_to_components(q_fp) -> QFpComponents/
q_fp_from_components(q_lo, frac) -> u32accessors;
per_band_eighth_bits_at_q_fp(band, q_fp, channels, n_bins, lm) -> u64returning the per-band Q3 allocation under the linear
interpolationcell_q11 = alloc[b][q_lo] * (64 - frac) + alloc[b][q_lo + 1] * fracfollowed by the
(channels * N * cell_q11) << LM >> 8unit conversion;
total_eighth_bits_at_q_fp(q_fp, channels, frame_size, is_hybrid) -> u64summing across coded bands while respecting the §4.3
first-coded-band rule (0for CELT-only /17for Hybrid);
search_q_fp(budget, channels, frame_size, is_hybrid) -> AllocSearchOutcomerunning the §4.3.3 linear scan from
q_fp = Q_FP_MAXdownwards and returning the highest
q_fp ∈ 0..=640whose summed allocation fits the budget;
AllocSearchOutcome { q_fp, total_eighth_bits }carrying the
chosen quality plus its evaluated total; andAllocSearchError:: {ChannelsOutOfRange, QFpOutOfRange, BandOutOfRange}for
caller-side bookkeeping errors. Twenty-seven new unit tests pin
theQ_FP_MAX = 640constant +STATIC_ALLOC_INTERP_RIGHT_SHIFT = 8derived constant; the(q_lo, frac)decomposition at
q_fp = 0(q_lo = 0, frac = 0), at every integer column
(q_fp = q * 64 ⇒ frac = 0), at the saturation endpoint
(q_fp = 640 ⇒ q_lo = 9, frac = 64), and at a mid-step
(q_fp = 352 ⇒ q_lo = 5, frac = 32); the round-trip identity
q_fp_from_components(q_fp_to_components(q_fp)) == q_fpfor
everyq_fp ∈ 0..=640; the four invalid(q_lo, frac)shapes
the recomposer rejects (q_lo = 10 with non-zero frac, frac = 64
at q_lo ≠ 9, frac > 64, q_lo > 10); the per-band parity check
thatper_band_eighth_bits_at_q_fp(band, q * 64, ...)exactly
reproduces the round-39static_alloc_eighth_bits(band, q, ...)
for every(band, q, channels, n_bins, lm)in a representative
sweep; the saturation parity check that
per_band_eighth_bits_at_q_fp(band, Q_FP_MAX, ...)matches the
pure column-10static_alloc_eighth_bits(band, 10, ...); the
column-zero pin (per_band_eighth_bits_at_q_fp(_, 0, ...) = 0);
the §4.3.3 invariant that per-band allocations are monotone
non-decreasing inq_fpacross the full0..=640sweep; every
caller-bookkeeping error path (BandOutOfRange,
ChannelsOutOfRange,QFpOutOfRange); the total-across-coded-
bands properties (total(q_fp = 0) = 0across every
(frame_size, channels, is_hybrid)combination; monotone-non-
decreasing-in-q_fptotal; CELT-only total exceeds Hybrid at
saturation; stereo total is bounded by2 * monoand
2 * mono + 21to capture the per-band>> 8rounding slack);
and the search behaviour (budget = 0⇒q_fp = 0,
budget = u64::MAX⇒q_fp = Q_FP_MAX, exact-target probes
return at least the target quality; one-less-than-target probes
fall strictly below; the self-consistency invariant that the
returned total recomputes to the same value AND if
q_fp < Q_FP_MAXthe next step's total strictly exceeds the
budget). Bridges round 39'scelt_static_allocparameter
surface with the orchestrated §4.3.3 allocator the next round
will land. Source: RFC 6716 §4.3.3 (pp. 111–112) — held in-repo
atdocs/audio/opus/rfc6716-opus.txt. -
Clean-room round 39 (2026-06-08): RFC 6716 §4.3.3 static
allocation table (Table 57) — a newcelt_static_allocmodule
landing the 21-band × 11-quality-column Q5 gridalloc[band][q]
the §4.3.3 Bit Allocation procedure interpolates over to derive
each band's static shape allocation. RFC 6716 §4.3.3 (p. 111)
describes the conversion as
channels * N * alloc[band][q] << LM >> 2, where the result is
in 1/8 bits (the same units as every other §4.3.3 budget
quantity). New public surface:STATIC_ALLOC: [[u8; 11]; 21]
reproducing the 231 cells of Table 57, the layout / conversion
constantsSTATIC_ALLOC_Q_COUNT = 11,STATIC_ALLOC_Q_MIN = 0,
STATIC_ALLOC_Q_MAX = 10,STATIC_ALLOC_TOTAL_CELLS = 231,
STATIC_ALLOC_RIGHT_SHIFT = 2,STATIC_ALLOC_INTERP_STEPS = 64,
the typed accessorsstatic_alloc_cell(band, q) -> u8and
static_alloc_row(band) -> &[u8; 11]for raw Q5 lookups, the
static_alloc_eighth_bits(band, q, channels, n_bins, lm) -> u32
conversion folding the per-band scale(channels * N) << LM >> 2
into the Q5-to-Q3 unit fold, andStaticAllocError::{BandOutOfRange, QualityOutOfRange, ChannelsOutOfRange, LmOutOfRange}for caller-side
bookkeeping errors. Twenty-eight new unit tests pin the table shape
(21 × 11 = 231 cells; column 0 uniformly zero; column 10 at 200 for
bands 0..=7 then declining to 104 at band 20), the
monotone-non-decreasing-in-qinvariant the §4.3.3 search depends
on, hand-picked corner cells (band 0 / q 1 / q 10; band 13 / q 1 / q
2; band 20 / q 5..=9), worked-example traces of the<< LM >> 2
unit conversion at LM = 0 and LM = 3, the<< LMdoubling property
across the four CELT frame sizes, a cross-check against the round-24
Table 55 band-width lookup, and every out-of-range guard. Bridges
the round-31 cap surface (celt_cache_caps50), the round-33
band-boost decoder, the round-34 reservation block, the round-35
per-band minimum threshold, and the round-36 trim offsets with the
§4.3.3 1/64-step interpolated search the next round will land.
Source: RFC 6716 §4.3.3 Table 57 (pp. 111–112) — held in-repo at
docs/audio/opus/rfc6716-opus.txt. -
Clean-room round 38 (2026-06-07): RFC 6716 §4.5.3 Summary of
Transitions (Figure 18 + Figure 19) — a newcelt_transitions
module that closes the §4.5 chain after the round-26 §4.5.1
redundancy side information, the round-28 §4.5.1.4 cross-lap
placement, and the round-27 §4.5.2 state-reset policy. §4.5.3
enumerates the nine normative transition shapes (Figure 18)
the encoder is allowed to use, plus seven recommended
non-normative shapes (Figure 19) for transitions without
redundancy where PLC is allowed. New public surface:
NormativeTransitionwith one variant per Figure-18 row,
RecommendedNonNormativeTransitionwith one variant per
Figure-19 row,BoundaryOplifting the figure-key markers (;,
|,!,&,+,c,P,>) to a typed list,
classify_normative_transition(prev_mode, prev_silk_bw, next_mode, next_silk_bw, redundancy_present) -> Option<NormativeTransition>for Figure-18 lookup, and
recommended_non_normative(prev_mode, prev_silk_bw, next_mode, next_silk_bw) -> Option<RecommendedNonNormativeTransition>for
Figure-19 lookup. Each enum exposes aseam_operations() -> &'static [BoundaryOp]accessor returning the ordered §4.5.3
marker list at the transition seam. The classifier bakes in the
SILK-bandwidth split between Figure-18 rows 2 ("NB or MB SILK to
Hybrid with Redundancy") and 3 ("WB SILK to Hybrid"), the
symmetric Hybrid → SILK split (rows 5 and 6), and the §4.5
first-paragraph "audio-bandwidth change is the glitch source"
reading that rules out same-bandwidth SILK→SILK from row 1.
Forty-two new unit tests pin every Figure-18 and Figure-19 row,
the SILK-bandwidth splits, the §4.5 first-paragraph "no special
treatment" exemption for same-configuration CELT→CELT and
Hybrid→Hybrid pairs, the seam-op ordering per row, and a
cross-check that the §4.5.3 figure-reset markers agree with the
§4.5.2 state-reset policy already encoded in
mode_transition_reset. Source: RFC 6716 §4.5.3 (pp. 128–130) —
held in-repo atdocs/audio/opus/rfc6716-opus.txt. -
Clean-room round 37 (2026-06-07): RFC 6716 Appendix B
self-delimiting framing — a newframing_self_delimmodule wires
up the alternate Opus framing that prefixes one or two extra
§3.2.1 length fields so a transport can pack multiple Opus streams
back to back (the appendix's worked example is the multi-channel
case formed from several one- or two-channel Opus streams). The
parser handles all five Appendix-B shapes — Figure 25 (code 0,
one Opus frame, one length), Figure 26 (code 1, two equal-size
frames, one length), Figure 27 (code 2, two length fields: the
§3.2.4 inline length for the first frame and the Appendix-B
extra length for the second), Figure 28 (CBR code 3, the
Appendix-B length applies to every frame; padding chain handled
per §3.2.5), and Figure 29 (VBR code 3,M − 1§3.2.1 inline
lengths plus the Appendix-B trailing length for frame M). New
public surface:parse_self_delimited(buffer) -> Result< SelfDelimitedParse<'_>, Error>returns the parsed
OpusPacket<'_>plus aconsumedbyte count so a multistream
demuxer can advance exactly one packet at a time (buffer[ consumed..]is the next stream's TOC byte). Frame slices borrow
the buffer just like [OpusPacket::parse] — the two construction
paths are interchangeable downstream. All Appendix-B malformation
conditions are bundled into [Error::MalformedPacket] / [Error:: EmptyPacket]: zero-byte buffer, truncated length, truncated
padding chain, frame larger than [MAX_FRAME_BYTES] (= 1275, the
§3.2.1 cap),M = 0orM > MAX_FRAMES_PER_PACKET(= 48), or
any frame / padding payload running past the buffer end. Unlike
[OpusPacket::parse] (which consumes the entire input as one
packet), this entry point consumes only the bytes its lengths
describe — that's the whole point of the Appendix-B variant.
Reuses the §3.2.1 length decoder via a crate-private re-export
(frames::decode_length) so the two framing modes share one
length-encoding implementation. 17 new tests cover each of the
five figures, multistream chaining (parse, advance, parse), and
the seven malformation paths. Source: RFC 6716 Appendix B
(September 2012), pp. 321–325 — held in-repo at
docs/audio/opus/rfc6716-opus.txt. -
Clean-room round 36 (2026-06-07): §4.3.3 per-band allocation-trim
offsets — a newcelt_trim_offsetsmodule delivering the §4.3.3
trim_offsets[]per-band tilt vector that biases the §4.3.3 Table 57
static-allocation search after the round-35
[band_min_thresh] floor is applied. RFC 6716 §4.3.3 (p. 115)
specifies the formula: for each coded bandb, withchannels ∈ {1, 2},
LM ∈ {0, 1, 2, 3}(the §4.3 frame-size scale),
n_shortest = celt_band_bins_per_channel(b, Ms2_5)(Table 55 column 0
— the shortest §4.3 frame size for the standard CELT mode),
n_per_channel = celt_band_bins_per_channel(b, frame_size), and
remaining_bandsthe band-position-dependent factor,
`base = (alloc_trim - 5 - LM) * channels * n_shortest * remaining_bands- (1 << LM) * 8 / 64
, thentrim_offsets[b] = base - 8 * channelswhenn_per_channel == 1(width-1 bands receive greater benefit from the coarse-energy coding, so the §4.3.3 narrative backs the trim off by one whole bit per channel for them). All arithmetic is signed (the(alloc_trim - 5 - LM)factor reaches-8at the lowest trim with the largest frame size); the output is in 1/8 bits, the same units the §4.3.3 budget loop works in. The "number of remaining bands" choice is deferred to the consumer site (the round that lands the §4.3.3 Table 57 static-allocation search): the RFC narrative phrases it as a per-band-iteration quantity, and this module acceptsremaining_bandsas an explicit caller-supplied parameter. New public surface:band_trim_offset(alloc_trim, lm, is_stereo, n_shortest, n_per_channel,
remaining_bands) -> Result<i32, TrimOffsetError>per-band primitive (validatesalloc_trim ≤ ALLOC_TRIM_MAX);band_trim_offset_for_band(
band, alloc_trim, frame_size, is_stereo, remaining_bands) ->
Result<i32, TrimOffsetError>convenience that derivesn_shortestandn_per_channelfrom the round-24 Table 55 layout;band_n_shortest
(band) -> OptionTable-55 column-0 lookup helper;shortest_frame_size() -> CeltFrameSizereturningMs2_5for the standard §4.3 mode; formula constantsTRIM_OFFSETS_BIAS = 5(§4.3.3 "subtract 5"),TRIM_OFFSETS_NUMERATOR_SCALE = 8(§4.3.3 "multiply by 8"),TRIM_OFFSETS_DIVISOR = 64(§4.3.3 "divide by 64"),TRIM_OFFSETS_WIDTH_ONE_BINS_PER_CHANNEL = 1(§4.3.3 width-1 trigger),TRIM_OFFSETS_WIDTH_ONE_PER_CHANNEL_EIGHTH_BITS = 8(§4.3.3 per-channel subtraction = one whole bit), andTRIM_OFFSETS_MONO_CHANNELS = 1/TRIM_OFFSETS_STEREO_CHANNELS = 2channel multipliers matching the round-35BAND_THRESH_{MONO,STEREO}CHANNELSpins; error variantsTrimOffsetError::{AllocTrimOutOfRange{provided, max}, BandOutOfRange
{band}}for caller-side bookkeeping bugs. Forty-two new unit tests (751 lib tests total, up from 709 at round-35 close; 20 integration tests unchanged, grand total 771) cover: the seven §4.3.3 formula constants pinned to their narrative sources; the constant cross-checkTRIM_OFFSETS_BIAS == ALLOC_TRIM_DEFAULT == 5(the §4.3.3 trim default cancels the multiplicative kernel atLM = 0); the net-scale-keeps-Q3-units invariant (8 / 64 = 1/8); theband_n_shortestTable-55-column-0 path at three pin cells (band 0 ⇒ 1, band 20 ⇒ 22, band 21 ⇒None); theband_n_shortest-matches-celt_band_bins_per_channel(, Ms2_5)cross-check over the full 21 bands; the §4.3.3 single-band formula at six worked points (default-trim / LM 0 / no-width-1 ⇒ 0; default-trim / LM 0 / width-1 mono ⇒ -8; default-trim / LM 0 / width-1 stereo ⇒ -16; max-trim / LM 0 / large factors ⇒ +577; min-trim / LM 3 / large factors mono ⇒ -3 696; min-trim / LM 3 / width-1 stereo ⇒ -352); the LM-factor-doubles cross-check at four LMs (40 → 64 → 96 → 128 withtrim_termadjusted per LM); the channel-factor-scales-linearly invariant; the n_shortest-scales-linearly invariant; the remaining_bands-scales-linearly invariant; theremaining_bands = 0case reducing to the width-1 correction only; thetrim_term = 0kernel-cancel path over many factor combinations (with the width-1 correction still firing where applicable); thealloc_trim - 5 == LMkernel-cancel pin at(alloc_trim=8, LM=3); the width-1 subtraction is purely additive (the difference betweenn_per_channel = 1andn_per_channel ≥ 2is exactly8 *
channels); the width-1 trigger fires only atn_per_channel == 1(verified at{0, 2, 3, 22, 176}exclusion edges); the truncating-toward-zero integer-division behaviour at three numerator cells (-512 / 64 = -8exact,-8 / 64 = 0truncating-positive-zero,-80 / 64 = -1truncating-toward-zero); thealloc_trim > ALLOC_TRIM_MAXerror path at the boundary (11) and far above (255); thealloc_trim ∈ {0, ALLOC_TRIM_MAX}accepted-edge cases; theband_trim_offset_for_bandTable-55 wrapper rejectingband ≥ CELT_NUM_BANDS; the wrapper matching the primitive's output over the full 21 × 4 × 2 (band × frame-size × stereo) matrix; the wrapper propagatingAllocTrimOutOfRange; the wrapper width-1 trigger at Table-55 band 0 / 2.5 ms (N = 1); the wrapper width-1 inactive at band 20 / 20 ms (N = 176 ⇒ result = -1 386); a determinism sweep over fivealloc_trimvalues × four frame sizes × 21 bands × 2 channels × 4remaining_bandsvalues; the output-fits-well-within-i32guarantee at the worst-case input edges; andDebugrendering for both error variants. The §4.3.3 Table 57 static-allocation search that consumestrim_offsets[](against the round-31cap[]per-band maximum, the round-33boosts[], and the round-35thresh[]` floor) is the responsibility
of the §4.3.3 allocator and runs in a downstream round.
- (1 << LM) * 8 / 64
-
Clean-room round 35 (2026-06-06): §4.3.3 per-band minimum-allocation
vector — a newcelt_band_threshmodule delivering the §4.3.3
thresh[band]lower bound used by the §4.3.3 Table 57 static-allocation
search to drop low-rate bands rather than code them sparsely. RFC 6716
§4.3.3 (p. 115) specifies the formula: for each coded bandb, with
N = celt_band_bins_per_channel(b, frame_size)(Table 55) and
channels ∈ {1, 2},thresh[b] = max((24 * N) / 16, 8 * channels)in
1/8 bits — one whole bit per channel or 48 128th-bits per MDCT bin,
whichever is greater. The §4.3.3 narrative is explicit that the
band-size dependent term(24 * N) / 16is not scaled by the
channel count: at the very low rates where this floor binds, the
§4.3.3 allocator concentrates the budget on the mid channel. New
public surface:band_min_thresh(band, frame_size, is_stereo) -> Option<u32>per-band lookup (Nonewhenband ≥ 21);
compute_band_min_thresh(start, end, frame_size, is_stereo, &mut thresh)in-place vector fill over the §4.3 coding windowstart..end
(0..21CELT-only,17..21Hybrid);band_min_thresh_vec(start, end, frame_size, is_stereo) -> Result<Vec<u32>, BandThreshError>
allocating convenience;standard_band_window(is_hybrid) -> (usize, usize)helper producing the §4.3 full-frame window from
[crate::celt_band_layout::celt_first_coded_band] +
[crate::celt_band_layout::celt_end_coded_band]; formula constants
BAND_THRESH_BINS_MULTIPLIER = 24(§4.3.3 "24 times the number of MDCT
bins"),BAND_THRESH_BINS_DIVISOR = 16(§4.3.3 "divide by 16"),
BAND_THRESH_PER_CHANNEL_EIGHTH_BITS = 8(§4.3.3 "8 times the number
of channels"),BAND_THRESH_MONO_CHANNELS = 1/
BAND_THRESH_STEREO_CHANNELS = 2channel multipliers; error variants
BandThreshError::{InvertedBandWindow{start, end}, BandWindowOutOfRange{end}, OutputBufferTooSmall{expected, provided}}
for caller-side bookkeeping bugs (the band layout itself is total over
band < 21; an out-of-range window cannot come from a corrupt
bitstream). Thirty-eight new unit tests (709 lib tests total, up from
671 at round-34 close; 20 integration tests unchanged, grand total
729) cover: the five §4.3.3 constants pinned to their narrative
sources; the channel-multiplier sanity (mono = 1, stereo = 2); the
§4.3.3 per-band formula at three key cells (band 0 / 2.5 ms / mono ⇒
channel-term wins ⇒thresh = 8; band 0 / 20 ms / mono ⇒ bin-term
wins ⇒thresh = 12; band 20 / 20 ms ⇒ bin-term dominates ⇒thresh = 264independent of channel count); theband ≥ 21Nonepath
(Custom mode out of scope); a full cross-check that the function
equalsmax((24 * N) / 16, 8 * channels)for every (band, frame_size,
channels) triple over the standard 21-band × 4-frame-size × 2-channel
matrix; the §4.3.3 "not scaled by channel count" invariant at the
bin-term-dominated cell (band 20 / 20 ms: mono = stereo = 264); the
channel-term-doubles-with-stereo behaviour at the channel-term-
dominated cell (band 0 / 2.5 ms: stereo = 2 × mono); the full
CELT-only window (0..21) and the §4.3 Hybrid window (17..21)
driver paths; a partial CELT-only NB 2.5 ms window (0..13) where
every band hits the channel-term floor (= 8 mono); the
band_min_thresh_vecallocator agreeing with the slice form; the
threeBandThreshErrorpaths (inverted window, end past 21, output
buffer mismatched length); the empty-window success case; the §4.3.3
"at least one whole bit per channel" lower-bound invariant across
every (band, frame_size) cell for both channel counts; the
thresh-monotonic-in-frame-size invariant at fixed band (driven by N
doubling across each Table 55 column); the
stereo ≥ monoinvariant; a units cross-check pinning the §4.3.3
"48 128th bits per MDCT bin" wording to(24 * N) / 161/8 bits;
two Table 55 cell pins (band 8 / 20 ms / stereo: N = 16, bin_term
= 24, channel_term = 16 ⇒ thresh = 24; band 20 / 2.5 ms: N looked
up via [celt_band_bins_per_channel] and formula reconciled); the
standard_band_windowhelper at CELT-only and Hybrid; an
integration test threadingstandard_band_window(true)⇒
band_min_thresh_vec⇒ stereo-floor invariant; determinism across
repeats; andDebugrendering for the error type. The §4.3.3
Table 57 static-allocation search that consumesthresh[](against
the round-31cap[]per-band maximum and the upcoming
trim_offsets[]per-band tilt) is the responsibility of the
§4.3.3 allocator and runs in a downstream round. -
Clean-room round 34 (2026-06-04): §4.3.3 reservation block —
a newcelt_reservationsmodule delivering the §4.3.3 fixed-cost
preamble that runs after the §4.3.3 band-boost loop (round 33) and
the §4.3.3 allocation-trim decode (round 32) but before the §4.3.3
Table 57 static-allocation search. RFC 6716 §4.3.3 (p. 114)
specifies four reservations skimmed off the workingtotal
budget:anti_collapse_rsv(8 1/8 bits iff transient &&LM > 1
&&total ≥ (LM + 2) * 8),skip_rsv(8 1/8 bits ifftotal > 8
after anti-collapse),intensity_rsv(stereo only; equal to
LOG2_FRAC_TABLE[end − start]from round 30 except reset to 0 if
greater thantotal), anddual_stereo_rsv(stereo only, 8 1/8
bits ifftotal > 8after the intensity-stereo deduction; only
considered when intensity_rsv was successfully reserved). The
§4.3.3 workingtotalstarts atframe_size_bytes * 64 − ec_tell_frac − 1(the trailing-1is the §4.3.3 conservative
deduction). New public surface:reserve_block(frame_size_bytes, ec_tell_frac, total_boost, lm, is_transient, is_stereo, coded_bands) -> Result<ReservationOutcome, ReservationError>
pure-function evaluator (lmtypedCeltFrameSize,
coded_bands=end − startfor the §4.3 band-coding window);
ReservationOutcome { anti_collapse_rsv, skip_rsv, intensity_rsv, dual_stereo_rsv, total_remaining_eighth_bits }typed outcome with
reserved_total_eighth_bits()summing helper; reservation-cost
constantsONE_BIT_EIGHTH_BITS = 8(anti-collapse / skip /
dual-stereo) andCONSERVATIVE_DEDUCTION_EIGHTH_BITS = 1;
anti-collapse gating constantsANTI_COLLAPSE_LM_MIN_EXCLUSIVE = 1(strictLM > 1floor) and
ANTI_COLLAPSE_HEADROOM_MULT_EIGHTH_BITS = 8/
ANTI_COLLAPSE_HEADROOM_LM_OFFSET = 2(the(LM + 2) * 8
1/8-bit headroom test); the module-localEIGHTH_BITS_PER_BYTE = 64mirror ofcelt_alloc_trim::EIGHTH_BITS_PER_BYTE; error
variantsReservationError::{FrameSizeOverflows, TellExceedsFrame { frame_eighth_bits, ec_tell_frac }, TotalBoostExceedsFrame { frame_eighth_bits, ec_tell_frac, total_boost }, LogFracLookupFailed(Log2FracError) }for caller-side bookkeeping
bugs (the range coder's sticky error flag is the right channel
for a corrupt bitstream signal);From<Log2FracError>round-trip
helper. Forty-one new unit tests (671 lib tests total, up from
630 at round-33 close; 20 integration tests unchanged, grand total
691) cover: the five RFC constants pinned to their narrative
sources; theEIGHTH_BITS_PER_BYTEagreement with
celt_alloc_trim; theCeltFrameSize::column_index() → LM
cross-check at every frame size; the four anti-collapse predicate
paths (non-transient ⇒ no rsv; LM ∈ {0, 1} ⇒ no rsv even with
transient; LM = 2 / LM = 3 with budget ⇒ rsv = 8); the §4.3.3
anti-collapse threshold inequality at exact match and one short;
the §4.3.3 skip gate attotal = 8(rsv = 0) andtotal = 9
(rsv = 8); a strict-ordering check that the anti-collapse
deduction precedes the skip gate; the mono branch skipping all
stereo reservations even with budget; the stereo
intensity-reset-on-overflow path withdual_stereo_rsv = 0
follow-on; the stereo intensity-just-fits path with
dual_stereo_rsv ∈ {0, 8}depending on the remaining budget vs
thetotal > 8gate; the §4.3 Hybrid 4-band window producing
intensity_rsv = 19fromLOG2_FRAC_TABLE[4]; thecoded_bands ∈ {0, 1}boundary cells; the §4.3.3 invarianttotal_remaining + reserved = frame_eighth − ec_tell − 1across mono / stereo /
transient / non-transient / nonzero-tell permutations; the four
ReservationErrorpaths; the mono short-circuit on out-of-range
coded_bands(intensity-stereo lookup is not attempted for
mono frames, so the input is harmless); the zero-byte and
one-byte frame edge cases; the §3.4 R5 1275-byte max-frame
headroom assertion with every reservation at its maximum (8 + 8 +
37 + 8 = 61, total_remaining = 81538); the
ReservationOutcome::default()all-zero pattern; determinism
across repeats; debug formatting; and theFrom<Log2FracError>
round-trip. The §4.3.3 use of the reservations — the actual
dec_bit_logp(1)reads of the anti-collapse / skip /
dual-stereo flags and theec_dec_uint(end − start)read of the
intensity-stereo band — runs at the §4.3.3 allocator's consumer
site once the Table 57 search produces the per-band shape
allocation; the per-bandtrim_offsets[]derivation that biases
the Table 57 search is the responsibility of the §4.3.3 allocator
and runs in a downstream round. -
Clean-room round 33 (2026-06-04): §4.3.3 band-boost decoder —
a newcelt_band_boostmodule delivering the §4.3.3 band-boost
decode loop (RFC 6716 §4.3.3, pp. 113–114) — the third §4.3.3
fragment after rounds 30 and 31'sLOG2_FRAC_TABLE/
CACHE_CAPS50parameter surfaces, and the structural bridge that
takes round 31'scap[]per-band upper bound and round 32's
decode_alloc_trimgate'stotal_boostinput and ties them
together at the §4.3.3 control-flow site. The §4.3.3 narrative is:
"To decode the band boosts: First, set 'dynalloc_logp' to 6 […]
'total_bits' to the size of the frame in 8th bits, 'total_boost'
to zero […]. For each band […] the boost quanta in units of 1/8
bit is calculated asquanta = min(8*N, max(48, N)). […] Set
'boost' to zero and 'dynalloc_loop_logp' to dynalloc_logp. While
dynalloc_loop_logp […] in 8th bits plus tell is less than
total_bits plus total_boost and boost is less thancap[]for
this band: Decode a bit […] update tell […] If the decoded value
is zero break the loop. Otherwise, add quanta to boost and
total_boost, subtract quanta from total_bits, and set
dynalloc_loop_log to 1. […] If boost is non-zero and dynalloc_logp
is greater than 2, decrease dynalloc_logp." New public surface:
shape constantsDYNALLOC_LOGP_INIT = 6(§4.3.3 initial
first-boost cost in whole bits),DYNALLOC_LOGP_MIN = 2(§4.3.3
first-boost floor),DYNALLOC_LOOP_LOGP_AFTER_FIRST = 1(§4.3.3
second-and-subsequent-bits cost within a single band's loop),
BAND_BOOST_QUANTA_FLOOR_EIGHTH_BITS = 48(§4.3.3max(48, N)
floor), andBAND_BOOST_QUANTA_CEIL_MULT = 8(§4.3.38*N
1-bit/sample ceiling multiplier); theband_boost_quanta(n)pure
helper computingmin(8*n, max(48, n))overu32; the
decode_band_boosts(rd, start, end, caps, n_bins, frame_size_bytes) -> Result<BandBoostOutcome, BandBoostError>
driver walking the §4.3start..endcoding window (0..end
normally,17..endin Hybrid mode) and running the §4.3.3
per-band inner loop against caller-suppliedcaps[band - start]
andn_bins[band - start]slices; the
BandBoost { boost_eighth_bits, bits_read }per-band outcome
struct; theBandBoostOutcome { per_band, total_boost_eighth_bits, total_bits_remaining_eighth_bits, dynalloc_logp_final }full
driver outcome bundling the §4.3.3total_boostaccumulator
consumed bycelt_alloc_trim::decode_alloc_trimdownstream; and
error variantsBandBoostError::{CapsLengthMismatch{expected, provided}, NBinsLengthMismatch{expected, provided}, EmptyBandWindow{start, end}, InvertedBandWindow{start, end}}
for caller-side bookkeeping bugs that don't belong to the range
coder's sticky error flag. Thirty-seven new unit tests (630 lib
tests total, up from 593 at round-32 close; 20 integration tests
unchanged, grand total 650) cover: the five §4.3.3 RFC constants
pinned to their narrative sources; the §4.3.3
quanta = min(8*N, max(48, N))rule sampled atN = 48
(boundary),N > 48(linear regime),6 ≤ N < 48(floor regime),
N < 6(ceiling regime),N = 0(degenerate), and as a total
function over everyu16; the fourBandBoostErrorpaths with
the range coder'stell_frac()unchanged across error returns;
the no-room-for-any-boost path (frame_size_bytes = 0) returning
all-zero boosts and the §4.3.3 invariant
total_bits + total_boost = frame_eighth_bitsholding at zero;
the stop-bit-biased payload ([0x00; 64]whose §4.1.1 init
val = 127 - (b0 >> 1) = 127biasesdec_bit_logptoward the
§4.3.3 stop branch) decoding zero boosts withbits_read = 1
per band and the §4.3.3dynalloc_logp_final = DYNALLOC_LOGP_INITno-decrement rule; the boost-bit-biased
payload ([0xFF; 64]⇒val = 0) actually boosting at least one
band and decrementingdynalloc_logpbelow its initial value;
theper_bandvector alignment with thestart..endwindow
(including the §4.3 Hybrid17..21four-band window); the §4.3.3
invarianttotal_bits + total_boost = frame_size_bytes * 64
conserved across both the stop and boost paths; the §4.3.3
dynalloc_logpcross-band floor atDYNALLOC_LOGP_MIN; the
boost = 0short-circuit on acap = 0band (no range-coder
bits read); theBandBoostOutcomedebug / equality / determinism
cross-check on identical runs; and the §3.4 R51275 * 64
max-frame headroom assertion. The §4.3.3 use of the per-band
boostvalues — the per-band shape-allocation adjustment that
feeds into the §4.3.3 Table 57 static-allocation search and the
§4.3.3 anti-collapse / skip / dual-stereo reservations — is the
responsibility of the §4.3.3 allocator and runs at the call site
ofdecode_band_boosts. -
Clean-room round 32 (2026-06-03): §4.3.3 allocation trim
parameter surface — a newcelt_alloc_trimmodule delivering the
Table-58 PDF of RFC 6716 §4.3.3 (p. 115) plus the §4.3.3
signalling-gate predicate (RFC 6716 §4.3.3 p. 114) and the typed
decode wrapper that fuses the two. The §4.3.3 narrative reads:
"To decode the trim, first set the trim value to 5, then if and
only if the count of decoded 8th bits so far (ec_tell_frac) plus
48 (6 bits) is less than or equal to the total frame size in 8th
bits minus total_boost […], decode the trim value using the PDF
in Table 58." New public surface:ALLOC_TRIM_PDF: [u8; 11]
(the 11-cell Table-58 PDF{2, 2, 5, 10, 22, 46, 22, 10, 5, 2, 2}/128) and the derivedALLOC_TRIM_ICDF: [u8; 11]([126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0]) for direct
RangeDecoder::dec_icdfconsumption; shape constants
ALLOC_TRIM_PDF_LEN = 11,ALLOC_TRIM_FTB = 7,
ALLOC_TRIM_PDF_DENOMINATOR = 128; trim-integer range constants
ALLOC_TRIM_DEFAULT = 5,ALLOC_TRIM_MIN = 0,
ALLOC_TRIM_MAX = 10per the RFC's "an integer value from 0-10"
and "the default value of 5 indicates no trim" wording;
signalling-cost constantsALLOC_TRIM_SIGNAL_COST_EIGHTH_BITS = 48(6 whole bits at 1/8-bit precision) and
EIGHTH_BITS_PER_BYTE = 64; the §4.3.3 signalling-gate
predicatealloc_trim_is_signalled(ec_tell_frac, frame_eighth_bits, total_boost) -> boolevaluating
(ec_tell_frac + 48) ≤ (frame_eighth_bits − total_boost)with
saturating arithmetic for the malformed-input edge cases; the
byte-to-1/8-bit conversion helper
frame_eighth_bits(frame_size_bytes) -> Result<u32, AllocTrimError>withu32overflow rejection; the composite
decode wrapperdecode_alloc_trim(rd, ec_tell_frac, frame_size_bytes, total_boost) -> Result<u8, AllocTrimError>
fusing the gate evaluation, the gate-fail-returns-5rule, and
theRangeDecoder::dec_icdf(&ALLOC_TRIM_ICDF, 7)read into one
typed call; full-table borrowsalloc_trim_pdf()and
alloc_trim_icdf(); error variants
AllocTrimError::{FrameSizeOverflows, TotalBoostExceedsFrame { frame_eighth_bits, total_boost }}for caller-side bookkeeping
bugs. Thirty-three new unit tests (593 lib tests total, up from
560 at round-31 close; 20 integration tests unchanged, grand
total 613) pin the shape constants, the Table 58 PDF cells
against the RFC body, the PDF sum-to-denominator and
symmetric-around-default invariants, the heaviest-mass-at-default
cell pin, the iCDF strict-monotone-decreasing invariant, the
iCDF-from-PDF derivation, spot iCDF cells, the
frame_eighth_bitsscaling and overflow rejection, the §4.3.3
signalling gate at the six-bit boundary (ec_tell_frac + 48 = budgetpasses, one over fails) and across the total_boost / no
room / underflow /u32overflow edge cases, the
decode_alloc_trimgate-fail returns5and consumes no
range-coder bits, the gate-pass returns an in-range value and
advancestell_frac, the error paths leave the range coder
untouched, and the worst-case-symbol-cost-matches-gate-budget
math (log2(128/2) = 6whole bits = 48 1/8 bits). The §4.3.3
use of the trim — the per-bandtrim_offsets[]derivation
that biases the Table 57 static allocation search — runs at the
call site ofdecode_alloc_trimand is out of scope for this
parameter surface. -
Clean-room round 31 (2026-06-03): §4.3.3 per-band
maximum-allocation parameter surface — a newcelt_cache_caps50
module delivering theCACHE_CAPS50lookup piece of RFC 6716 §4.3.3
(pp. 113–114): the 168-byte bits/sample table the §4.3.3 per-band
bit capcap[band] = ((cache_caps50[i] + 64) * channels * N) / 4
consumes (namedinit_caps()in RFC 6716 §4.3.3 p. 114). Round 24
noted the §4.3.3 allocator as blocked oncache_caps50+
LOG2_FRAC_TABLE; round 30 landedLOG2_FRAC_TABLE, and this round
closes that pair by landingCACHE_CAPS50plus theinit_caps()
convert-rule helpers. New public surface:CACHE_CAPS50: [u8; 168]
(168 Q0 bytes; layout[LM ∈ 0..4][stereo ∈ {0,1}][band ∈ 0..21]
flattened by the §4.3.3i = nbBands * (2*LM + stereo) + bandrule
withnbBands = 21, matching
docs/audio/celt/tables/cache_caps50.csvrow-for-row); shape
constantsCACHE_CAPS50_LM_COUNT = 4,
CACHE_CAPS50_STEREO_COUNT = 2,CACHE_CAPS50_TOTAL_BYTES = 168;
stereo-axis index constantsCACHE_CAPS50_STEREO_MONO = 0,
CACHE_CAPS50_STEREO_STEREO = 1; convert-rule constants
INIT_CAPS_BIAS = 64,INIT_CAPS_DIVISOR = 4,
INIT_CAPS_MAX_CHANNELS = 2; typed stereo-axis selector
CacheCapsStereo::{Mono, Stereo}withaxis_index()/
channels()/from_is_stereo(bool)helpers (thechannels()
helper turnsMono → 1/Stereo → 2to feed theinit_caps()
multiplier independently of the axis index); typed accessors
cache_caps_value(lm, stereo, band) -> Result<u8, CacheCaps50Error>
andcache_caps_row(lm, stereo) -> Result<&'static [u8], CacheCaps50Error>over the lookup; flat-offset helper
cache_caps_offset(lm, stereo, band) -> usizecovering the §4.3.3
row-stride rule;init_caps(caps_value, channels, n_bins) -> u32
computing the §4.3.3(value + 64) * channels * N / 4convert
rule on a single byte; composite
cap_for_band_bits(lm, stereo, band, channels, n_bins) -> Result<u32, CacheCaps50Error>performing lookup-plus-convert in
one typed call; error variants
CacheCaps50Error::{LmOutOfRange, BandOutOfRange, ChannelsOutOfRange}. Twenty-nine new unit tests (560 lib tests
total, up from 531 at round-30 close; 20 integration tests
unchanged, grand total 580) pin the table shape, the
INIT_CAPS_BIAS = 64/INIT_CAPS_DIVISOR = 4/
INIT_CAPS_MAX_CHANNELS = 2convert-rule constants, the
CACHE_CAPS50_STEREO_MONO = 0/CACHE_CAPS50_STEREO_STEREO = 1
axis indices, theCacheCapsStereo::channels()Mono → 1/
Stereo → 2helper mapping, thefrom_is_stereo(bool)round-trip,
eight CSV-cell spot-checks at(row 0, band 0)/(row 1, band 20)
/(row 2, band 0)/(row 3, band 8)/(row 4, band 12)/
(row 5, band 17)/(row 6, band 20)/(row 7, band 0), the
§4.3.3cache_caps_offset()rule against every(LM, stereo, band)
triple (168 cells) plus its two endpoints, thecache_caps_value()
total-function sweep, thecache_caps_row()per-cell mirror, the
LmOutOfRange/BandOutOfRange/ChannelsOutOfRangeerror
paths on both accessors, four §4.3.3init_caps()formula pins
(including the(caps=255, channels=2, N=192) → 30624upper-bound
cell and the floor-division corner atcaps ∈ {1,2,3}), a
cap_for_band_bits()composite cross-check against the manual
lookup-plus-init_caps()sequence, the §4.3.3 narrative invariant
that 20 ms stereo caps fit ini16but at least one exceeds
i8::MAX, and two §4.3.3-reachable-cell pins (CELT-only 20 ms
stereo band 0 →caps = 204→cap = 134 * n_bins; Hybrid 20 ms
mono band 17 →caps = 173→cap = (237 * n_bins) / 4). The
§4.3.3 bit allocation orchestration that consumes thecap[]
vector (boost / trim / anti-collapse / skip / dual-stereo
reservations, the Table 57 static allocation search, the
reallocation / fine-vs-shape split / band-priority computation) is
out of scope for this round. -
Clean-room round 30 (2026-06-02): §4.3.3 intensity-stereo
reservation parameter surface — a newcelt_log2_frac_tablemodule
delivering theLOG2_FRAC_TABLElookup piece of RFC 6716 §4.3.3
(p. 113): the 24-byte conservativelog2table (in Q3 / 1/8-bit
units) the §4.3.3intensity_rsv = LOG2_FRAC_TABLE[end − start]
reservation consumes. Round 24 noted the §4.3.3 allocator as blocked
oncache_caps50+LOG2_FRAC_TABLE; this round delivers the
smaller of the two table dependencies. New public surface:
LOG2_FRAC_TABLE: [u8; 24](24 Q3 bytes; layout
LOG2_FRAC_TABLE[coded_bands] = conservative_log2(coded_bands)in
1/8-bit units, matchingdocs/audio/celt/tables/log2_frac_table.csv
row-for-row); shape constantLOG2_FRAC_TABLE_LEN = 24;
unit-denominator constantQ3_BITS_PER_WHOLE_BIT = 8; typed
accessorlog2_frac(coded_bands) -> Result<u8, Log2FracError>
with the §4.3.3coded_bands = end − startindexing rule and a
bounds check covering thecoded_bands ≥ 24case; full-row
borrowlog2_frac_row() -> &'static [u8; 24]; error variant
Log2FracError::CodedBandsOutOfRange { coded_bands }. Seventeen
new unit tests (531 lib tests total, up from 514 at round-29
close) pin the table shape, theQ3_BITS_PER_WHOLE_BIT = 8unit
constant, seven CSV-row spot-checks at indices 0 / 1 / 2 / 4 / 14
/ 15 / 21 / 23 (covering the §4.3.3 base case, the 1-bit floor,
the upward-rounded conservative entry, the Hybrid reachable
index, the 32-byte plateau pair, the CELT-only reachable index,
and the final entry), a monotone-non-decreasing property across
every adjacent pair, a conservative-bound property
LOG2_FRAC_TABLE[n] ≥ 8 × floor(log2(n))for everyn ∈ 1..24
(leading-zero-count formulation, no floats), a total-function
sweep over every in-range index, theCodedBandsOutOfRangeerror
paths, a row-vs-pair cross-check, and two §4.3.3-reachable-index
sanity pins (CELT-onlyend − start = 21→36Q3; Hybrid
end − start = 4→19Q3). The rest of the §4.3.3 allocation
algorithm (anti-collapse / skip / dual-stereo reservations, the
Table 57 static-allocation search, boost / trim decoding, and the
cache_caps50per-band maximum vector) is out of scope. -
Clean-room round 29 (2026-06-01): §4.3.2.1 CELT coarse-energy
Laplace-model parameter surface — a newcelt_e_prob_modelmodule
delivering the parameter-surface piece of RFC 6716 §4.3.2.1
(pp. 108–109): the per-(LM, mode, band)Q8{prob, decay}table
the §4.3.2.1ec_laplace_decoderoutine consumes. Round 20's CELT
pre-band header noted the §4.3.2.1 coarse energy as blocked on this
table; this round delivers it plus the surrounding selector /
accessor surface so the Laplace decoder and 2-D(time, frequency)
predictor can be wired up against it next. New public surface:
E_PROB_MODEL: [[[u8; 42]; 2]; 4](336 Q8 bytes; layout
[LM ∈ 0..4][mode ∈ {inter, intra}][band × 2 + {prob, decay}],
matchingdocs/audio/celt/tables/e_prob_model.csvrow-for-row);
shape constantsE_PROB_MODEL_LM_COUNT = 4,
E_PROB_MODEL_MODE_COUNT = 2,E_PROB_MODEL_BYTES_PER_BAND = 2,
E_PROB_MODEL_BYTES_PER_ROW = 42,
E_PROB_MODEL_TOTAL_BYTES = 336; inner-axis index constants
E_PROB_MODEL_MODE_INTER = 0,E_PROB_MODEL_MODE_INTRA = 1;
typed selectorEnergyPredictionMode::{Inter, Intra}with
from_intra_flag(bool)decode helper and atable_index()
accessor;EProbPair { prob: u8, decay: u8 }; typed accessors
e_prob_pair(lm, mode, band) -> Result<EProbPair, EProbModelError>
ande_prob_row(lm, mode) -> Result<&'static [u8; 42], EProbModelError>; intra-case prediction-coefficient constants
INTRA_PRED_ALPHA_Q15 = 0andINTRA_PRED_BETA_Q15 = 4915against
Q15_ONE = 32768per RFC 6716 §4.3.2.1 p. 108
(4915 / 32768 ≈ 0.15). Twenty-two new unit tests (514 lib tests
total, up from 492 at round-28 close) pin the table shape, the Q8
byte values at seven CSV-row spot-checks, theEnergyPredictionMode
mapping, theLmOutOfRange/BandOutOfRangeerror paths, a
total-function sweep over every(LM, mode, band)triple
(4 × 2 × 21 = 168 cells), a pair-vs-row cross-check on every cell,
and the §4.3.2.1 prediction-effectiveness sanity property
(intra_band0_prob < inter_band0_probfor every LM). The
§4.3.2.1 Laplace decoder itself, the 2-D(time, frequency)
predictor application, and the §4.3.2.2 fine-energy follow-up are
out of scope for this module. The per-LM inter-mode
(alpha, beta)pair is a §4.3.2.1 docs gap (the RFC names them as
"depend on the frame size in use" without giving numeric values);
deferred until the docs side delivers the gap fill. -
Clean-room round 28 (2026-06-01): §4.5.1.4 redundant-CELT-frame
decode parameters and cross-lap placement — a new
redundancy_decode_paramsmodule encoding the two normative halves
of RFC 6716 §4.5.1.4 (pp. 126–127). Half 1: the parameter-derivation
rule (no TOC byte, 5 ms fixed duration via
REDUNDANT_FRAME_TENTHS_MS = 50, inherited channel count,
inherited bandwidth with the §4.5.1.4 "MB SILK → WB" exception via
apply_mb_to_wb_override) bundled into
RedundantFrameParams { duration_tenths_ms, channels, bandwidth, position, size_bytes, cross_lap }. Half 2: the cross-lap placement
rule (CrossLapPlacement::FirstHalfAsIsfor
RedundancyPosition::Beginning— CELT → SILK/Hybrid carriers,
where the redundant CELT frame's first 2.5 ms replace the carrier's
leading 2.5 ms and the second 2.5 ms cross-lap;
CrossLapPlacement::SecondHalfAsIsforRedundancyPosition::End
— SILK/Hybrid → CELT carriers, where only the second 2.5 ms is
used and it cross-laps with the SILK/Hybrid trailing edge).
redundant_frame_params(routing, decision)is the pure-function
driver entry;RedundancyDecision::Invalid(the §4.5.1.3 overflow
outcome) andRedundancyDecision::NotPresentboth route toNone.
Twenty-five new unit tests (492 lib tests total, up from 467 at
round-27 close) pin every rule, cross-check four §4.5.3 Figure 18
transition rows, and sweep the total-function output for the
MB-bandwidth invariant. -
Clean-room round 27 (2026-05-31): §4.5.2 SILK + CELT decoder
state-reset policy across mode transitions — a new
mode_transition_resetmodule encoding the four normative rules
of RFC 6716 §4.5.2 (p. 127) as a pure decision function
decide_state_resets(prev_mode, next_mode, redundancy) -> StateReset { silk, celt: CeltResetPlacement }. Rule 1 resets
SILK on every CELT-only → SILK-only/Hybrid transition; rule 2
resets CELT on every mode change into Hybrid or CELT-only except
when redundancy is used; rule 3 places the CELT reset before
the redundant CELT frame on SILK/Hybrid → CELT-only with
redundancy and skips it before the following CELT-only frame;
rule 4 suppresses the CELT reset on CELT-only → SILK/Hybrid
with redundancy.RedundancyDecision::Invalid(the §4.5.1.3
overflow outcome) is treated as no usable redundancy.
CeltResetPlacement::{None, BeforeFrame, BeforeRedundantOnly}
plusStateReset::{celt_resets, is_noop}accessors round out
the public surface. Twenty-seven new unit tests (467 lib tests
total) pin every cell of the 3×3 mode-pair × redundancy
cross-product and cross-check four §4.5.3 Figure 18 transition
rows.