# test_demo - Audio/Visual Synchronization Debug Tool ## Overview A minimal standalone tool for debugging audio/visual synchronization in the demo without the complexity of the full demo64k timeline. ## Features - **Simple Drum Beat**: Kick-snare pattern with crash every 4th bar - **NOTE_A4 Reference Tone**: 440 Hz tone plays at start of each bar for testing - **Screen Flash Effect**: Visual feedback synchronized to audio peaks - **16 Second Duration**: 8 bars at 120 BPM - **Variable Tempo Mode**: Tests tempo scaling (1.0x ↔ 1.5x and 1.0x ↔ 0.66x) - **Peak Logging**: Export audio peaks to file for gnuplot visualization ## Building ```bash cmake --build build --target test_demo ``` ## Usage ### Basic Usage ```bash build/test_demo ``` ### Command-Line Options ``` --help Show help message and exit --fullscreen Run in fullscreen mode --resolution WxH Set window resolution (e.g., 1024x768) --tempo Enable tempo variation test mode --log-peaks FILE Log audio peaks to FILE for gnuplot visualization ``` ### Examples #### Run in fullscreen ```bash build/test_demo --fullscreen ``` #### Custom resolution with tempo testing ```bash build/test_demo --resolution 1024x768 --tempo ``` #### Log audio peaks for analysis ```bash build/test_demo --log-peaks peaks.txt ``` After running, visualize with gnuplot: ```bash gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 1:3 with lines title 'Raw Peak'" ``` ## Keyboard Controls - **ESC**: Exit the demo - **F**: Toggle fullscreen ## Audio Pattern The demo plays a repeating drum pattern: ``` Bar 1-2: Kick-Snare-Kick-Snare (with A4 note) Bar 3: Kick+Crash-Snare-Kick-Snare (with A4 note) ← Crash landmark Bar 4-6: Kick-Snare-Kick-Snare (with A4 note) Bar 7: Kick+Crash-Snare-Kick-Snare (with A4 note) ← Crash landmark Bar 8: Kick-Snare-Kick-Snare (with A4 note) ``` **Timing:** - 120 BPM (2 beats per second) - 1 bar = 4 beats = 2 seconds - Total duration: 8 bars = 16 seconds **Crash Landmarks:** - First crash at T=4.0s (bar 3, beat 8) - Second crash at T=12.0s (bar 7, beat 24) ## Tempo Test Mode (`--tempo`) When enabled with `--tempo` flag, the demo alternates tempo scaling every bar: - **Even bars (0, 2, 4, 6)**: Accelerate from 1.0x → 1.5x - **Odd bars (1, 3, 5, 7)**: Decelerate from 1.0x → 0.66x This tests the variable tempo system where music time advances independently of physical time: - `music_time += dt * tempo_scale` - Pattern triggering respects tempo scaling - Audio samples play at normal pitch (no pitch shifting) **Console Output with --tempo:** ``` [T=0.50, MusicT=0.56, Beat=1, Frac=0.12, Peak=0.72, Tempo=1.25x] ``` **Expected Behavior:** - Physical time always advances at 1:1 (16 seconds = 16 seconds) - Music time advances faster during acceleration, slower during deceleration - By end of demo: Music time > Physical time (due to net acceleration) ## Peak Logging Format The `--log-peaks` option writes a text file with three columns: ``` # Audio peak log from test_demo # To plot with gnuplot: # gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 1:3 with lines title 'Raw Peak'" # Columns: beat_number clock_time raw_peak # 0 0.000000 0.850000 1 0.500000 0.720000 2 1.000000 0.800000 ... ``` **Columns:** 1. **beat_number**: Beat index (0, 1, 2, ...) 2. **clock_time**: Physical time in seconds 3. **raw_peak**: Audio peak value (0.0-1.0+) **Use Cases:** - Verify audio/visual synchronization timing - Detect clipping (peak > 1.0) - Analyze tempo scaling effects - Compare expected vs actual beat times ## Files - **`src/test_demo.cc`**: Main executable (~220 lines) - **`assets/test_demo.track`**: Drum pattern and NOTE_A4 definition - **`assets/test_demo.seq`**: Visual timeline (FlashEffect) - **`src/generated/test_demo_timeline.cc`**: Generated timeline (auto) - **`src/generated/test_demo_music.cc`**: Generated music data (auto) ## Verification Checklist ### Normal Mode - [ ] Visual flashes occur every ~0.5 seconds - [ ] Audio plays (kick-snare drum pattern audible) - [ ] A4 tone (440 Hz) audible at start of each bar - [ ] Synchronization: Flash happens simultaneously with kick hit - [ ] Crash landmark: Larger flash + cymbal crash at T=4.0s and T=12.0s - [ ] Auto-exit: Demo stops cleanly at 16 seconds - [ ] Console timing: Peak values spike when kicks hit (Peak > 0.7) - [ ] No audio glitches: Smooth playback, no stuttering ### Tempo Test Mode - [ ] Bar 0 accelerates (1.0x → 1.5x) - [ ] Bar 1 decelerates (1.0x → 0.66x) - [ ] Music time drifts from physical time - [ ] Audio still syncs with flashes - [ ] Smooth transitions at bar boundaries - [ ] Physical time = 16s at end - [ ] Music time > 16s at end - [ ] Console shows tempo value ### Peak Logging - [ ] File created when `--log-peaks` specified - [ ] Contains beat_number, clock_time, raw_peak columns - [ ] Gnuplot command in header comment - [ ] One row per beat (32 rows for 16 seconds) - [ ] Peak values match console output - [ ] Gnuplot visualization works ## Troubleshooting **Flash appears before audio:** - Cause: Audio latency too high - Fix: Reduce ring buffer size in `ring_buffer.h` **Flash appears after audio:** - Cause: Ring buffer under-filled - Fix: Increase pre-fill duration in `audio_render_ahead()` **No flash at all:** - Cause: Peak threshold not reached - Check: Console shows Peak > 0.7 - Fix: Increase `visual_peak` multiplier in code (currently 8.0×) **A4 note not audible:** - Cause: NOTE_A4 volume too low or procedural generation issue - Check: Console shows correct sample count (4 samples) - Fix: Increase volume in test_demo.track (currently 0.5) **Peak log file empty:** - Cause: Demo exited before first beat - Check: File has header comments - Fix: Ensure demo runs for at least 0.5 seconds ## Design Rationale **Why separate from demo64k?** - Isolated testing environment - No timeline complexity - Faster iteration cycles - Independent verification **Why use main demo assets?** - Avoid asset system conflicts (AssetId enum collision) - Reuse existing samples - No size overhead - Simpler CMake integration **Why 16 seconds?** - Long enough for verification (8 bars) - Short enough for quick tests - Crash landmarks at 25% and 75% for easy reference **Why NOTE_A4?** - Standard reference tone (440 Hz) - Easily identifiable pitch - Tests procedural note generation - Minimal code impact