Skip to content

stereo: dynamic IS crossover and MS restriction at low bitrates - #182

Merged
fabiangreffrath merged 1 commit into
knik0:masterfrom
nschimme:improve-stereo
Aug 30, 2026
Merged

stereo: dynamic IS crossover and MS restriction at low bitrates#182
fabiangreffrath merged 1 commit into
knik0:masterfrom
nschimme:improve-stereo

Conversation

@nschimme

Copy link
Copy Markdown
Contributor

This is a quality improvement.

Passes core bandwidth into AACstereo() to improve low-bitrate encoding quality. Dynamically scales Intensity Stereo (IS) crossover and disables short-window Mid/Side (M/S) stereo under constrained bandwidths to eliminate pre-echo artifacts and save bit allocation for low-frequency phase detail.


Benchmark Data & MOS Results

image

Key MOS Highlights

  • Significant Low-Bitrate Lift: Major MOS gains at constrained stereo bitrates ($\le$48 kbps):
    • 24k Stereo: +0.592 ABR (49/0 wins) | +0.614 VBR (49/0 wins)
    • 32k Stereo: +0.396 ABR (49/0 wins) | +0.363 VBR (46/3 wins)
    • 40k Stereo: +0.213 ABR (43/2 wins) | +0.238 VBR (42/4 wins)
    • 48k Stereo: +0.105 ABR (40/4 wins) | +0.214 VBR (40/7 wins)
  • High Bitrate Neutrality: Zero regression at > 128 kbps (mono tracks and high-bitrate stereo maintain identical baseline performance).

Technical Changes

  • Disable Short-Window M/S at Low Bitrates: Prevents transient pre-echo when bandWidth <= 16000 Hz in JOINT_MIXED mode by falling back to JOINT_IS.
  • Dynamic IS Crossover: Scales crossover frequency between 3.5 kHz (IS_START_FREQ_MIN) and 7.0 kHz (IS_START_FREQ_MAX) based on bandWidth * 0.35 (capped at 0.35 * Fs).
  • Loop & Memory Optimizations: Precalculates IS target bin offsets (target_offset_long / target_offset_short) outside per-element loops and replaces element-wise clearing loops with memset() in apply_ms() and apply_mute().
  • API Update: Updates AACstereo() signature in libfaac/stereo.h / libfaac/stereo.c to take unsigned int bandWidth and updates the call site in libfaac/frame.c.

Pass the core bandwidth parameter to AACstereo() to adaptively scale
intensity stereo and restrict Mid/Side stereo decision boundaries.

Changes:
- Disable short-window M/S stereo when bandwidth <= 16 kHz in
  JOINT_MIXED mode to eliminate pre-echo and quantization noise.
- Dynamically scale the intensity stereo (IS) crossover frequency
  with configured core bandwidth (3.5 kHz - 7.0 kHz).
- Precalculate IS band target offsets outside the CPE processing loop
  to avoid redundant per-element divisions.
- Optimize apply_mute() and apply_ms() with memset for float arrays.
- Update libfaac/frame.c call site to pass config.bandWidth.
@fabiangreffrath
fabiangreffrath merged commit f255192 into knik0:master Aug 30, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants