Expand description
Pure-Rust Dolby AC-4 audio decoder foundation.
AC-4 is a complex, hierarchical codec — multiple presentations, nested substream descriptors, ASF/ASF-A2/A-SPX coefficient streams driven by huffman-coded scalefactor data, plus an EMDF metadata sidecar carrying DRC / downmix / dialog-norm info. Full decode is weeks of work.
What this crate lands today (per ETSI TS 103 190-1 V1.4.1):
-
Sync framing —
ac4_syncframe()from Annex G:0xAC40plain and0xAC41CRC-protected, 16-bitframe_size()with 24-bit escape, plus a standalone CRC-16 helper. Seesync. -
Table of contents — full
ac4_toc()walker intoc: bitstream_version, sequence_counter, fs_index, frame_rate_index, b_iframe_global, payload_base, per-presentationac4_presentation_info()(single / multi-substream, configs 0..=5 plus extension escape, HSF extension, pre-virtualised flag, extra EMDF substreams), per-substreamac4_substream_info()(channel_mode prefix decoder, sf_multiplier, bitrate_indicator, content_type w/ language tag, b_iframe),substream_index_table()byte sizes, and thevariable_bits(n)codec. -
Decoder —
decoder::Ac4Decoderaccepts either a sync-wrapped packet (0xAC40/0xAC41prefix) or a bare MP4-styleraw_ac4_framepayload, parses the TOC, and emits a silent S16AudioFramewith the correct channel count, sample rate, and samples-per-frame for the stream configuration. -
ASF substream walker —
asf::walk_ac4_substreamreadsac4_substream()(audio_size + variable_bits extension), the mono/stereo outeraudio_data()layers (mono_codec_mode / stereo_codec_mode, spec_frontend, b_enable_mdct_stereo_proc),asf_transform_info()(Tables 99 / 100 / 103) andasf_psy_info()(Table 106 n_msfb_bits + Tables 109/110 n_grp_bits). Surfaces the result throughdecoder::Ac4Decoder::last_substreamso downstream tooling can see the frame’s tool mix and MDCT window grouping without touching Huffman state. -
Coefficient pipeline —
huffmancarries the normative ASF_HCB_SCALEFAC / ASF_HCB_SNF / ASF_HCB_1..11 tables from Annex A (plus CB_DIM / UNSIGNED_CB);sfb_offsetcarries the Annex B.4-B.7 scale-factor-band offset vectors for the 48 kHz family.asf_datawalksasf_section_data(),asf_spectral_data()(with Pseudocode-19 dim=2/dim=4 split and Pseudocode-20 codebook-11 extension code),asf_scalefac_data()(dpcm-over-reference scale factors withsf_gain = 2^((sf-100)/4)), andasf_snf_data().dequantise_and_scale()appliesrec_spec = sign(q)|q|^(4/3)then multiplies by the band gain. -
MDCT —
mdctimplements the reference AC-4 IMDCT (§5.5.2 pseudocodes 60-64, naive O(N^2) complex DFT) plus the KBD window family (§5.5.3, alphas from Table 186) with overlap-add. -
A-SPX configuration —
aspx::parse_aspx_configimplements the 15-bitaspx_config()element (Table 50, §4.2.12.1) andaspx::parse_companding_controlthecompanding_control()element (Table 49, §4.2.11). The outeraudio_data()walker inasfnow consumes these for the mono ASPX, stereo ASPX, and stereo ASPX_ACPL_{1,2} I-frame paths. For ASPX_ACPL_{1,2} it now also reads the trailingacpl_config_1ch(PARTIAL)/acpl_config_1ch(FULL)element (§4.2.13.1 Table 59) viaacpl::parse_acpl_config_1ch. Exposes the parsedAspxConfigthroughdecoder::Ac4Decoder::last_substream.tools.aspx_configand the A-CPL configs throughacpl_config_1ch_partial/acpl_config_1ch_fullonasf::SubstreamTools. -
A-SPX framing —
aspx::parse_aspx_framingimplementsaspx_framing()(Table 53, §4.2.12.4) end-to-end for all four interval classes (FIXFIX / FIXVAR / VARFIX / VARVAR) including the 1/2/3-bitaspx_int_classprefix code, the envelope-count derivation for FIXFIX (1 << tmp_num_envwithenvbits = aspx_num_env_bits_fixfix + 1), Note-1 1-vs-2-bit field widths driven bynum_aspx_timeslots, theaspx_tsg_ptrsizing viaceil(log2(num_env + 2)), and the I-frame gate onaspx_var_bord_leftfor VARFIX / VARVAR. Returns the fullaspx::AspxFraming(int_class, num_env, num_noise, freq_res vector, border fields, tsg_ptr). Wired intoasf::walk_ac4_substreamfor both the mono ASPX and stereo ASPX I-frame paths: aftercompanding_control()and themono_data()/stereo_data()body the walker readsaspx_xover_subband_offset(3 bits) and thenaspx_framing(0)(and, for stereo,aspx_balance+ conditionalaspx_framing(1)).num_aspx_timeslotsfor the Note-1 field width comes from the TOC’sframe_lengthviaaspx::num_aspx_timeslots(Table 189 × Table 192). -
A-SPX delta direction —
aspx::parse_aspx_delta_dirimplementsaspx_delta_dir(ch)(Table 54, §4.2.12.5): one bit per signal envelope plus one bit per noise envelope. The per- channelAspxDeltaDirdrives whichASPX_HCB_*_{F0,DF,DT}codebook the matchingaspx_ec_data()path will pull from. -
A-SPX HF generation / interleaved-waveform coding (mono) —
aspx::parse_aspx_hfgen_iwc_1chimplements Table 55 (§4.2.12.6): per-subband-grouptna_mode,ah_present+ conditionaladd_harmonic[],fic_present+ conditionalfic_used_in_sfb[], andtic_present+ conditionaltic_used_in_slot[]. Takesnum_sbg_noise,num_sbg_sig_highres,num_aspx_timeslotsfrom the caller. -
A-SPX HF generation / interleaved-waveform coding (stereo) —
aspx::parse_aspx_hfgen_iwc_2chimplements Table 56 (§4.2.12.7). Adds per-channeltna_mode[ch][](withaspx_balance == 1mirroring channel 0 into channel 1), per-channelaspx_ah_left/_rightgates,aspx_fic_presentplus per-channelfic_left/fic_rightgates, and theaspx_tic_copy/aspx_tic_left/aspx_tic_rightTIC gating (including mirroring left-channel TIC into right whentic_copyis set). -
A-SPX Huffman infrastructure —
aspx::AspxHcbis a(len[], cw[], cb_off)codebook helper: the symbol decoder walks one bit at a time until a(len == width, cw == code)match lands, then returnssymbol_index - cb_offas the delta. All 18 Annex A.2 codebooks (Tables A.16..=A.33) are transcribed inaspx_huffman— six(F0, DF, DT)triples covering envelope-LEVEL / envelope-BALANCE @ 1.5 dB / 3 dB plus noise-LEVEL / noise-BALANCE. Aaspx::HuffmanCodebookIdenum plusaspx::lookup_aspx_hcbresolve theget_aspx_hcb(data_type, quant_mode, stereo_mode, hcb_type)tuple from §5.7.6.3.4 Pseudocode 79. -
A-SPX entropy coded data —
aspx::parse_aspx_ec_dataimplementsaspx_ec_data()(Table 57, §4.2.12.8) on top ofaspx::parse_aspx_huff_data(Table 58) — per-envelope loop that picks F0/DF/DT codebook per direction and returns a vector ofaspx::AspxHuffEnvs. -
A-SPX master freq-scale derivation —
aspx::derive_aspx_frequency_tablesimplements §5.7.6.3.1 Pseudocodes 67, 68, 69 and 70: picks betweenaspx::ASPX_SBG_TEMPLATE_HIGHRESandaspx::ASPX_SBG_TEMPLATE_LOWRESbyaspx_master_freq_scale, trims withaspx_start_freq/aspx_stop_freqinto the master subband-group table, then appliesaspx_xover_subband_offsetto produce the high-res / low-res signal tables. The noise subband-group table follows Pseudocode 70’smax(1, floor(aspx_noise_sbg * log2(sbz/sbx) + 0.5))count rule and is clamped tonum_sbg_noise <= 5. Returnsaspx::AspxFrequencyTablescontaining master / high-res / low-res / noise border tables plussba,sbz,sbx,num_sb_aspxand anaspx::AspxSbgCountsready to feedaspx::parse_aspx_ec_data. -
Full A-SPX data-path wiring —
asf::walk_ac4_substreamnow runs the wholeaspx_data_1ch()/aspx_data_2ch()body on I-frame ASPX substreams:aspx_xover_subband_offset→aspx_framing(+ stereoaspx_balance/ second framing) →aspx_delta_dir→ derivedaspx::AspxFrequencyTables→aspx_hfgen_iwc_1ch()/aspx_hfgen_iwc_2ch()→aspx_ec_data()SIGNAL and NOISE per channel. All parsed data lands onasf::SubstreamToolsalongside the existing framing / delta-dir / qmode fields. -
QMF analysis + synthesis filter bank —
qmf::QWINcarries the 640-coefficient QMF prototype window from Annex D.3.qmf::qmf_analysis_slot+qmf::QmfAnalysisBankimplement the §5.7.3.2 Pseudocode 65 forward transform (windowing + 5-fold time-fold to vector u + 64-point complex modulation);qmf::qmf_synthesis_slot+qmf::QmfSynthesisBankimplement the matching §5.7.4.2 Pseudocode 66 inverse transform (shifted 1 280-sampleqsyn_filtdelay line + 128-point modulation + folded-tap 64-way tap sum). The analysis/synthesis pair achieves ~80 dB PSNR end-to-end roundtrip on sine and noise test signals (unit tests inqmf). -
A-SPX HF regeneration scaffold —
aspx::derive_patch_tablesimplements §5.7.6.3.1.4 Pseudocode 71 (patch subband-group table derivation).aspx::hf_tile_copyimplements a simplified §5.7.6.4.1.4 Pseudocode 89 high-band tile copy via the patch table (no chirp/alpha0/alpha1 tonal adjust). The full TNS body lives in the dedicatedaspx_tnsmodule — see below.aspx::apply_flat_envelope_gainis a one-gain scaffold kept as a fallback for the §5.7.6.4.2 HF envelope adjustment tool. Together with the QMF bank these form an end-to-end bandwidth- extension pipeline: PCM → QMF analysis → low-band truncate → HF tile-copy → QMF synthesis → non-silent PCM. -
A-SPX TNS (chirp + α0 + α1) —
aspx_tnsimplements the full §5.7.6.4.1.2 / .1.3 / .1.4 complex-covariance Temporal Noise Shaping path: pre-flatten gain vector (aspx_tns::compute_preflat_gains, Pseudocode 85), complex covariance matrix overQ_low_ext(aspx_tns::compute_covariance, Pseudocode 86), α0 / α1 LPC coefficients with the EPSILON_INV slack and the |α|≥4 fallback (aspx_tns::compute_alphas, Pseudocode 87), per-noise-subband- group chirp factors via the Table 195tabNewChirplookup with attack / decay smoothing (aspx_tns::chirp_factors, Pseudocode 88), and the full HF signal creation that addschirp * α0 * Q_low[n-2]+chirp² * α1 * Q_low[n-4]plus the optional pre-flatten divide (aspx_tns::hf_tile_tns, Pseudocode 89). Per-channel state (aspx_tns::AspxTnsState) carriesaspx_tna_mode_prev[]/prev_chirp_array[]plus the tail of the previous interval’sQ_lowfor thets_offset_hfadj = 4look-back. The decoder auto-selects the TNS path when the parsedaspx_hfgen_iwc_*providesaspx_tna_mode[ch][]and the framing is FIXFIX; otherwise it falls back to the bare tile copy. -
A-SPX HF envelope adjustment (per-envelope gain) —
aspx::AspxEnvelopeAdjusterimplements §5.7.6.4.2 Pseudocodes 90 + 91 + 95 (non-harmonic, non-limited path): delta-decodeaspx_data_sig/aspx_data_noise(Pseudocodes 80 / 81) viaaspx::delta_decode_sig/aspx::delta_decode_noise, dequantize toscf_sig_sbg/scf_noise_sbg(Pseudocodes 82 / 83) viaaspx::dequantize_sig_scf/aspx::dequantize_noise_scf, estimate the actual HF envelope energy (aspx::estimate_envelope_energy), map subband-group scale factors onto QMF subbands (aspx::map_scf_to_qmf_subbands), then compute per-subband compensatory gains (aspx::compute_sig_gains) =sqrt(scf_sig / ((1 + est) * (1 + scf_noise))). The per-envelope gains are applied viaaspx::apply_envelope_gainsusing the FIXFIX Table-194atsg_sig/atsg_noiseborders derived byaspx::derive_fixfix_atsg. The decoder auto-selects the per-envelope path when the substream parsed FIXFIX framing plus matching envelope deltas, and falls back toapply_flat_envelope_gain(0.5)otherwise. -
ASPX decoder wiring —
decoder::Ac4Decodernow routes ASPX substreams through the extension pipeline: when an I-frame ASPX substream produces derivedaspx_frequency_tables, the decoder takes the IMDCT low-band PCM, runs QMF analysis → tile-copy HF regen → per-envelope gain (or flat-gain fallback) → QMF synthesis, and emits bandwidth-extended PCM instead of silence. -
Dialogue Enhancement (DE) parser —
de::parse_dialog_enhancementwalks thedialog_enhancement(b_iframe)element (§4.2.14.11 Table 76) end-to-end:b_de_data_presentgate, optional I-framede_config()(§4.2.14.12 Table 77,de_method/de_max_gain/de_channel_config), and the per-framede_data()payload (§4.2.14.13 Table 78) including the cross-channelde_keep_pos_flag+de_mix_coef[12]_idxpanning parameters, thede_keep_data_flagre-use gate, thede_ms_proc_flagM/S processing flag, and the per-channel per-bandde_par[ch][band]matrix decoded via the Annex A.4 Huffman codebooks (de_huffman::de_abs_huffman/de_huffman::de_diff_huffman, Tables A.58..A.61). The four codebooks (DE_HCB_ABS_0/DE_HCB_DIFF_0/DE_HCB_ABS_1/DE_HCB_DIFF_1) are transcribed verbatim from the normative ETSI accompaniment filets_10319001v010401p0-tables.cand are verified by Kraft-sum = 1 and prefix-code unit tests. -
DRC metadata parser —
drc::parse_drc_framewalks thedrc_frame()element (§4.2.14.5 Table 70) end-to-end:b_drc_presentgate, optional I-framedrc_config()(§4.2.14.6 Table 71) including up to eightdrc_decoder_mode_config()blocks with all three branches (drc_repeat_profile_flag,drc_default_profile_flag, explicitdrc_compression_curve()), the fulldrc_compression_curve()with optional boost / cut sections and per-mode time-constant block (§4.2.14.8 Table 73), and the per-framedrc_data()payload (§4.2.14.9 Table 74) that pulls onedrc_gains()entry per gainset mode.drc::parse_drc_gainsdecodes the seven-bitdrc_gain_valseed plus all(ch, band, sf)deltas through the Annex A.5DRC_HCBHuffman codebook (huff_decode_diffper §4.3.10.8.3), with the per-band / per-channelref_drc_gainreset semantics from Table 75 honoured. The Annex A.5 codebook itself (drc_huffman::DRC_HCB_LEN/drc_huffman::DRC_HCB_CW) is transcribed verbatim from the ETSI accompaniment filets_10319001v010401p0-tables.cand is verified by a Kraft-sum = 1 unit test (complete prefix code) plus an explicit prefix- code check. -
Metadata walker —
metadata::parse_metadataimplements the outermetadata(b_iframe)element (§4.2.14.1 Table 66) end-to-end:basic_metadata(channel_mode)(§4.2.14.2 Table 67) including theb_more_basic_metadatablock with optionalfurther_loudness_info(§4.2.14.3 Table 68), the stereo / multi-channel downmix info tracks, the 5.x-onlypre_dmixtyp_5ch/pre_upmixtyp_5chand 7.x-onlypre_upmixtyp_3_4/pre_upmixtyp_3_2_2paths, and theb_dc_blockingflag;extended_metadata(channel_mode, b_associated, b_dialog)(§4.2.14.4 Table 69) including the per-channelb_*_active/b_*_has_dialogchannels-classifier block; thetools_metadata_size_value(7-bit + optionalvariable_bits(3) << 7extension) hint; dispatch intodrc::parse_drc_frameandde::parse_dialog_enhancement; and the trailingb_emdf_payloads_substreamflag. The walker chains ametadata::MetadataStateforward across frames so non-I frames re-use the most recentdrc_config()/de_config()per the bitstream’s gating semantics. After DRC + DE consume their bytes the walker reconciles againsttools_metadata_sizeand skips any trailing reserved bits inside the announced envelope, providing forward compatibility against future tools-metadata extensions. -
A-CPL parameter↔QMF subband mapping —
acpl::sb_to_pbimplements §5.7.7.2 Table 197 for all fouracpl_num_param_bandsconfigurations (15 / 12 / 9 / 7), the last piece needed to wireacpl_data_*ch()parameters through to QMF subbands during synthesis. -
A-CPL synthesis math —
acpl_synthimplements the §5.7.7 QMF-domain synthesis pipeline end-to-end:acpl_synth::differential_decode(§5.7.7.7 Pseudocode 121) recovers absoluteacpl_<SET>_qarrays from the Huffman deltas produced byacpl::parse_acpl_data_1ch/acpl::parse_acpl_data_2ch, with state carried across parameter sets and AC-4 frames viaacpl_synth::AcplDiffState;acpl_synth::dequantize_alpha_beta/acpl_synth::dequantize_beta3/acpl_synth::dequantize_gammaapply Tables 203-208 (with the cross-coupled Tables 203/204 and 205/206ibetalinkage);acpl_synth::interpolate(§5.7.7.3 Pseudocode 109) covers both smooth (linear-between-borders) and steep (timeslot-keyed) per-QMF-subsample interpolation;acpl_synth::InputSignalModifier(§5.7.7.4.2 Pseudocode 111) implements the three frequency-region all-pass IIR decorrelatorsD0/D1/D2over Tables 198-201;acpl_synth::TransientDucker(§5.7.7.4.3 Pseudocodes 112-114) carries the per-pb peak-decay / smooth state and emitsduck_gain[pb];acpl_synth::acpl_module(§5.7.7.5 Pseudocode 116) andacpl_synth::run_pseudocode_115_pair(Pseudocode 115) wire the channel-pair element together end-to-end with theacpl_qmf_bandM/S split below the threshold and the alpha/beta-modulated decorrelator mix above. -
A-CPL decoder wiring —
asf::walk_ac4_substreamnow consumes the fullaspx_data_1ch()(Table 51) +acpl_data_1ch()(Table 61) tail of theASPX_ACPL_2stereo path: the mono MDCT body parser ([asf::parse_aspx_acpl2_mdct_body] internal) walks thespec_frontend; sf_info; sf_datashape, then the shared [asf::parse_aspx_data_1ch_body] helper reads the leading xover-offset + framing + delta-dir + hfgen + ec_data, and finallyacpl::parse_acpl_data_1chis invoked withnum_bands=acpl_num_param_bandsandstart_band=sb_to_pb(acpl_qmf_band, num_param_bands)per Table 61. The parsed payload lands onasf::SubstreamTools::acpl_data_1ch.decoder::Ac4Decodernow drivesacpl_synth::run_acpl_1ch_pcm(mono PCM → QMF analysis → §5.7.7.5 channel-pair element → QMF synthesis × 2) when the substream provides anacpl_config_1chplusacpl_data_1ch, emitting two PCM channels in place of the duplicate-of-primary fallback. Per-substreamacpl_synth::AcplSubstreamState(alpha-diff + beta-diff +AcplCpeStatedecorrelator + ducker) lives on the decoder so IIR delay-lines andacpl_<SET>_q_prevsurvive across frames. ASPX_ACPL_1’s joint-MDCT residual layer (b_dual_maxsfb = 1 withchparam_info()) now walks end-to-end as of round-18:asf::parse_chparam_info(§4.2.10.1 Table 47) +asf::parse_sap_data(Table 48) drive the joint shell,parse_aspx_acpl1_mdct_bodywalks the dual M/S residuals (long frame + single window group), and the decoder feeds both intoacpl_synth::run_acpl_1ch_pcm_stereo(x0 = M, x1 = S into Pseudocode 116) for the full stereo synth. -
Speech Spectral Frontend (SSF) tables + arithmetic decoder core — the full Annex C scalar-table inventory now lands in
ssf_tables:POST_GAIN_LUT(C.1),PRED_GAIN_QUANT_TAB(C.3),PRED_RFS_TABLE/PRED_RTS_TABLE(C.4 / C.5), the 705-entryCDF_TABLE(C.7),PREDICTOR_GAIN_CDF_LUT(C.8),ENVELOPE_CDF_LUT(C.9), the 256-entryDITHER_TABLE(C.10) andRANDOM_NOISE_TABLE(C.11),STEP_SIZES_Q4_15(C.12),AC_COEFF_MAX_INDEX(C.13), and the fourSLOPES_*/OFFSETS_*dB↔linear LUTs (C.14). The 37 SSF prediction- coefficient matrices from Annex C.6 (~22 KB total) live inssf_pred_coeffaddressable viassf_pred_coeff::ssf_pred_coeff_mat. Every byte in every table is validated against the ETSI accompaniment file by thevalidate_ssf_*integration tests. The arithmetic decoder itself (ssf_ac::AcState) implements §5.2.8 Pseudocodes 41-47 (AcDecoderInit/AcDecodeTarget/AcDecode/AcDecodeSymbolExtCdf/AcDecodeFinish) plus Pseudocode 51-53 (Idx2Reconstruction+CdfEstfor the computed-CDF transform-coefficient path) and the §5.2.8.3 random-number generator (ssf_ac::SsfRandGenState, Pseudocodes 54-57). Wired-up convenience functions:ssf_ac::decode_envelope_indices(Pseudocode 48),ssf_ac::decode_predictor_gain(Pseudocode 49),ssf_ac::decode_coefficient_indices(Pseudocode 50). Thessf_data()/ssf_granule()/ssf_st_data()/ssf_ac_data()bitstream walkers (Tables 43-46) are the next round’s scope — the AC decoder building blocks are now in place. -
SSF bitstream walker —
ssf::parse_ssf_data/ssf::parse_ssf_granule/ssf::parse_ssf_st_data/ssf::parse_ssf_ac_dataimplement Tables 43-46 end-to-end. The walker derives the SSF block layout per Table 112 (48 kHz family) viassf::SsfFrameConfig::from_frame_len_base, buildsstart_bin[]/end_bin[]/num_binsfrom the Annex C.1 bandwidths matrix (ssf::SSF_BANDWIDTHS) per §4.3.7.5 Pseudocode 7, drains the per-block predictor / static fields, and drives the §5.2.8 arithmetic decoder (ssf_ac::AcState) forenv_curr_ac_bits/env_startup_ac_bits/predictor_gain_ac_bits[block]/q_mdct_coefficients_ac_bits[block]. Per-channelssf::SsfChannelStatecarries forward dither / noise RNG state (reset per SSF-I-frame per Pseudocode 55) plusprev_pred_lag_idx/last_num_bands/env_prev[]. The walker is wired intoasf::walk_ac4_substreamfor both the mono path (spec_frontend == SSFno longer returnsUnsupported) and the split-MDCT stereo + ASPX_ACPL_1 paths (per-channel SSF/ASF selection). Parsed payload lands onasf::SubstreamTools::ssf_data_primary/ssf_data_secondaryfor downstream synthesis.
Known gaps (Unsupported or stubbed):
- Short / grouped frames (
num_window_groups > 1) — round 28 lands the mono / stereosf_data(ASF)walker per Tables 39-42 (eachasf_*_data()body has its own outerfor (g; ...)loop, with a singlereference_scale_factorand singleb_snf_data_existsat the head). Multichannel layouts (5.X / 7.X) still use the r24 per-group interleaved walker. MDCT synthesis for the per-group spectra (concatenated group-major intools.scaled_spec_primary/tools.scaled_spec_secondary) is not yet hooked through the decoder. - Remaining §5.7.6.4 A-SPX HF regeneration — non-FIXFIX interval
classes (FIXVAR / VARFIX / VARVAR) still fall back to the
flat-gain scaffold; the limiter (§5.7.6.4.2.2) and TNS
(§5.7.6.4.1) paths only run on FIXFIX framing today. The TNS
pipeline is fully implemented in
aspx_tnsbut per-channelmaster_resetsemantics (resettingprev_chirp_array/ theQ_low_prevhistory) when a new substream starts mid-stream isn’t surfaced through the decoder API yet. - A-CPL data-path decoder hookup —
ASPX_ACPL_2(mono MDCT body) was fully wired in round-17, andASPX_ACPL_1(joint-MDCT body withchparam_info()driving M/S coupling) is now wired in round-18: parser walks the full dual-residual body, decoder IMDCTs both M and S spectra and feeds them asx0/x1into the §5.7.7.5 channel-pair element. Round-21 lands the §5.7.7.6.2 ASPX_ACPL_3 transform-matrix synthesis math (Transform(),ACplModule2(),ACplModule3(),run_pseudocode_118_5x()— Pseudocodes 118 / 119); the 5_X-walker glue from the bitstream into the new transform synthesis is the next round’s scope. Multichannel5_X_codec_mode = ASPX_ACPL_1/ASPX_ACPL_2wrappers (Pseudocode 117) are still pending — the building blocks are all in place but the 5-input wrapper is not wired. - Speech Spectral Frontend (SSF) PCM synthesis — round 31 lands
the §5.2.3-5.2.7 chain in
ssf_synth: envelope decoder (ssf_synth::decode_envelope/ssf_synth::interpolate_envelope/ssf_synth::decode_gains/ssf_synth::refine_envelope— Pseudocodes 4a-4d), predictor parameter calculation (ssf_synth::decode_predictor— Pseudocode 4e), helper variables and lossless-decoding allocation table (ssf_synth::compute_helpers/ssf_synth::build_alloc_table— Pseudocodes 26 + 31 no-rfu path), inverse quantizer (ssf_synth::inverse_quantize_block/ssf_synth::mmse_laplace— Pseudocodes 32 / 33), inverse heuristic scaling (ssf_synth::inverse_heuristic_scale— Pseudocode 34), C-matrix reconstruction (ssf_synth::build_c_matrix— Pseudocode 39), subband predictor (ssf_synth::SubbandPredictorState::run— Pseudocodes 35-37) and inverse flattening (ssf_synth::inverse_flatten— Pseudocode 38). The decoder (decoder::Ac4Decoder::receive_frame) now consumestools.ssf_data_primary/tools.ssf_data_secondaryand runssynthesize_ssf_data→ IMDCT → KBD overlap-add per channel, producing real PCM in place of silence for SSF substreams. The heuristic-scaling helpers (§5.2.5.2.2 Pseudocodes 27 / 28 / 29 / 30) are deferred — the spec’sf_rfu == 0short-circuit short-circuits to the no-heuristic path the synth already supports, covering any block with the predictor disabled. - Spectral noise fill synthesis —
asf_snf_data()parses the Huffman-coded indices but doesn’t inject shaped noise into zero bands yet. emdf_payloads_substream()parsing — the outermetadata::parse_metadatawalker errors out whenb_emdf_payloads_substream == 1rather than mis-aligning the bitstream. Implementing §4.2.4.4 / §4.2.14.14 EMDF payloads is the next step before real-bitstream metadata can fully round-trip.walk_ac4_substreamitself doesn’t yet invoke the metadata walker — that wiring is the follow-up to this round.- TS 103 190-2 IFM (immersive / object) decoding — round 47 lands the
v2 TOC walker (
bitstream_version >= 2dispatch intoc::parse_ac4_tocrunningac4_presentation_v1_info()per §6.2.1.3 +ac4_substream_group_info()per §6.3.2.5 +ac4_substream_info_chan()per §6.2.1.8) and the matchingencoder_ims::Ac4ImsEncodertone-encoder (encoder_ims::Ac4ImsEncoder::encode_frame_mono_tone/encoder_ims::Ac4ImsEncoder::encode_frame_mono_tone_at_hz) that produces a v2 frame whose mono SIMPLE/ASF audio body round-trips throughdecoder::Ac4Decoderto non-silent PCM. Object / a-joc substream parsing insideac4_substream_group_info()is still deferred — the walker surfacesUnsupportedon the first object substream. - Encoder for arbitrary PCM input — round 47 ships a closed-form
canned-tone encoder
(
encoder_ims::build_mono_simple_asf_tone_body). MDCT analysis, scalefactor selection, and ASF entropy coding for arbitrary input PCM are the next step.
The decoder emits real PCM for long-frame, single-window-group
mono and stereo SIMPLE/ASF streams. The stereo path covers both
the split-MDCT layout (two independent ASF spectra) and the joint
b_enable_mdct_stereo_proc == 1 mode (shared sections +
scalefactors, two residuals, per-sfb ms_used[] inverse
L = M + S / R = M - S per §7.5). Everything else falls back to
silence with a correctly-shaped AudioFrame.
Modules§
- acpl
- Advanced Coupling (A-CPL) parser plumbing — ETSI TS 103 190-1 §4.2.13 / §4.3.11.
- acpl_
huffman - A-CPL (Advanced Coupling) Huffman codebooks (Annex A.3, Tables A.34..A.57 of ETSI TS 103 190-1 V1.4.1).
- acpl_
synth - A-CPL (Advanced Coupling) QMF synthesis math — ETSI TS 103 190-1 §5.7.7.
- asf
- AC-4 Audio Spectral Frontend (ASF) substream baseline.
- asf_
data - ASF data-payload parsers — the Huffman-driven body of
asf_section_data(),asf_spectral_data(),asf_scalefac_data()andasf_snf_data()(ETSI TS 103 190-1 §4.2.8.3 / §4.2.8.4 / §4.2.8.5 / §4.2.8.6 and §5.1.2 / §5.1.3). - aspx
- AC-4 Advanced Spectral Extension (A-SPX) parameter parsing.
- aspx_
huffman - A-SPX envelope / noise Huffman codebooks (Annex A.2, Tables A.16..A.33).
- aspx_
limiter - A-SPX gain limiter — ETSI TS 103 190-1 §5.7.6.4.2.2 Pseudocodes
96..101 plus the §5.7.6.3.1.5
sbg_limderivation (Pseudocodes 72..74). - aspx_
noise - A-SPX noise generator (§5.7.6.4.3) + Annex D.2 NoiseTable.
- aspx_
tns - A-SPX Temporal Noise Shaping (complex-covariance LPC + chirp).
- aspx_
tone - A-SPX tone generator (§5.7.6.4.4) + Table 196 SineTable.
- de
- Dialogue Enhancement (DE) parser — §4.2.14.11..13 syntax,
§4.3.14 semantics. Walks
dialog_enhancement(b_iframe)(Table 76) end-to-end, includingde_config()(Table 77, §4.3.14.3) andde_data()(Table 78, §4.3.14.4) plus thede_par[ch][band]decoding that runs through the Annex A.4 Huffman codebooks (crate::de_huffman). - de_
huffman - Dialogue Enhancement (DE) Huffman codebooks (Annex A.4, Tables A.58..A.61 of ETSI TS 103 190-1 V1.4.1).
- decoder
- Foundation AC-4 decoder.
- drc
- Dynamic Range Control (DRC) metadata parsing — §4.2.14.5..10 syntax,
§4.3.13 semantics. Pure parser: walks the bitstream and surfaces the
decoded fields, plus the per-(channel, subframe, band) DRC gain
matrix decoded via the Annex A.5 Huffman codebook
(
crate::drc_huffman). - drc_
huffman - DRC Huffman codebook (Annex A.5, Table A.62 of ETSI TS 103 190-1).
- emdf
- EMDF payloads substream parser — TS 103 190-1 V1.4.1.
- encoder_
acpl3 - 5_X ASPX_ACPL_3 multichannel encoder per ETSI TS 103 190-1 §4.2.6.6
Table 25 row
case ASPX_ACPL_3:(round 95). - encoder_
asf - Forward ASF entropy coding for the AC-4 IMS encoder (round 48).
- encoder_
ims - AC-4 IMS (Immersive Multichannel Service) encoder scaffold.
- encoder_
mdct - Forward MDCT analysis for the AC-4 IMS encoder (round 48).
- huffman
- ASF Huffman codebooks from ETSI TS 103 190-1 Annex A.
- mch
- Multichannel
5_X_channel_elementwalker family — round 20 wiring. - mdct
- AC-4 IMDCT and KBD window synthesis (ETSI TS 103 190-1 §5.5).
- metadata
- Outer §4.2.14.1
metadata()walker — TS 103 190-1 V1.4.1 Table 66. - qmf
- AC-4 QMF analysis / synthesis filter-bank (§5.7.1 – 5.7.4).
- sfb_
offset - Scale-factor-band offset tables (Annex B.4-B.7 of ETSI TS 103 190-1).
- ssf
- AC-4 Speech Spectral Frontend (SSF) bitstream walker.
- ssf_ac
- AC-4 Speech Spectral Frontend (SSF) arithmetic decoder.
- ssf_
pred_ coeff - AC-4 Annex C.6 — SSF prediction-coefficient matrices.
- ssf_
synth - AC-4 Speech Spectral Frontend (SSF) synthesis chain.
- ssf_
tables - AC-4 Annex C scalar lookup tables (TS 103 190-1 V1.4.1).
- sync
- AC-4 sync-frame helpers (TS 103 190-1 Annex G).
- tables
- Normative AC-4 lookup tables (ETSI TS 103 190-1 Annex B and §4.3.6).
- toc
ac4_toc()— AC-4 table-of-contents parser.
Constants§
- CODEC_
ID_ STR - Canonical codec id.
Functions§
- register
- Unified registration entry point — installs AC-4 into the codec
sub-registry of the supplied
oxideav_core::RuntimeContext. - register_
codecs - Register the AC-4 decoder in a codec registry.