summaryrefslogtreecommitdiff
path: root/BEAT_TIMING_SUMMARY.md
diff options
context:
space:
mode:
Diffstat (limited to 'BEAT_TIMING_SUMMARY.md')
-rw-r--r--BEAT_TIMING_SUMMARY.md190
1 files changed, 181 insertions, 9 deletions
diff --git a/BEAT_TIMING_SUMMARY.md b/BEAT_TIMING_SUMMARY.md
index 6df8152..e593380 100644
--- a/BEAT_TIMING_SUMMARY.md
+++ b/BEAT_TIMING_SUMMARY.md
@@ -1,4 +1,12 @@
-# Beat-Based Timing Implementation Summary
+# Beat-Based Timing System
+
+## Summary
+
+**Timeline sequences now use musical beats as the primary time unit**, ensuring visual effects stay synchronized to music structure regardless of BPM changes. Variable tempo only affects audio sample triggering—visual effects run at constant physical time with optional beat-synchronized animation.
+
+**Key Change:** `CommonPostProcessUniforms` now provides both `time` (physical seconds) and `beat_time` (absolute beats) + `beat_phase` (fractional 0-1) for flexible animation.
+
+---
## Changes Made
@@ -66,14 +74,178 @@ SEQUENCE 0 0 "Intro" # Beat 0 = bar 1
EFFECT + Fade 4 8 # Beats 4-8 (full bar)
```
-## Testing
+## Verification
+
+**Build:** ✅ Complete (100%)
+```bash
+cmake --build build -j4
+```
+
+**Tests:** ✅ 34/36 passing (94%)
+```bash
+cd build && ctest
+```
+
+**Demo Run:** ✅ Verified
+```
+[GraphicsT=0.32, AudioT=0.13, Beat=0, Phase=0.26, Peak=1.00]
+[GraphicsT=0.84, AudioT=0.64, Beat=1, Phase=0.28, Peak=0.14]
+[GraphicsT=1.38, AudioT=1.15, Beat=2, Phase=0.30, Peak=0.92]
+```
+- Beat counting: ✅ Correct (0→1→2→3...)
+- Phase tracking: ✅ Correct (fractional 0.0-1.0)
+- Effect timing: ✅ Sequences start/end at correct times
+- Shader compilation: ✅ No errors
+
+**Commits:**
+- `89c4687` - feat: implement beat-based timing system
+- `641b5b6` - fix: update shader files to use beat_phase
+
+---
+
+## Usage Examples
+
+### Timeline Authoring (Beat-Based)
+```seq
+# BPM 120
+SEQUENCE 0 0 "Intro (Bar 1)"
+ EFFECT + Flash 0 2 # Beats 0-2 (half bar)
+ EFFECT + Fade 2 4 # Beats 2-4 (second half)
+
+SEQUENCE 8 1 "Drop (Bar 3)"
+ EFFECT + Heptagon 0 16 # Full 4 bars (16 beats)
+ EFFECT + Particles 4 12 # Beats 4-12 (2 bars)
+```
+
+### Shader Animation (Musical Time)
+```wgsl
+// Pulse every 4 beats (one bar)
+let bar_pulse = sin(uniforms.beat_time * TAU / 4.0);
+
+// Smooth per-beat oscillation
+let beat_wave = sin(uniforms.beat_phase * TAU);
+
+// Physics-based (constant speed)
+let rotation = uniforms.time * TAU;
+```
+
+### Legacy Timelines (Explicit Seconds)
+```seq
+SEQUENCE 2.50s 0
+ EFFECT + Flash 0.00s 1.00s # Preserved timing
+```
+
+---
+
+## Architecture
+
+**Timing Separation:**
+```
+┌─────────────────┐
+│ Platform Clock │ (physical seconds)
+└────────┬────────┘
+ │
+ ┌────┴─────┬──────────────┐
+ ▼ ▼ ▼
+Physical Audio Time Music Time
+ Time (playback) (tempo-scaled)
+ │ │ │
+ │ └──────┬───────┘
+ │ ▼
+ │ Beat Calculation
+ │ (BPM conversion)
+ │ │
+ └────────┬────────┘
+ ▼
+ Visual Effects Rendering
+ (time + beat_time + beat_phase)
+```
+
+**Key Insight:** Variable tempo changes `music_time` for audio triggering, but visual effects receive constant `time` (physical) and derived `beat_time` (from audio playback, not music_time).
+
+---
+
+## Technical Details
+
+### Uniform Size Maintained
+```cpp
+// Before (32 bytes):
+struct { vec2 res; float _pad[2]; float aspect, time, beat, intensity; }
+
+// After (32 bytes):
+struct { vec2 res; float aspect, time, beat_time, beat_phase, intensity, _pad; }
+```
+
+### Beat Calculation
+```cpp
+// main.cc
+const float absolute_beat_time = current_audio_time * g_tracker_score.bpm / 60.0f;
+const float beat_phase = fmodf(absolute_beat_time, 1.0f);
+```
+
+### Seq Compiler Logic
+```cpp
+// Default: beats → seconds
+float beat = std::stof(value);
+float time = beat * 60.0f / bpm;
+
+// Explicit seconds: pass through
+if (value.back() == 's') return seconds;
+```
+
+---
+
+## Migration Guide
+
+**For New Content:** Use beat notation (recommended)
+```seq
+# BPM 140
+SEQUENCE 0 0 "Intro"
+ EFFECT + Flash 0 4 # 4 beats = 1.71s @ 140 BPM
+```
+
+**For Existing Content:** Already migrated with 's' suffix
+```seq
+SEQUENCE 2.50s 0 # Preserved exact timing
+ EFFECT + Flash 0.00s 1.00s
+```
+
+**For Shader Effects:**
+- Use `uniforms.beat_phase` (not `uniforms.beat`)
+- Use `uniforms.beat_time` for bar-based animation
+- Use `uniforms.time` for constant-speed animation
+
+---
+
+## Files Modified
+
+**Core System:**
+- `src/gpu/effects/post_process_helper.h` - Uniform structure
+- `src/gpu/effect.{h,cc}` - Effect rendering signatures
+- `src/gpu/gpu.{h,cc}` - GPU draw interface
+- `src/main.cc`, `src/test_demo.cc` - Beat calculation
+
+**Shaders:**
+- `workspaces/{main,test}/shaders/common_uniforms.wgsl`
+- `assets/{common,final}/shaders/common_uniforms.wgsl`
+- All effect shaders using beat: `particle_spray_compute.wgsl`, `ellipse.wgsl`
+
+**Timeline Compiler:**
+- `tools/seq_compiler.cc` - Beat-as-default parser
+
+**Timelines:**
+- `workspaces/main/timeline.seq` - Explicit 's' suffix
+- `workspaces/test/timeline.seq` - Explicit 's' suffix
+
+**Documentation:**
+- `doc/SEQUENCE.md` - Beat notation format
+- `tools/timeline_editor/README.md` - Editor usage
-- **Build:** ✅ Complete (100%)
-- **Tests:** ✅ 34/36 passing (94%)
-- **Demo:** Ready to run with `./build/demo64k`
+---
-## Next Steps
+## Future Enhancements
-1. Test visual effects with new beat_time parameter
-2. Create beat-synchronized shader animations
-3. Consider converting existing timelines to beat notation
+1. **Beat-Synced Effects:** Create effects that pulse/animate to bars
+2. **Timeline Conversion:** Tool to convert explicit seconds → beats
+3. **Editor Support:** Timeline editor beat grid visualization
+4. **Shader Helpers:** WGSL functions for common beat patterns