pub struct Ac4ImsEncoder {
pub bitstream_version: u8,
pub sequence_counter: u16,
pub fs_index: u8,
pub frame_rate_index: u8,
pub b_iframe_global: bool,
pub channel_mode_value: u8,
pub channel_mode_bits: u8,
pub mdct_state: Option<EncoderMdctState>,
pub mdct_state_r: Option<EncoderMdctState>,
pub mdct_states_multi: Vec<EncoderMdctState>,
}Expand description
Encoder-side builder for AC-4 IMS frames. One instance per audio
stream — carries the 10-bit sequence_counter rolling counter and
the canonical frame layout (sample rate, frame-rate index, channel
mode) so each encode_frame() call produces a structurally-valid
output frame ready to wrap in a sync-frame (0xAC40 / 0xAC41)
or hand to an MP4 muxer.
Round 46 lands the Auditor-mode bit layout per ETSI TS 103 190-2 §6.2.1.1 — the audio body itself is all-zero placeholder bits.
Fields§
§bitstream_version: u8bitstream_version value to emit (TS 103 190-2 Table 74).
0 selects the TS 103 190-1 v0 path (ac4_presentation_info()
per-pres); 2 selects the IMS path
(ac4_presentation_v1_info() + ac4_substream_group_info()).
sequence_counter: u16Rolling 10-bit sequence_counter field — wraps modulo 1024.
fs_index: u8fs_index (1 b): 0 → 44.1 kHz, 1 → 48 kHz.
frame_rate_index: u8frame_rate_index (4 b) per Table 83 / 84.
b_iframe_global: boolb_iframe_global flag for this frame.
channel_mode_value: u8Channel mode prefix code per Table 85 (TS 103 190-1) / Table
78 (TS 103 190-2): 0b0 → mono, 0b10 → stereo, etc.
Encoded as the literal prefix in the low-order bits of
channel_mode_value with the bit count in
channel_mode_bits.
channel_mode_bits: u8Bit-width of channel_mode_value (1..=11).
mdct_state: Option<EncoderMdctState>Forward-MDCT analysis state for encode_frame_pcm(). Carries
the previous frame’s N PCM samples so the 50% TDAC overlap
runs correctly across frames. Lazy-initialised on first use.
mdct_state_r: Option<EncoderMdctState>Forward-MDCT analysis state for the secondary (right) channel of
encode_frame_pcm_stereo(). Identical role to mdct_state but
for the second channel — separate so 50% TDAC overlap is
per-channel.
mdct_states_multi: Vec<EncoderMdctState>Forward-MDCT analysis state for the multichannel encoder paths
(encode_frame_pcm_5_0() and any future N>2 variants). One
EncoderMdctState per output channel — separate so 50% TDAC
overlap continuity is preserved per channel across frames. Lazy-
initialised on first use; grown to the required channel count.
Implementations§
Source§impl Ac4ImsEncoder
impl Ac4ImsEncoder
Sourcepub fn new() -> Self
pub fn new() -> Self
New encoder defaulting to the smallest-valid IMS shape:
bitstream_version = 2, sequence_counter = 0, 48 kHz, 24 fps
(frame_rate_index = 1), b_iframe_global = 1, mono channel
mode (0b0, 1 b).
Sourcepub fn with_v0(self) -> Self
pub fn with_v0(self) -> Self
Switch to a TS 103 190-1 v0 frame layout. The decoder in this crate parses v0 today; v2 is structurally emitted but not yet re-parsed end-to-end.
Sourcepub fn with_stereo(self) -> Self
pub fn with_stereo(self) -> Self
Stereo channel mode (0b10, 2 b).
Sourcepub fn with_5_0(self) -> Self
pub fn with_5_0(self) -> Self
5.0 channel mode (0b1101, 4 b) per Table 85 — channel_mode 3 —
the 5.0 surround layout (L, R, C, Ls, Rs) without LFE. Drives the
decoder’s 5_X_channel_element() walker for channels == 5 (no
b_has_lfe block) and the corresponding dispatch_5x_cfg3_simple_aspx
PCM output path.
Sourcepub fn with_7_0(self) -> Self
pub fn with_7_0(self) -> Self
7.0 (3/4/0) channel mode (0b1111000, 7 b) per ETSI TS 103 190-1
§4.3.3.7.1 Table 88 — channel_mode value 1111000 → ch_mode 5 → 7
channels with layout L, C, R, Ls, Rs, Lb, Rb. Drives the decoder’s
7_X_channel_element() walker for channels == 7 (no b_has_lfe
— that branch is gated on channel_mode 6 / 7.1) per §4.2.6.14
Table 33. The decoder’s internal coding order for the inner
five_channel_data() is [L, R, C, Ls, Rs] per Table 180 (the
inner SCE order differs from the surface Table 88 listing’s L, C, R ordering — the decoder treats the inner five_channel_data slots
as L/R/C/Ls/Rs).
Sourcepub fn with_7_1(self) -> Self
pub fn with_7_1(self) -> Self
7.1 (3/4/0.1) channel mode (0b1111001, 7 b) per ETSI TS 103 190-1
§4.3.3.7.1 Table 88 — channel_mode value 1111001 → ch_mode 6 → 8
channels with layout L, C, R, Ls, Rs, Lb, Rb, LFE. Drives the
decoder’s 7_X_channel_element() walker for channels == 8 (with
b_has_lfe) per §4.2.6.14 Table 33. The decoder’s internal coding
order for the inner five_channel_data() is [L, R, C, Ls, Rs]
per Table 180 (the inner SCE order differs from the surface
Table 88 listing’s L, C, R ordering — the decoder treats the
inner five_channel_data slots as L/R/C/Ls/Rs).
Sourcepub fn encode_frame(&mut self, body_padding_bytes: usize) -> Vec<u8> ⓘ
pub fn encode_frame(&mut self, body_padding_bytes: usize) -> Vec<u8> ⓘ
Encode one Auditor-mode frame: emits a raw_ac4_frame()
payload (TOC + minimum-viable substream skeleton) and bumps
sequence_counter. Returns the produced bytes.
Sourcepub fn encode_frame_v0(&mut self, body_padding_bytes: usize) -> Vec<u8> ⓘ
pub fn encode_frame_v0(&mut self, body_padding_bytes: usize) -> Vec<u8> ⓘ
Encode the same frame at bitstream_version = 0 regardless of
the encoder’s configured version — used by the round-trip test
to feed a TS 103 190-1-decodable frame back through
crate::toc::parse_ac4_toc.
Source§impl Ac4ImsEncoder
impl Ac4ImsEncoder
Sourcepub const STEREO_JOINT_MS_CORRELATION_THRESHOLD: f32 = 0.7
pub const STEREO_JOINT_MS_CORRELATION_THRESHOLD: f32 = 0.7
Round-52 heuristic threshold for joint M/S coding. When the
per-SFB average Pearson correlation between L and R MDCT spectra
exceeds this value, the encoder switches to Path B (joint M/S CPE,
b_enable_mdct_stereo_proc == 1); otherwise Path A (split-MDCT,
2× SCE) is used. The 0.7 threshold matches the spec’s §5.3
guidance plus the headline number cited in this crate’s round-52
task brief.
Sourcepub fn encode_frame_mono_tone(
&mut self,
tone_cb_idx: usize,
tone_pair_idx: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_mono_tone( &mut self, tone_cb_idx: usize, tone_pair_idx: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a mono SIMPLE/ASF audio
substream that injects a single quantised spectral tone (per
tone_cb_idx from the ETSI Annex A HCB5 codebook). The decoder
dequantises the tone via rec_spec = sign(q)|q|^(4/3) and the
IMDCT + KBD windowing produce real, non-silent PCM.
This is the canned-tone closed-form encoder mentioned in round-47
scope: full MDCT analysis + scalefactor optimisation + ASF
entropy coding for arbitrary PCM input is deferred. The shape
of this method (input PCM → bytes) is reserved for that future
work; for now it ignores its _input_pcm argument and emits
the canned tone payload.
Per ETSI TS 103 190-1 §5.7 + §5.8.
Sourcepub fn encode_frame_pcm(&mut self, frame: &[f32]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm(&mut self, frame: &[f32]) -> Vec<u8> ⓘ
Encode one IMS v2 mono frame from arbitrary float PCM input
(range [-1.0, 1.0]). Returns the produced frame bytes.
Pipeline (round 48):
- Forward MDCT analysis with KBD windowing across the 50% TDAC
boundary (carries prior-frame
Nsamples in the per-encoderEncoderMdctState). - Per-band scalefactor selection (greedy nearest power-of-two that keeps |q| within the chosen Huffman codebook’s bound).
- Quantisation per Pseudocode 18 inverse:
q = round(sign(c) * (|c|/sf_gain)^(3/4)). - ASF entropy coding via HCB5 (signed dim=2, q-range -4..=+4).
- Wrap in v2 IMS TOC + single-substream-group
audio_sizebody.
Frame length is derived from the encoder’s
(fs_index, frame_rate_index) pair via crate::toc::frame_rate_entry.
For the default mono 48 kHz / 24 fps configuration frame.len() is
1920 samples and max_sfb is 10 (matching the canned-tone helper).
Per ETSI TS 103 190-1 §5.5 (MDCT) + §5.7 / §5.8 (SIMPLE/ASF) + TS 103 190-2 §6.2.1.1 (IMS TOC).
Sourcepub fn encode_frame_pcm_with_max_sfb(
&mut self,
frame: &[f32],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_with_max_sfb( &mut self, frame: &[f32], max_sfb: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 mono frame from arbitrary float PCM input
(range [-1.0, 1.0]) at a caller-specified max_sfb. Larger
values widen the encoder’s frequency coverage at the cost of
more bits per frame:
max_sfb = 40→ bins 0..508 → ~6.35 kHz @ tl=1920max_sfb = 50→ bins 0..1216 → ~15.2 kHz @ tl=1920max_sfb = 55→ bins 0..1600 → ~20.0 kHz @ tl=1920
max_sfb must satisfy max_sfb <= num_sfb_48(frame_len) (61 at
tl=1920). The pad budget scales with max_sfb so the announced
audio_size reliably exceeds the actual emission length.
Sourcepub fn encode_frame_pcm_stereo(
&mut self,
frame_l: &[f32],
frame_r: &[f32],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_stereo( &mut self, frame_l: &[f32], frame_r: &[f32], ) -> Vec<u8> ⓘ
Encode one IMS v2 stereo frame from arbitrary float PCM input
(range [-1.0, 1.0]) for both L and R. Returns the produced
frame bytes.
Path A — 2× SCE (split-MDCT) per ETSI TS 103 190-1 §5.3 +
§4.2.6.3 Table 22 (stereo_data() with
b_enable_mdct_stereo_proc == 0): each channel is encoded
independently with the shared forward analysis pipeline (KBD-
windowed MDCT, per-band scalefactor, DP-optimal sectioning,
HCB1..11 codebook selection, SNF emission). No joint M/S coding.
frame_l / frame_r must each be exactly frame_len samples
long (1920 samples for the default 48 kHz / 24 fps configuration).
The encoder forces stereo channel mode (channel_mode_value = 0b10) for this call. The decoder’s
[crate::asf::parse_stereo_data_body_stateful] split-MDCT path
consumes the frame and reconstructs both channels through the
shared ASF Huffman pipeline.
max_sfb defaults to 40 (matching the round-48 mono default,
covers bins 0..508 ≈ 0..6.35 kHz at tl = 1920) when called via
Self::encode_frame_pcm_stereo; use
Self::encode_frame_pcm_stereo_with_max_sfb for wider coverage.
The decoder’s split-MDCT branch reads BOTH L and R max_sfb with
the full n_msfb_bits width (the spec’s b_side_limited only
applies to joint-MDCT stereo per §4.3.6.2), so the encoder isn’t
limited by the narrower n_side_bits.
Per ETSI TS 103 190-1 §5.3 + §4.2.6.3 + §5.5 (MDCT) + §5.7 / §5.8 (SIMPLE/ASF) + TS 103 190-2 §6.2.1.1 (IMS TOC).
Sourcepub fn encode_frame_pcm_stereo_with_max_sfb(
&mut self,
frame_l: &[f32],
frame_r: &[f32],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_stereo_with_max_sfb( &mut self, frame_l: &[f32], frame_r: &[f32], max_sfb: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 stereo frame from arbitrary float PCM input
(range [-1.0, 1.0]) at a caller-specified max_sfb. Both
channels use the same max_sfb — the encoder uses the full
n_msfb_bits field width for both. See
Self::encode_frame_pcm_stereo.
Round 52 — Path A vs Path B dispatch. The encoder computes the
per-SFB average Pearson correlation between the L and R MDCT
spectra (via average_per_sfb_correlation) and, when it exceeds
Self::STEREO_JOINT_MS_CORRELATION_THRESHOLD (default 0.7),
switches to joint M/S CPE (Path B,
b_enable_mdct_stereo_proc == 1) per ETSI TS 103 190-1 §5.3 +
§4.2.6.3 Table 22 + §7.5 (Pseudocode 77). Otherwise it stays on
the round-51 split-MDCT path (Path A, 2× SCE,
b_enable_mdct_stereo_proc == 0). Per-SFB M/S vs L/R selection
within the joint path is driven by the natural-q bit-cost
comparison inside
build_stereo_simple_asf_joint_body_from_pcm_spectra.
Use Self::encode_frame_pcm_stereo_split_with_max_sfb or
Self::encode_frame_pcm_stereo_joint_with_max_sfb to force a
specific path regardless of correlation.
Sourcepub fn encode_frame_pcm_stereo_split_with_max_sfb(
&mut self,
frame_l: &[f32],
frame_r: &[f32],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_stereo_split_with_max_sfb( &mut self, frame_l: &[f32], frame_r: &[f32], max_sfb: u32, ) -> Vec<u8> ⓘ
Force the split-MDCT (Path A: 2× SCE) encoder path regardless of
the L-vs-R correlation. Useful for tests / fixtures that need a
deterministic on-wire layout. See
Self::encode_frame_pcm_stereo_with_max_sfb.
Sourcepub fn encode_frame_pcm_stereo_joint_with_max_sfb(
&mut self,
frame_l: &[f32],
frame_r: &[f32],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_stereo_joint_with_max_sfb( &mut self, frame_l: &[f32], frame_r: &[f32], max_sfb: u32, ) -> Vec<u8> ⓘ
Force the joint-MDCT (Path B: M/S CPE) encoder path regardless of
the L-vs-R correlation. Useful for tests / fixtures that need a
deterministic on-wire layout. See
Self::encode_frame_pcm_stereo_with_max_sfb.
Sourcepub fn encode_frame_pcm_5_0(&mut self, frames: &[&[f32]; 5]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0(&mut self, frames: &[&[f32]; 5]) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame from arbitrary float PCM input (range
[-1.0, 1.0]) for L, R, C, Ls, Rs.
Path SIMPLE/Cfg3Five — 5 SCE multichannel forward analysis per
ETSI TS 103 190-1 §4.2.6.6 Table 25 row case SIMPLE: coding_config == 3 + §4.2.7.5 Table 29 (five_channel_data()): each of the five
channels is encoded independently with the shared forward-analysis
pipeline (KBD-windowed MDCT, per-band scalefactor, DP-optimal
section partition, HCB1..11 codebook selection, SNF emission). One
shared sf_info(ASF, 0, 0) precedes the per-channel data; the
five_channel_info() uses identity SAP (sap_mode = 0 on every
chparam_info(), chel_matsel = 0) so no joint-MDCT mixing happens
at decode time — every output channel comes straight from its own
sf_data(ASF) body. This is the spec-mandated minimum for the 5.0
SIMPLE path and unblocks the encoder’s path to multichannel.
frames[i] must each be exactly frame_len samples long
(1920 samples for the default 48 kHz / 24 fps configuration). The
slice order matches the 5.0 output layout (L, R, C, Ls, Rs —
Table 180 row coding_config == 3). The encoder forces the 5.0
channel mode (channel_mode_value = 0b1101, 4 b — Table 85
channel_mode 3) for this call.
The decoder’s crate::mch::parse_5x_audio_data_outer for
channels == 5 (no LFE) consumes the body, IMDCTs each per-channel
spectrum into slots 0..4, and emits 5-channel interleaved S16 PCM at
the declared sample rate. There is no companding / ASPX / A-CPL on
the SIMPLE path so the round-trip is purely the per-channel MDCT
quantisation noise (≥ 20 dB spectral SNR per channel on tone /
white-noise fixtures).
max_sfb defaults to 40 (matching the round-49 mono default).
Use Self::encode_frame_pcm_5_0_with_max_sfb for wider coverage.
Per ETSI TS 103 190-1 §4.2.6.6 + §4.2.7.5 + §5.5 (MDCT) + §5.7 / §5.8 (SIMPLE/ASF) + TS 103 190-2 §6.2.1.1 (IMS TOC).
Sourcepub fn encode_frame_pcm_5_0_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame from arbitrary float PCM input at a
caller-specified max_sfb. All five channels share the same
max_sfb (the joint sf_info header carries one value). See
Self::encode_frame_pcm_5_0 for the rest of the contract.
Sourcepub fn encode_frame_pcm_5_1(&mut self, frames: &[&[f32]; 6]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1(&mut self, frames: &[&[f32]; 6]) -> Vec<u8> ⓘ
Encode one IMS v2 5.1 frame from float PCM input per ETSI
TS 103 190-1 §4.2.6.6 + §4.2.7.5 + TS 103 190-2 §6.2.1.1, building
on top of the 5.0 Cfg3Five forward analysis path with an extra
LFE mono_data(1) element per Table 25
(if (b_has_lfe) mono_data(1);).
frames is in [L, R, C, Ls, Rs, LFE] order. Each slice must
have length frame_len (1920 for the default 48 kHz / 24 fps
configuration); panics otherwise.
The encoder forces the 5.1 channel_mode prefix (0b1110, 4 b —
Table 85 channel_mode 4) so the decoder’s
walk_ac4_substream dispatches channels == 6 through
parse_5x_audio_data_outer(b_has_lfe = true). The LFE channel
is coded with sf_info_lfe() (Table 35) carrying max_sfb in
n_msfbl_bits bits (Table 106 column 4 — 3 bits for tl = 1920
→ max_sfb_lfe is capped at 7). The five non-LFE channels share
the same Cfg3Five five_channel_data() body as the 5.0 path
(identity SAP, independent per-channel SCE).
max_sfb defaults to 40 (matching the round-49 mono / round-74
5.0 default); max_sfb_lfe defaults to 7 (the LFE-spec cap at
tl = 1920). Use Self::encode_frame_pcm_5_1_with_max_sfb
for wider coverage.
Sourcepub fn encode_frame_pcm_5_1_with_max_sfb(
&mut self,
frames: &[&[f32]; 6],
max_sfb: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_with_max_sfb( &mut self, frames: &[&[f32]; 6], max_sfb: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.1 frame from arbitrary float PCM input at
caller-specified max_sfb (non-LFE channels) and max_sfb_lfe
(LFE channel). See Self::encode_frame_pcm_5_1 for the rest of
the contract.
Sourcepub fn encode_frame_pcm_7_0(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
Encode one IMS v2 7.0 (3/4/0) frame from float PCM input per ETSI
TS 103 190-1 §4.2.6.14 Table 33 + §4.2.7.5 Table 29
(five_channel_data()) + §4.2.7.4 Table 26 (two_channel_data()).
The non-LFE immersive counterpart of
Self::encode_frame_pcm_7_1 — same 7_X_codec_mode = SIMPLE +
coding_config = Cfg3Five body shape, but the walker’s
if (b_has_lfe) mono_data(1); branch is omitted (b_has_lfe = false for channel_mode 5 / 7.0).
frames is in [L, R, C, Ls, Rs, Lb, Rb] order — the inner
five_channel_data() (Table 180) carries the front/surround pair
L/R/C/Ls/Rs and the SIMPLE/ASPX additional-channel block carries
the immersive back pair Lb/Rb via a trailing
two_channel_data() per Table 26. The encoder uses identity SAP
(b_use_sap_add_ch = 0, sap_mode = 0 on every chparam_info)
so no joint-MDCT mixing happens at decode time: every output
channel comes straight from its own sf_data(ASF) body.
The encoder forces the 7.0 channel_mode prefix (0b1111000, 7 b —
Table 88 channel_mode 5) so the decoder’s walk_ac4_substream
dispatches channels == 7 through
parse_7x_audio_data_outer(b_has_lfe = false). The five
front/surround channels share the same Cfg3Five
five_channel_data() body as the 5.0 / 5.1 / 7.1 paths; the
additional pair (Lb, Rb) rides the trailing two_channel_data()
which the decoder’s dispatch_7x_additional_channel_pair (Table
183 row “3/4/0.x” identity path) routes into output slots 5 / 6.
max_sfb defaults to 40 (matching the round-49 mono / round-74
5.0 / round-80 5.1 / round-91 7.1 default); max_sfb_add
defaults to 40 (same width as the 7.0 non-additional channels).
Use Self::encode_frame_pcm_7_0_with_max_sfb for wider coverage.
Sourcepub fn encode_frame_pcm_7_0_with_max_sfb(
&mut self,
frames: &[&[f32]; 7],
max_sfb: u32,
max_sfb_add: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_with_max_sfb( &mut self, frames: &[&[f32]; 7], max_sfb: u32, max_sfb_add: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 7.0 (3/4/0) frame from arbitrary float PCM input
at caller-specified max_sfb (five-channel front/surround SCEs)
and max_sfb_add (additional Lb/Rb pair). See
Self::encode_frame_pcm_7_0 for the rest of the contract.
Sourcepub fn encode_frame_pcm_7_1(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
Encode one IMS v2 7.1 (3/4/0.1) frame from float PCM input per ETSI
TS 103 190-1 §4.2.6.14 Table 33 + §4.2.7.5 Table 29
(five_channel_data()) + §4.2.7.4 Table 26 (two_channel_data()),
building on top of the 5.1 Cfg3Five forward analysis path with an
extra trailing two_channel_data() for the immersive
additional-channel pair (Lb, Rb) per the SIMPLE/ASPX
additional-channel block in §4.2.6.14:
b_use_sap_add_ch + two_channel_data().
frames is in [L, R, C, Ls, Rs, Lb, Rb, LFE] order (matching
the decoder’s output slot convention: slots 0..4 from
five_channel_data() per Table 180, slots 5/6 from the additional
two_channel_data() per dispatch_7x_additional_channel_pair /
Table 183 row “3/4/0.x” identity-SAP path, slot 7 from the LFE
mono_data(1)). Each slice must have length frame_len (1920
for the default 48 kHz / 24 fps configuration); panics otherwise.
The encoder forces the 7.1 (3/4/0.1) channel_mode prefix
(0b1111001, 7 b — Table 88 channel_mode 6) so the decoder’s
walk_ac4_substream dispatches channels == 8 through
parse_7x_audio_data_outer(b_has_lfe = true). The LFE channel
is coded with sf_info_lfe() (Table 35) carrying max_sfb in
n_msfbl_bits bits (Table 106 column 4 — 3 bits for tl = 1920
→ max_sfb_lfe is capped at 7). The five non-LFE front/surround
channels share the same Cfg3Five five_channel_data() body as
the 5.1 path; the additional pair (Lb, Rb) is coded as a single
two_channel_data() with identity SAP (b_use_sap_add_ch = 0,
sap_mode = 0 on its chparam_info) so no joint-MDCT mixing
happens at decode time and slots 5/6 receive Lb/Rb directly.
max_sfb defaults to 40 (matching the round-49 mono / round-74
5.0 / round-80 5.1 default); max_sfb_add defaults to 40 (same
width as the 5.1 non-LFE channels); max_sfb_lfe defaults to 7
(the LFE-spec cap at tl = 1920). Use
Self::encode_frame_pcm_7_1_with_max_sfb for wider coverage.
Sourcepub fn encode_frame_pcm_7_1_with_max_sfb(
&mut self,
frames: &[&[f32]; 8],
max_sfb: u32,
max_sfb_add: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_with_max_sfb( &mut self, frames: &[&[f32]; 8], max_sfb: u32, max_sfb_add: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
Encode one IMS v2 7.1 (3/4/0.1) frame from arbitrary float PCM
input at caller-specified max_sfb (five-channel front/surround
SCEs), max_sfb_add (additional Lb/Rb pair), and max_sfb_lfe
(LFE channel). See Self::encode_frame_pcm_7_1 for the rest of
the contract.
Sourcepub fn encode_frame_pcm_5_0_acpl3(&mut self, frames: &[&[f32]; 3]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3(&mut self, frames: &[&[f32]; 3]) -> Vec<u8> ⓘ
Encode one IMS v2 5.X frame in 5_X_codec_mode = ASPX_ACPL_3 per
ETSI TS 103 190-1 §4.2.6.6 Table 25 row case ASPX_ACPL_3:
(round 95). Symmetric counterpart to the decoder’s round-34
crate::mch::parse_5x_audio_data_outer ASPX_ACPL_3 walker.
frames is in [L, R, C] order — three carrier channels. The
L/R pair feeds the stereo_data() body (split-MDCT path) and
drives the A-CPL Ls/Rs surround reconstruction via Pseudocode 118
at decode time. The centre carrier C is present in the
coeffs_per_channel slice but unused on the spec ASPX_ACPL_3
path — the decoder reconstructs the centre from
cfg0_centre_mono.scaled_spec (which the ASPX_ACPL_3 walker
doesn’t populate), so the decoder’s centre output is zero-filled.
The encoder forces the 5.0 channel_mode prefix (0b1101, 4 b —
Table 85 channel_mode 3) so the decoder’s walk_ac4_substream
dispatches channels == 5 through
parse_5x_audio_data_outer(b_has_lfe = false) with
5_X_codec_mode = AspxAcpl3.
The ASPX/A-CPL parameter bits are emitted as
minimum-bit-cost zero-delta Huffman codewords (per round-95
“structural scaffold” mode — see crate::encoder_acpl3).
The decoder walks the full Table 25 body and produces
5-channel [L, R, C, Ls, Rs] PCM via
crate::acpl_synth::run_acpl_5x_mch_pcm. With all-zero ACPL
parameter deltas the surround pair Ls/Rs collapses to the
ducker-driven reconstruction from the L/R carriers.
max_sfb defaults to 40 (matching the round-49 mono / round-74
5.0 default).
Sourcepub fn encode_frame_pcm_5_1_acpl3(&mut self, frames: &[&[f32]; 4]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3(&mut self, frames: &[&[f32]; 4]) -> Vec<u8> ⓘ
Encode one IMS v2 5.1 frame in 5_X_codec_mode = ASPX_ACPL_3 with
an LFE channel per ETSI TS 103 190-1 §4.2.6.6 Table 25
(if (b_has_lfe) mono_data(1);) + §4.2.8 (sf_info_lfe()).
frames is in [L, R, C, LFE] order. The L/R carrier pair drives
the stereo body + A-CPL Ls/Rs reconstruction (same as
Self::encode_frame_pcm_5_0_acpl3); the LFE channel is coded
as a leading mono_data(b_lfe = 1) element per Table 21.
Sourcepub fn encode_frame_pcm_5_0_acpl3_real_beta(
&mut self,
frames: &[&[f32]; 3],
beta_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3_real_beta( &mut self, frames: &[&[f32]; 3], beta_scale: f32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_3 with
real per-parameter-band β1 / β2 extraction from the L / R
carrier energy distributions (round 193). Symmetric to
Self::encode_frame_pcm_5_0_acpl3 but routes the substream
body builder through
crate::encoder_acpl3::build_5_x_acpl3_body_from_pcm_spectra_real_beta
so the β1 / β2 Huffman layers carry the carrier-driven decorrelator
gains instead of all-zero codewords.
beta_scale controls the wet/dry balance — see
crate::encoder_acpl3::extract_beta_q_per_band_carrier_energy
for the magnitude / scale relationship. Values in 0.05..=0.3
produce noticeable surround reconstruction without saturating
the BETA codebook.
Sourcepub fn encode_frame_pcm_5_1_acpl3_real_beta(
&mut self,
frames: &[&[f32]; 4],
beta_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3_real_beta( &mut self, frames: &[&[f32]; 4], beta_scale: f32, ) -> Vec<u8> ⓘ
5.1 counterpart to Self::encode_frame_pcm_5_0_acpl3_real_beta.
frames is in [L, R, C, LFE] order. The LFE channel is coded
as a leading mono_data(b_lfe = 1) element per Table 21 — same
path as Self::encode_frame_pcm_5_1_acpl3.
Sourcepub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta(
&mut self,
frames: &[&[f32]; 3],
alpha_scale: f32,
beta_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta( &mut self, frames: &[&[f32]; 3], alpha_scale: f32, beta_scale: f32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_3 with
real per-parameter-band α₁ / α₂ extraction from the L↔R carrier
cross-correlation (round 196) and the round-193 real β₁ / β₂
extraction from the L / R carrier energies. Symmetric counterpart
to Self::encode_frame_pcm_5_0_acpl3_real_beta but routes the
substream body builder through
crate::encoder_acpl3::build_5_x_acpl3_body_from_pcm_spectra_real_alpha_beta
so the α₁ / α₂ Huffman layers carry correlation-driven dry-mix
balance indices in addition to the carrier-driven decorrelator
gains in β₁ / β₂.
alpha_scale controls the front/back-balance policy — see
crate::encoder_acpl3::extract_alpha_q_per_band_carrier_correlation
for the magnitude / scale relationship. Values in 0.25..=1.0
produce a noticeable front/back bias on correlated content
without saturating the ALPHA codebook.
beta_scale retains its r193 meaning. With
alpha_scale = beta_scale = 0.0 the output is byte-identical to
Self::encode_frame_pcm_5_0_acpl3’s round-95 scaffold.
Sourcepub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta(
&mut self,
frames: &[&[f32]; 4],
alpha_scale: f32,
beta_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta( &mut self, frames: &[&[f32]; 4], alpha_scale: f32, beta_scale: f32, ) -> Vec<u8> ⓘ
5.1 counterpart to
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta. frames is
in [L, R, C, LFE] order. The LFE channel is coded as a leading
mono_data(b_lfe = 1) element per Table 21 — same path as
Self::encode_frame_pcm_5_1_acpl3.
Sourcepub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_gamma(
&mut self,
frames: &[&[f32]; 3],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_gamma( &mut self, frames: &[&[f32]; 3], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_3 with
real per-band α + β + γ5/γ6. Layered on top of
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta: the γ5 / γ6
entropy layers now carry per-band magnitudes derived from a 2×2
least-squares fit of the centre channel
C ≈ K · (γ5·L + γ6·R) (Pseudocode 118 step 7 + step 11 with
K = √2 · (1 + √2) / 2). γ1..γ4 + β3 stay zero-delta.
gamma_scale = 0.0 reproduces the round-196 real-α-β byte stream
exactly; gamma_scale = 1.0 writes the full analytic γ pair
(clamped to the Table-208 ±2.0 bound). alpha_scale = beta_scale = gamma_scale = 0.0 reproduces the round-95 zero-delta scaffold
byte-for-byte.
frames is in [L, R, C] order. The decoder walks the same
Table 25 ASPX_ACPL_3 body; γ5 / γ6 feed the ACplModule2 instance
that synthesises the centre output channel (Pseudocode 119 with
a = 1, b = 0, y = 0). γ1..γ4 still at zero-delta keeps the
(L, R, Ls, Rs) sub-pipeline behaviour identical to the round-196
path.
Sourcepub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_gamma(
&mut self,
frames: &[&[f32]; 4],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_gamma( &mut self, frames: &[&[f32]; 4], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, ) -> Vec<u8> ⓘ
5.1 counterpart to
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta_gamma.
frames is in [L, R, C, LFE] order. The LFE channel is coded
as a leading mono_data(b_lfe = 1) element per Table 21 — same
path as Self::encode_frame_pcm_5_1_acpl3_real_alpha_beta.
Sourcepub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma(
&mut self,
frames: &[&[f32]; 5],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma( &mut self, frames: &[&[f32]; 5], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_3 with
full real per-parameter-band α₁ / α₂ / β₁ / β₂ / γ₁..γ₆
extraction (round 215) — the round-208 entry point
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta_gamma lifted
the centre γ₅ / γ₆ pair to real values; this entry point also
lifts γ₁ / γ₂ (driving the (L, Ls) pair via Pseudocode 118
step 5) and γ₃ / γ₄ (driving the (R, Rs) pair via Pseudocode 118
step 6), closing the README’s long-standing “γ1..γ4 stay at the
round-95 zero-delta scaffold” deferral for the 5_X ACPL_3 path.
The γ₁ / γ₂ pair comes from a per-band 2×2 least-squares fit of
the (L, Ls) output sum (L + Ls/√2)/(1 + √2) onto the (L, R)
carrier pair; γ₃ / γ₄ come from the symmetric fit on the
(R, Rs) pair (see
crate::encoder_acpl3::extract_gamma_1_2_q_per_band_surround_least_squares
and
crate::encoder_acpl3::extract_gamma_3_4_q_per_band_surround_least_squares).
Both sums are independent of the α / β decorrelator
contributions and equal a (1 + √2) · (γ·L + γ'·R) linear
combination, so the resulting 2×2 normal-equations system is
identical in shape to the round-208 γ₅ / γ₆ centre fit.
frames is in [L, R, C, Ls, Rs] order. The L / R carriers
also feed the round-51 stereo two_channel_data() body the
ASPX_ACPL_3 path emits. β₃ stays at the round-95 zero-delta
scaffold — its analytic extraction requires a model for the
third decorrelator output y₂ which is not observable at
encode time. The ASPX envelope layer also stays at the
minimum-bit-cost FIXFIX num_env=1 scaffold pending the
“real ASPX envelope coding” deferral elsewhere on the README.
alpha_scale / beta_scale / gamma_scale control the
extractor magnitude (typically 1.0 for the analytic
least-squares solution; 0.0 reproduces the prior-round
scaffold byte-for-byte at the corresponding layer position).
In particular α/β/γ_scale = 0.0 reproduces the round-95
zero-delta scaffold (Self::encode_frame_pcm_5_0_acpl3)
byte-for-byte; γ_scale = 0.0 reproduces the round-196
real-α-β bytes exactly.
Sourcepub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_full_gamma(
&mut self,
frames: &[&[f32]; 6],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_full_gamma( &mut self, frames: &[&[f32]; 6], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, ) -> Vec<u8> ⓘ
5.1 counterpart to
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma.
frames is in [L, R, C, Ls, Rs, LFE] order. The LFE channel
is coded as a leading mono_data(b_lfe = 1) element per Table
21 — same path as
Self::encode_frame_pcm_5_1_acpl3_real_alpha_beta_gamma.
Sourcepub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma_beta3(
&mut self,
frames: &[&[f32]; 5],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
beta3_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma_beta3( &mut self, frames: &[&[f32]; 5], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, beta3_scale: f32, ) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_3 with
real per-parameter-band α₁ / α₂ + β₁ / β₂ + γ₁..γ₆ + β₃
extraction (round 285 — the β₃-real extension of
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma).
frames is in [L, R, C, Ls, Rs] order. β₃ (the gain on the
third decorrelator output y₂ per §5.7.7.6.2 Pseudocode 118
steps 8–10) is energy-matched to the centre-channel
reconstruction residual left over after the γ₅ / γ₆ dry-mix fit
— see
crate::encoder_acpl3::extract_beta3_q_per_band_centre_residual.
beta3_scale = 0.0 reproduces the round-215 full-γ byte stream
exactly; beta3_scale = 1.0 applies the full energy-matching
solution clamped to the Table-207 ±1.0 magnitude bound.
Sourcepub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_full_gamma_beta3(
&mut self,
frames: &[&[f32]; 6],
alpha_scale: f32,
beta_scale: f32,
gamma_scale: f32,
beta3_scale: f32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_1_acpl3_real_alpha_beta_full_gamma_beta3( &mut self, frames: &[&[f32]; 6], alpha_scale: f32, beta_scale: f32, gamma_scale: f32, beta3_scale: f32, ) -> Vec<u8> ⓘ
5.1 counterpart to
Self::encode_frame_pcm_5_0_acpl3_real_alpha_beta_full_gamma_beta3.
frames is in [L, R, C, Ls, Rs, LFE] order. The LFE channel
is coded as a leading mono_data(b_lfe = 1) element per Table
21 — same path as
Self::encode_frame_pcm_5_1_acpl3_real_alpha_beta_full_gamma.
Sourcepub fn encode_frame_pcm_5_0_acpl2(&mut self, frames: &[&[f32]; 3]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl2(&mut self, frames: &[&[f32]; 3]) -> Vec<u8> ⓘ
Encode one IMS v2 5.0 frame in 5_X_codec_mode = ASPX_ACPL_2 per
ETSI TS 103 190-1 §4.2.6.6 Table 25 row case ASPX_ACPL_2:
(round 100). Symmetric counterpart to the decoder’s round-25
crate::mch::parse_5x_audio_data_outer ASPX_ACPL_{1,2} inner-
body walker (Pseudocode 117).
frames is in [L, R, C] order — the L/R carrier pair feeds the
two_channel_data() body and drives the A-CPL Ls/Rs surround
reconstruction via crate::acpl_synth::run_acpl_5x_pair_pcm at
decode time; the centre carrier C is coded as a Cfg0
mono_data(0) element. ASPX_ACPL_2 has no surround carriers — the
Ls/Rs PCM is reconstructed entirely from the L/R carriers + the
two acpl_data_1ch() parameter sets.
The encoder forces the 5.0 channel_mode prefix (0b1101, 4 b —
Table 85 channel_mode 3) so the decoder’s walk_ac4_substream
dispatches channels == 5 through
parse_5x_audio_data_outer(b_has_lfe = false) with
5_X_codec_mode = AspxAcpl2.
The ASPX/A-CPL parameter bits are emitted as minimum-bit-cost
zero-delta Huffman codewords (the round-95 “structural scaffold”
mode — see crate::encoder_acpl3). The decoder walks the full
Table 25 ASPX_ACPL_2 body and produces 5-channel [L, R, C, Ls, Rs] PCM. With all-zero ACPL parameter deltas the surround pair
Ls/Rs collapses to the ducker-driven reconstruction from the L/R
carriers.
max_sfb defaults to 40 (matching the round-95 ACPL_3 default).
Sourcepub fn encode_frame_pcm_5_0_acpl2_with_max_sfb(
&mut self,
frames: &[&[f32]; 3],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl2_with_max_sfb( &mut self, frames: &[&[f32]; 3], max_sfb: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of Self::encode_frame_pcm_5_0_acpl2.
Sourcepub fn encode_frame_pcm_5_0_acpl2_real_alpha_beta(
&mut self,
frames: &[&[f32]; 5],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl2_real_alpha_beta( &mut self, frames: &[&[f32]; 5], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 5.0 SIMPLE/ASPX_ACPL_2
multichannel substream with real per-parameter-band α + β
extraction carried by the two trailing acpl_data_1ch() elements
(round 144 — the ACPL_2 5.0 counterpart to the round-132 ACPL_1 5.0
real α + β path).
Per ETSI TS 103 190-1 §5.7.7.5 Pseudocode 116 + §5.7.7.6.1 Pseudocode 117, the A-CPL surround reconstruction carries the level component via α and a decorrelated residual via β:
α = 1 − 2·√2 · ⟨x_carrier, x_surround⟩ / ⟨x_carrier, x_carrier⟩
E[Ls²] = 0.5 · E[L²] · ( (1 − α)² + β² )
⇒ β = √max(0, 2·E[Ls²]/E[L²] − (1 − α_dq)²)Unlike the ACPL_1 paths, ACPL_2 does not transmit the Ls/Rs
surround pair on the wire — the decoder reconstructs the surround
purely from the L/R carriers + the two acpl_data_1ch() parameter
sets. This entry point therefore still emits the round-100
ASPX_ACPL_2 body layout (no joint-MDCT residual layer, no
acpl_config_1ch(PARTIAL) qmf_band field), but extracts the α + β
indices from the caller’s full 5-channel [L, R, C, Ls, Rs] input
rather than pinning them at the zero-codebook scaffold.
frames is in [L, R, C, Ls, Rs] order; β3 / γ stay at the
scaffold. The acpl_config_1ch(FULL) carries no qmf_band →
start_band = 0 so every parameter band participates in the α + β
coding (in contrast to the ACPL_1 PARTIAL mode whose
acpl_qmf_band masks the low bands).
Note (round-128 ALPHA F0 writer-side alpha_q desync —
deferred follow-up since round 132). The shared
write_acpl_alpha_f0_value writer treats the signed alpha_q ∈ [-N/2..+N/2] returned by quantise_alpha as a raw F0 symbol
index without re-centering it against the table’s shortest
codeword. The decoder’s dequantize_alpha_index re-centers via
lane = alpha_q + N/2, so non-trivial α values do not round-trip
bit-exact through the full PCM→MDCT→writer→parser→synth chain
when the analytic α resolves to a non-center quantisation lane.
The on-wire β codewords for ACPL_2 are wired correctly per
§A.3 Table A.40 / A.41 (β uses unsigned-magnitude F0 with
cb_off = 0, no re-centering needed); the round-100 zero-α/β
scaffold is structurally superseded by this entry point. Once
the writer-side desync lands as a follow-up commit the on-wire β
recovery will be bit-exact end-to-end.
Sourcepub fn encode_frame_pcm_5_0_acpl2_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl2_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of
Self::encode_frame_pcm_5_0_acpl2_real_alpha_beta.
Sourcepub fn encode_frame_pcm_5_0_acpl1(&mut self, frames: &[&[f32]; 5]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1(&mut self, frames: &[&[f32]; 5]) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 5.0 SIMPLE/ASPX_ACPL_1
multichannel substream per ETSI TS 103 190-1 §4.2.6.6 Table 25 row
case ASPX_ACPL_1: (Pseudocode 117).
Unlike ASPX_ACPL_2 (which reconstructs the Ls/Rs surround pair
purely from the L/R carriers + the two acpl_data_1ch() parameter
sets), ASPX_ACPL_1 transmits the surround signal explicitly as a
joint-MDCT residual layer (max_sfb_master + 2× chparam_info + 2× sf_data(ASF)) keyed by the acpl_config_1ch(PARTIAL) element’s
acpl_qmf_band field. It therefore accepts a full 5-channel
[L, R, C, Ls, Rs] input: L/R become the two_channel_data()
carriers, C the Cfg0 mono_data(0), and Ls/Rs the residual pair
(sSMP,3 / sSMP,4 per Table 181).
The encoder forces the 5.0 channel_mode prefix (0b1101, 4 b —
Table 85 channel_mode 3) so the decoder’s walk_ac4_substream
dispatches channels == 5 through
parse_5x_audio_data_outer(b_has_lfe = false) with
5_X_codec_mode = AspxAcpl1. The ASPX/A-CPL parameter bits use the
round-95 minimum-bit-cost zero-delta Huffman scaffold. The decoder
walks the full Table 25 ASPX_ACPL_1 body — including the residual
layer that IMDCTs into the Ls/Rs PCM carriers — and produces
5-channel [L, R, C, Ls, Rs] PCM via
crate::acpl_synth::run_acpl_5x_pair_pcm (Pseudocode 117).
max_sfb defaults to 40; max_sfb_master (the residual-layer band
budget) defaults to 20.
Sourcepub fn encode_frame_pcm_5_0_acpl1_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_5_0_acpl1.
Sourcepub fn encode_frame_pcm_5_0_acpl1_sap(
&mut self,
frames: &[&[f32]; 5],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_sap( &mut self, frames: &[&[f32]; 5], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 5.0 SIMPLE/ASPX_ACPL_1
multichannel substream whose joint-MDCT residual layer is
SAP-coded by decision (round 279) — the automatic,
decision-driven counterpart of Self::encode_frame_pcm_5_0_acpl1.
Per ETSI TS 103 190-1 §5.3.4.3.2 / Table 181 + §5.3.2 Pseudocode
59, the encoder runs the round-271
crate::asf::select_alpha_q_for_pair least-squares decision per
(L, Ls) / (R, Rs) target pair, materialises the SAP-coded
chparam_info() rows via
crate::asf::build_chparam_info_sap_data_from_alpha_q (falling
back to the header-only SapMode::None row when no band
benefits), and transmits the Table-181 matrix-input carriers
(sSMP_A, sSMP_B) = (M, ·) plus the side prediction residual
(sSMP_3, sSMP_4) = (S − g·M, ·) recovered through
crate::asf::invert_sap_table_181. For a surround pair
correlated with its front carrier the residual sf_data collapses
to (near-)silence — the bits the identity path spends on the raw
Ls/Rs spectra are saved while the decoder’s
apply_sap_table_181 forward mix reproduces the same
preliminaries.
On-wire body layout is identical to
Self::encode_frame_pcm_5_0_acpl1; when the decision picks no
SAP band (e.g. Ls = L) the emitted frame is bit-for-bit
identical to the identity-SAP path.
Sourcepub fn encode_frame_pcm_5_0_acpl1_sap_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_sap_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_5_0_acpl1_sap.
Sourcepub fn encode_frame_pcm_5_0_acpl1_real_alpha(
&mut self,
frames: &[&[f32]; 5],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_real_alpha( &mut self, frames: &[&[f32]; 5], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 5.0 SIMPLE/ASPX_ACPL_1 multichannel substream with real per-parameter-band α extraction (round 128 — replaces the round-103 zero-delta scaffold for the α coefficient family; β / β3 / γ stay at the scaffold).
Body layout is identical to Self::encode_frame_pcm_5_0_acpl1
(delegates to crate::encoder_acpl3::build_5_x_acpl1_body_from_pcm_spectra_real_alpha);
the only on-wire difference is that the two acpl_data_1ch()
elements now emit ALPHA F0 + DF codewords with non-zero values
chosen to minimise the per-parameter-band residual against the
caller’s (Ls, Rs) input vs (L, R) carrier energies. See
crate::encoder_acpl3 §“Real per-band α extraction” for the
closed-form derivation (β = 0 ⇒ α = 1 − 2·√2·⟨carrier, surround⟩
/ ⟨carrier, carrier⟩).
frames is in [L, R, C, Ls, Rs] order. The decoder’s
crate::acpl_synth::run_acpl_5x_pair_pcm consumes the recovered
α and reconstructs Ls / Rs from the L / R carriers with measurably
better fidelity than the zero-α baseline when Ls / Rs aren’t a
pure scaled copy of L / R.
Sourcepub fn encode_frame_pcm_5_0_acpl1_real_alpha_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_real_alpha_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_5_0_acpl1_real_alpha.
Sourcepub fn encode_frame_pcm_5_0_acpl1_real_alpha_beta(
&mut self,
frames: &[&[f32]; 5],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_real_alpha_beta( &mut self, frames: &[&[f32]; 5], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 5.0 SIMPLE/ASPX_ACPL_1 multichannel substream with real per-parameter-band α + β extraction per ETSI TS 103 190-1 §5.7.7.5 Pseudocode 116 + §5.7.7.6.1 Pseudocode 117 (round 132).
Extends Self::encode_frame_pcm_5_0_acpl1_real_alpha by emitting
real per-band β magnitudes alongside the existing real α — the
surround Ls/Rs reconstruction at the decoder is no longer a pure
level-only image of L/R but also carries the energy of the
decorrelated residual:
E[Ls²] = 0.5 · E[L²] · ( (1 − α)² + β² )frames is in [L, R, C, Ls, Rs] order; β / γ stay at the
round-95 / 100 / 103 / 128 scaffold for non-ACPL_1 paths.
Sourcepub fn encode_frame_pcm_5_0_acpl1_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 5],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_5_0_acpl1_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 5], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_5_0_acpl1_real_alpha_beta.
Sourcepub fn encode_frame_pcm_7_0_acpl2(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl2(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.0 SIMPLE/ASPX_ACPL_2
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_2: (round 107). The 7_X (immersive) symmetric
counterpart to the round-100 5_X ASPX_ACPL_2 encoder — it reuses the
same 1ch ACPL / ASPX parameter shape (Pseudocode 117) but emits the
7_X channel element’s distinct framing (2-bit 7_X_codec_mode,
companding_control(5), 2-bit coding_config, two two_channel_data
pairs, trailing centre mono_data(0), and the two-aspx_data_2ch
envelope trailer).
frames is in [L, R, C, Ls, Rs, Lb, Rb] order — the 7.0 (3/4/0)
surface layout. The L/R pair feeds the first two_channel_data()
carriers and drives the A-CPL Ls/Rs surround reconstruction via
crate::acpl_synth::run_acpl_5x_pair_pcm at decode time. The Ls/Rs
pair is coded as the second two_channel_data() (keeps the body
well-formed for the walker; the ACPL_2 dispatch reconstructs the
surround from L/R + params). The centre C is the trailing Cfg0
mono_data(0). The back pair Lb, Rb is accepted for layout
completeness but not carried by the ASPX_ACPL_2 body (the decoder’s
ACPL_2 7_X dispatch populates slots 0..4 only — slots 5/6 stay
silent), matching the decoder’s documented Table 202 channel mapping.
The encoder forces the 7.0 (3/4/0) channel_mode prefix (0b1111000,
7 b — Table 85 channel_mode 5) so the decoder’s walk_ac4_substream
dispatches channels == 7 through
parse_7x_audio_data_outer(b_has_lfe = false) with
7_X_codec_mode = AspxAcpl2. The ASPX/A-CPL parameter bits use the
round-95 minimum-bit-cost zero-delta Huffman scaffold.
max_sfb defaults to 40.
Sourcepub fn encode_frame_pcm_7_0_acpl2_with_max_sfb(
&mut self,
frames: &[&[f32]; 7],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl2_with_max_sfb( &mut self, frames: &[&[f32]; 7], max_sfb: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of Self::encode_frame_pcm_7_0_acpl2.
Sourcepub fn encode_frame_pcm_7_1_acpl2(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl2(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.1 (3/4/0.1) SIMPLE/ASPX_ACPL_2
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_2: with b_has_lfe = 1 (round 114). The LFE
counterpart of Self::encode_frame_pcm_7_0_acpl2 — it emits the
identical 7_X ASPX_ACPL_2 body plus a leading mono_data(b_lfe = 1)
element (Table 21 + sf_info_lfe() Table 35) between the I-frame
config block and companding_control(5), exactly where the decoder’s
parse_7x_audio_data_outer(b_has_lfe = true) reads
if (b_has_lfe) mono_data(1);.
frames is in [L, R, C, Ls, Rs, Lb, Rb, LFE] order — the 7.1
(3/4/0.1) surface layout. The L/R pair feeds the first
two_channel_data() carriers and drives the A-CPL Ls/Rs surround
reconstruction via crate::acpl_synth::run_acpl_5x_pair_pcm at
decode time; the Ls/Rs pair rides the second two_channel_data();
the centre C is the trailing Cfg0 mono_data(0); the LFE is the
leading mono_data(1). The back pair Lb, Rb is accepted for layout
completeness but not carried by the ASPX_ACPL_2 body (the decoder’s
7_X ACPL_2 dispatch populates slots 0..4 + the LFE slot 7 — slots 5/6
stay silent), matching the round-107 documented Table 202 channel
mapping plus the round-80 LFE PCM render at decode time.
The encoder forces the 7.1 channel_mode prefix (0b1111001, 7 b —
Table 88 channel_mode 6) so the decoder’s walk_ac4_substream
dispatches channels == 8 through
parse_7x_audio_data_outer(b_has_lfe = true) with
7_X_codec_mode = AspxAcpl2. The ASPX/A-CPL parameter bits use the
round-95 minimum-bit-cost zero-delta Huffman scaffold.
max_sfb defaults to 40; max_sfb_lfe defaults to 7 (the LFE-spec
cap at tl = 1920, n_msfbl_bits = 3).
Sourcepub fn encode_frame_pcm_7_1_acpl2_with_max_sfb(
&mut self,
frames: &[&[f32]; 8],
max_sfb: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl2_with_max_sfb( &mut self, frames: &[&[f32]; 8], max_sfb: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of Self::encode_frame_pcm_7_1_acpl2.
max_sfb governs the five front/surround carrier SCEs and the centre
mono; max_sfb_lfe governs the LFE mono_data(1) (clamped to the
n_msfbl_bits cap).
Sourcepub fn encode_frame_pcm_7_0_acpl2_real_alpha_beta(
&mut self,
frames: &[&[f32]; 7],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl2_real_alpha_beta( &mut self, frames: &[&[f32]; 7], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.0 (3/4/0) SIMPLE/ASPX_ACPL_2
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_2: with real per-parameter-band α + β extraction
(round 202). The 7_X (immersive) counterpart to the round-144 5.0
ACPL_2 real-α-β path
(Self::encode_frame_pcm_5_0_acpl2_real_alpha_beta) and the
real-α-β upgrade of the round-107 7.0 ACPL_2 zero-delta path
(Self::encode_frame_pcm_7_0_acpl2).
frames is in [L, R, C, Ls, Rs, Lb, Rb] order — the 7.0 (3/4/0)
surface layout. The L/R pair feeds the first two_channel_data()
carriers and drives the A-CPL Ls/Rs surround reconstruction via
crate::acpl_synth::run_acpl_5x_pair_pcm at decode time; the
Ls/Rs pair rides the second two_channel_data() and feeds the
α + β extractors (D0 module models (L → Ls); D1 module models
(R → Rs)). acpl_config_1ch(FULL) carries no qmf_band →
start_band = 0 so every parameter band participates. The centre
C is the trailing Cfg0 mono_data(0). The back pair Lb, Rb
is accepted for layout completeness but not carried by the
ASPX_ACPL_2 body (the decoder’s 7_X ACPL_2 dispatch populates
slots 0..4 — slots 5/6 stay silent), matching the round-107
documented Table 202 channel mapping.
The encoder forces the 7.0 channel_mode prefix (0b1111000, 7 b —
Table 85 channel_mode 5) so the decoder’s walk_ac4_substream
dispatches channels == 7 through
parse_7x_audio_data_outer(b_has_lfe = false) with
7_X_codec_mode = AspxAcpl2.
max_sfb defaults to 40.
Sourcepub fn encode_frame_pcm_7_0_acpl2_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 7],
max_sfb: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl2_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 7], max_sfb: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of
Self::encode_frame_pcm_7_0_acpl2_real_alpha_beta.
Sourcepub fn encode_frame_pcm_7_1_acpl2_real_alpha_beta(
&mut self,
frames: &[&[f32]; 8],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl2_real_alpha_beta( &mut self, frames: &[&[f32]; 8], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.1 (3/4/0.1) SIMPLE/ASPX_ACPL_2
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_2: with b_has_lfe = 1 and real per-parameter-band
α + β extraction (round 202). The LFE counterpart of
Self::encode_frame_pcm_7_0_acpl2_real_alpha_beta — it emits the
identical 7_X ASPX_ACPL_2 real-α-β body plus a leading
mono_data(b_lfe = 1) element between the I-frame config block and
companding_control(5), exactly where the decoder’s
parse_7x_audio_data_outer(b_has_lfe = true) reads
if (b_has_lfe) mono_data(1);.
frames is in [L, R, C, Ls, Rs, Lb, Rb, LFE] order. See
Self::encode_frame_pcm_7_0_acpl2_real_alpha_beta for the channel
routing contract; the LFE is the leading mono_data(1).
The encoder forces the 7.1 channel_mode prefix (0b1111001, 7 b —
Table 88 channel_mode 6) so the decoder dispatches channels == 8
through parse_7x_audio_data_outer(b_has_lfe = true) with
7_X_codec_mode = AspxAcpl2.
max_sfb defaults to 40; max_sfb_lfe defaults to 7 (the LFE-spec
cap at tl = 1920, n_msfbl_bits = 3).
Sourcepub fn encode_frame_pcm_7_1_acpl2_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 8],
max_sfb: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl2_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 8], max_sfb: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_lfe-parameterised form of
Self::encode_frame_pcm_7_1_acpl2_real_alpha_beta.
Sourcepub fn encode_frame_pcm_7_0_acpl1(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl1(&mut self, frames: &[&[f32]; 7]) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.0 (3/4/0) SIMPLE/ASPX_ACPL_1
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_1: (round 118). The 7_X (immersive) counterpart to
the round-103 5_X ASPX_ACPL_1 encoder and the encoder side of the
decoder’s round-27 parse_7x_audio_data_outer ASPX_ACPL_1 branch.
ASPX_ACPL_1 differs from the round-107 7.0 ASPX_ACPL_2 path in three
structural places (the same three that separate the 5_X ACPL_1 path
from the 5_X ACPL_2 path): 7_X_codec_mode = 2 (vs 3),
acpl_config_1ch is PARTIAL (vs FULL — carries the 3-bit
acpl_qmf_band_minus1), and the body carries an explicit joint-MDCT
residual layer (max_sfb_master + 2× chparam_info + 2× sf_data(ASF))
transmitting the Ls/Rs surround pair (sSMP,3 / sSMP,4 per Table 181)
rather than reconstructing it purely from the L/R carriers.
frames is in [L, R, C, Ls, Rs, Lb, Rb] order — the 7.0 (3/4/0)
surface layout. The L/R pair feeds the first two_channel_data()
carriers; the Ls/Rs pair rides the second two_channel_data() and
the joint-MDCT residual layer; the centre C is the trailing Cfg0
mono_data(0). The back pair Lb, Rb is accepted for layout
completeness but not carried by the ASPX_ACPL_1 body (the decoder’s
7_X ACPL_1 dispatch populates slots 0..4 only — slots 5/6 stay
silent), matching the round-107 documented Table 202 channel mapping.
The encoder forces the 7.0 (3/4/0) channel_mode prefix (0b1111000,
7 b — Table 85 channel_mode 5) so the decoder’s walk_ac4_substream
dispatches channels == 7 through
parse_7x_audio_data_outer(b_has_lfe = false) with
7_X_codec_mode = AspxAcpl1. The ASPX/A-CPL parameter bits use the
round-95 minimum-bit-cost zero-delta Huffman scaffold.
max_sfb defaults to 40; max_sfb_master (the residual band bound)
defaults to 20.
Sourcepub fn encode_frame_pcm_7_0_acpl1_with_max_sfb(
&mut self,
frames: &[&[f32]; 7],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl1_with_max_sfb( &mut self, frames: &[&[f32]; 7], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_7_0_acpl1.
Sourcepub fn encode_frame_pcm_7_0_acpl1_real_alpha_beta(
&mut self,
frames: &[&[f32]; 7],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl1_real_alpha_beta( &mut self, frames: &[&[f32]; 7], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.0 (3/4/0) SIMPLE/ASPX_ACPL_1 multichannel substream with real per-parameter-band α + β extraction per ETSI TS 103 190-1 §5.7.7.5 Pseudocode 116 + §5.7.7.6.1 Pseudocode 117 (round 135).
The 7_X immersive counterpart of
Self::encode_frame_pcm_5_0_acpl1_real_alpha_beta and the real-
α+β upgrade of Self::encode_frame_pcm_7_0_acpl1 (which emitted
both acpl_data_1ch() sets at the round-118 zero-delta scaffold).
The two trailing acpl_data_1ch() parameter sets now carry the
analytic α (from the L/Ls and R/Rs MDCT-energy correlation) and the
β magnitude that closes the surround/carrier energy balance after α
removes the level-only component:
E[Ls²] = 0.5 · E[L²] · ( (1 − α)² + β² )frames is in [L, R, C, Ls, Rs, Lb, Rb] order — the 7.0 (3/4/0)
surface layout, identical to Self::encode_frame_pcm_7_0_acpl1.
β / β3 / γ for non-ACPL_1 paths stay at the scaffold.
Sourcepub fn encode_frame_pcm_7_0_acpl1_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 7],
max_sfb: u32,
max_sfb_master: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_0_acpl1_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 7], max_sfb: u32, max_sfb_master: u32, ) -> Vec<u8> ⓘ
max_sfb / max_sfb_master-parameterised form of
Self::encode_frame_pcm_7_0_acpl1_real_alpha_beta.
Sourcepub fn encode_frame_pcm_7_1_acpl1(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl1(&mut self, frames: &[&[f32]; 8]) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.1 (3/4/0.1) SIMPLE/ASPX_ACPL_1
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_1: with b_has_lfe = 1 (round 118). The LFE
counterpart of Self::encode_frame_pcm_7_0_acpl1 — it emits the
identical 7_X ASPX_ACPL_1 body plus a leading mono_data(b_lfe = 1)
element (Table 21 + sf_info_lfe() Table 35) between the I-frame
config block and companding_control(5), exactly where the decoder’s
parse_7x_audio_data_outer(b_has_lfe = true) reads
if (b_has_lfe) mono_data(1);.
frames is in [L, R, C, Ls, Rs, Lb, Rb, LFE] order — the 7.1
(3/4/0.1) surface layout. The LFE is the leading mono_data(1); the
rest of the body matches the 7.0 ACPL_1 form. The encoder forces the
7.1 channel_mode prefix (0b1111001, 7 b — Table 88 channel_mode 6)
so the decoder dispatches channels == 8 through
parse_7x_audio_data_outer(b_has_lfe = true) with
7_X_codec_mode = AspxAcpl1; the LFE spectrum IMDCT’s into slot 7
via the round-80 LFE PCM render.
max_sfb defaults to 40; max_sfb_master defaults to 20;
max_sfb_lfe defaults to 7 (the LFE-spec cap at tl = 1920,
n_msfbl_bits = 3).
Sourcepub fn encode_frame_pcm_7_1_acpl1_with_max_sfb(
&mut self,
frames: &[&[f32]; 8],
max_sfb: u32,
max_sfb_master: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl1_with_max_sfb( &mut self, frames: &[&[f32]; 8], max_sfb: u32, max_sfb_master: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of Self::encode_frame_pcm_7_1_acpl1.
max_sfb governs the five front/surround carrier SCEs and the centre
mono; max_sfb_master governs the joint-MDCT surround residual
layer; max_sfb_lfe governs the LFE mono_data(1) (clamped to the
n_msfbl_bits cap).
Sourcepub fn encode_frame_pcm_7_1_acpl1_real_alpha_beta(
&mut self,
frames: &[&[f32]; 8],
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl1_real_alpha_beta( &mut self, frames: &[&[f32]; 8], ) -> Vec<u8> ⓘ
Encode one IMS v2 frame containing a 7.1 (3/4/0.1) SIMPLE/ASPX_ACPL_1
multichannel substream per ETSI TS 103 190-1 §4.2.6.14 Table 33 row
case ASPX_ACPL_1: with b_has_lfe = 1, with real per-parameter-band
α + β extraction carried by the two trailing acpl_data_1ch()
parameter sets (round 139 — the LFE counterpart of the round-135
7.0 immersive real-α+β path,
Self::encode_frame_pcm_7_0_acpl1_real_alpha_beta).
The round-118 7.1 ASPX_ACPL_1 encoder emitted both acpl_data_1ch()
parameter sets at the zero-delta scaffold; this entry point upgrades
them to carry the analytic α (from the L/Ls and R/Rs MDCT-energy
correlation, §5.7.7.5 Pseudocode 116) plus the β magnitude that
closes the surround/carrier energy balance after α removes the
level-only component (§5.7.7.6.1 Pseudocode 117):
E[Ls²] = 0.5 · E[L²] · ( (1 − α)² + β² )
⇒ β = √max(0, 2·E[Ls²]/E[L²] − (1 − α)²)frames is in [L, R, C, Ls, Rs, Lb, Rb, LFE] order — the 7.1
(3/4/0.1) surface layout, identical to
Self::encode_frame_pcm_7_1_acpl1. The leading mono_data(b_lfe = 1)
element (Table 21 + sf_info_lfe() Table 35) is emitted between the
I-frame config block and companding_control(5). The on-wire body
structure is otherwise identical — decoder resolves
SevenXCodecMode::AspxAcpl1 with b_has_lfe = true, both
acpl_data_1ch_pair[0/1] populated (now carrying real α + β),
joint-MDCT residual layer walked, LFE IMDCT’d into slot 7.
Sourcepub fn encode_frame_pcm_7_1_acpl1_real_alpha_beta_with_max_sfb(
&mut self,
frames: &[&[f32]; 8],
max_sfb: u32,
max_sfb_master: u32,
max_sfb_lfe: u32,
) -> Vec<u8> ⓘ
pub fn encode_frame_pcm_7_1_acpl1_real_alpha_beta_with_max_sfb( &mut self, frames: &[&[f32]; 8], max_sfb: u32, max_sfb_master: u32, max_sfb_lfe: u32, ) -> Vec<u8> ⓘ
max_sfb-parameterised form of
Self::encode_frame_pcm_7_1_acpl1_real_alpha_beta. max_sfb
governs the five front/surround carrier SCEs and the centre mono;
max_sfb_master governs the joint-MDCT surround residual layer;
max_sfb_lfe governs the LFE mono_data(1) (clamped to the
n_msfbl_bits cap).
Sourcepub fn encode_frame_mono_tone_at_hz(&mut self, target_hz: f32) -> (Vec<u8>, f32)
pub fn encode_frame_mono_tone_at_hz(&mut self, target_hz: f32) -> (Vec<u8>, f32)
Encode one IMS v2 frame containing a mono SIMPLE/ASF substream
whose injected tone falls on the spectral pair nearest the
requested frequency. With tl = 1920 at 48 kHz the bin spacing
is 12.5 Hz; the chosen pair carries a single non-zero quantised
value at the lower bin of that pair.
Returns the encoded frame bytes plus the actual nominal centre frequency the encoder targeted (lower-bin × bin_spacing).
Trait Implementations§
Source§impl Clone for Ac4ImsEncoder
impl Clone for Ac4ImsEncoder
Source§fn clone(&self) -> Ac4ImsEncoder
fn clone(&self) -> Ac4ImsEncoder
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more