Gemini Live native audio (24 kHz) plays one octave higher / sped up on 48 kHz browser hardware despite rate locking, unified paths, and AudioWorklet resampling.

Hello Gemini API community,

I’m building a real-time voice AI system using Gemini Live API (gemini-live-2.5-flash-native-audio) and facing a persistent high-pitch / chipmunk artifact after 4+ weeks of intensive debugging (including a full Antigravity-certified recovery blueprint).

Symptoms

  • Output is exactly one octave higher / sped up (classic time compression).

  • Duration test: 24 000 samples (1 second at 24 kHz) play in ~500 ms instead of ~1000 ms.

  • Logs confirm stable RAW BINARY path, hardwareRate=48000 Hz, ratio ≈0.5, no schema errors, no ghost path fallbacks.

What we’ve already fixed

  • Removed audio_format from handshake → no 400 Bad Request.

  • Unified ArrayBuffer + JSON/Base64 handling → only binary path used.

  • Clean bidirectional WebSocket proxy (no compression, no limits).

  • Hard-locked sourceRate=24000 in AudioPlayer.

  • Worklet with ring buffer, linear interpolation, 1-pole LPF, zero-crossing diagnostics (Antigravity certified as deployment-ready).

Suspected root cause (first-principles)
Gemini outputs fixed 24 kHz PCM → browser AudioContext clocks at 48 kHz → without correct upsampling, waveform plays in half the time → frequencies double (440 Hz test tone → 880 Hz).

Specific questions

  1. Is Gemini Live output strictly fixed 24 kHz little-endian PCM across all models/previews (no variability)?

  2. Are there known Web Audio / AudioWorklet quirks affecting 24→48 kHz upsampling in recent Chrome/Edge versions (e.g., render quantum, phase drift, buffer handoff)?

  3. What is the recommended low-latency, phase-accurate resampling pattern for real-time voice in AudioWorklet (e.g., correct phase accumulator direction, anti-aliasing filter placement, or polyphase alternative)?

Happy to share targeted / anonymized snippets (e.g., worklet process() logic), redacted logs, or a synthetic 440 Hz test audio file on request — protecting proprietary project details.

Any code pointers, sample worklets, known workarounds, or escalation suggestions would be incredibly helpful — this is blocking production rollout.

Thanks in advance!