From f2963ac821a3af1c54002ba13944552166956d04 Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 7 Feb 2026 16:41:30 +0100 Subject: fix(audio): Synchronize audio-visual timing with playback time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: test_demo was "flashing a lot" - visual effects triggered ~400ms before audio was heard, causing poor synchronization. Root Causes: 1. Beat calculation used physical time (platform_state.time), but audio peak measured at playback time (400ms behind due to ring buffer) 2. Peak decay too slow (0.7 per callback = 800ms fade) relative to beat interval (500ms at 120 BPM) Solution: 1. Use audio_get_playback_time() for beat calculation - Automatically accounts for ring buffer latency - No hardcoded constants (was considering hardcoding 400ms offset) - System queries its own state 2. Faster decay rate (0.5 vs 0.7) to match beat interval 3. Added inline PeakMeterEffect for visual debugging Changes: - src/test_demo.cc: - Added inline PeakMeterEffect class (red bar visualization) - Use audio_get_playback_time() instead of physical time for beat calc - Updated logging to show audio time - src/audio/backend/miniaudio_backend.cc: - Changed decay rate from 0.7 to 0.5 (500ms fade time) - src/gpu/gpu.{h,cc}: - Added gpu_add_custom_effect() API for runtime effect injection - Exposed g_device, g_queue, g_format as non-static globals - doc/PEAK_METER_DEBUG.md: - Initial analysis of timing issues - doc/AUDIO_TIMING_ARCHITECTURE.md: - Comprehensive architecture documentation - Time source hierarchy (physical → audio playback → music) - Future work: TimeProvider class, tracker_get_bpm() API Architectural Principle: Single source of truth - platform_get_time() is the only physical clock. Everything else derives from it. No hardcoded latency constants. Result: Visual effects now sync perfectly with heard audio. --- src/gpu/gpu.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gpu/gpu.h') diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index d7f5a8d..b8f58b2 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -7,6 +7,7 @@ #include "platform/platform.h" struct PlatformState; // Forward declaration +class Effect; // Forward declaration // Basic wrapper for WebGPU buffers struct GpuBuffer { @@ -36,6 +37,12 @@ void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat); void gpu_resize(int width, int height); #if !defined(STRIP_ALL) void gpu_simulate_until(float time); +void gpu_add_custom_effect(Effect* effect, float start_time, float end_time, int priority); + +// Expose WebGPU globals for custom effects (debug builds only) +extern WGPUDevice g_device; +extern WGPUQueue g_queue; +extern WGPUTextureFormat g_format; #endif void gpu_shutdown(); -- cgit v1.2.3