Skip to content

fix(playback): refactor Auto DJ eager prefetcher and C++ Oboe Automix processor - #430

Merged
ajisth69 merged 2 commits into
mainfrom
fix/autodj-automix-dsp-and-prefetch
Oct 26, 2026
Merged

ajisth69 merged 2 commits into
mainfrom
fix/autodj-automix-dsp-and-prefetch

Conversation

@ajisth69

Copy link
Copy Markdown
Member

Summary

Resolves 4 critical playback bugs in Auto DJ and Automix:

  1. Audio clipping and distortion during transitions
  2. Music gaps and stalls from unbuffered/undecoded incoming tracks
  3. Filter zipper clicks and jerky jumps during EQ/filter changes
  4. Stutters caused by blocking operations or Opus-to-FLAC hot-swapping during transitions

Key Changes

1. Eager Prefetch & RAM Pre-Decoded Buffer

  • Immediate Prefetch Trigger: Auto DJ starts resolving stream URL for \index + 1\ within 2 seconds of Deck A playback start on \Dispatchers.IO.
  • Decoded PCM Buffer Requirement: Deck B transitions through \DECODING_HEAD_WINDOW\ and is only marked \ARMED_READY\ once >= 12.0s of raw float PCM samples are pre-decoded in RAM.
  • Freeze Opus-to-FLAC Hot-Swap: Added \isStreamSwapLocked()\ in \MusicPlayer\ to lock stream source within 35 seconds of track completion, while Deck B is pre-decoding, or during active transitions.
  • Safe Fallback: If Deck A reaches \outCueMs\ and Deck B has < 8.0s of decoded PCM in RAM, gracefully falls back to natural playback until track end for a clean gapless handoff.

2. Clipping & Distortion Elimination in C++ Oboe Mixer

  • Attenuation Only: Clamped \gainTrimDb\ / \gainOffsetDb\ to [-6.0f, 0.0f]\ to eliminate positive makeup gain overload.
  • Correlated-Bass Headroom Compensation: Multiplied crossfade curves by (1.0f - 0.25f * sin(t * PI))\ to prevent +3 dB equal-power midpoint clipping.
  • Flat Butterworth Q (0.7071f): Removed resonant filter peaks (Q > 0.707f); standardized on flat Butterworth response.
  • Scaled Wet FX Returns: Scaled reverb/echo wet returns to <= 0.22f and proportionally attenuated dry signal (\dryGain *= (1.0f - 0.35f * wetSend)).
  • Master Bus Soft-Knee Safety Limiter: Continuous tanh soft-knee limiter with 0.85f threshold and 0.98f hard ceiling at the final mixer output and before PCM export.

3. Per-Sample Smoothing & S-Curve Crossover

  • Cytomic SVF: Replaced standard biquad coefficient snapping with Trapezoidal Integrated State Variable Filters.
  • One-Pole Parameter Smoother: Smoothed \gainA, \gainB, \cutoffA, and \cutoffB\ per-sample (\currentVal += 0.0015f * (targetVal - currentVal)).
  • Continuous Cosine S-Curve Bass Swap: Crossfades Deck B HPF (200 Hz -> 20 Hz) and Deck A HPF (20 Hz -> 350 Hz) smoothly across the 35% -> 65% transition zone using a cosine S-curve.

4. Lock-Free Real-Time Audio Thread

  • Dedicated SPSC lock-free ring buffer (\LockFreeRingBuffer).
  • Pre-allocated all scratch and loop buffers during configuration; removed dynamic allocations (.resize()), mutexes, JNI calls, FFT calculations, and file I/O from the audio rendering path.

Verification

  • Unit test suites passed:
    • \ est_echo_tail: Verified echo peak (0.525f) and decay tail without clipping.
    • \ est_transition_planner: Verified out-cue clamping, skit skipping, vocal pocket ducking (-9.0 dB), and midpoint bass swap.
    • \ est_automix_dsp_upgrades: Verified Cytomic SVF crossover, Butterworth Q = 0.7071f, in-place PCM16 conversion, and transient alignment.
    • \ est_automix_engine: Verified leading silence trimming, fast skip fading, and buffer handoffs.
    • \ est_autodj_processor: Verified latency estimation and decision pipelines.

… processor

- Eager prefetch within 2 seconds of playback start instead of waiting near track end
- Require >= 12.0s of decoded PCM in RAM ring buffer before marking Deck B as ARMED_READY
- Freeze Opus-to-FLAC stream hot-swapping during transitions, pre-decoding, or near track end
- Safe fallback when buffered < 8.0s: continue natural playback to track end for clean handoff
- Eliminate clipping: attenuation-only loudness matching, equal-power correlated-bass headroom compensation, Butterworth Q=0.7071 filters, scaled wet FX returns, and tanh master soft-knee safety limiter
- Eliminate zipper noise & clicks: Cytomic SVF crossover, per-sample one-pole parameter smoothing, and continuous cosine S-curve bass swap
- Strict lock-free real-time audio thread: pre-allocated scratch/loop buffers, no mutexes or allocations in onAudioReady()
@ajisth69
ajisth69 merged commit c31113f into main Oct 26, 2026
1 check failed
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.

1 participant