summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/music.track331
-rw-r--r--src/main.cc31
-rw-r--r--src/tests/test_tracker.cc8
3 files changed, 201 insertions, 169 deletions
diff --git a/assets/music.track b/assets/music.track
index c0b343e..7a0c963 100644
--- a/assets/music.track
+++ b/assets/music.track
@@ -1,205 +1,206 @@
-# Rock Demo Track - Full drum kit arrangement
-# Samples: name, freq, duration, amp, attack, harmonics, harmonic_decay (for generated)
-# OR SAMPLE ASSET_ASSETID (for assets)
+# Tempo Test Track - Drum beat with acceleration/deceleration tests
+# Tests variable tempo system with clear, debuggable patterns
-# Import all available drum samples
+# Import drum samples
SAMPLE ASSET_KICK_1
SAMPLE ASSET_KICK_2
-SAMPLE ASSET_KICK_3
SAMPLE ASSET_SNARE_1
-SAMPLE ASSET_SNARE_2
SAMPLE ASSET_SNARE_3
-SAMPLE ASSET_SNARE_4
SAMPLE ASSET_HIHAT_1
SAMPLE ASSET_HIHAT_2
-SAMPLE ASSET_HIHAT_3
-SAMPLE ASSET_HIHAT_4
SAMPLE ASSET_CRASH_1
-SAMPLE ASSET_RIDE_1
-SAMPLE ASSET_SPLASH_1
SAMPLE ASSET_BASS_1
-SAMPLE ASSET_SYNTH_BASS_1
-# Rock beat - kick and snare foundation (4/4 time)
-PATTERN rock_beat
+# Simple kick pattern with light syncopation
+# Pattern duration: 4 beats (2 seconds at 120 BPM)
+PATTERN kick_basic
0.0, ASSET_KICK_1, 1.0, 0.0
- 1.0, ASSET_SNARE_3, 0.9, 0.1
2.0, ASSET_KICK_1, 1.0, 0.0
- 2.5, ASSET_KICK_1, 0.7, -0.1
- 3.0, ASSET_SNARE_3, 0.9, 0.1
+ 2.5, ASSET_KICK_2, 0.7, -0.2
-# Heavy double kick pattern
-PATTERN double_kick
- 0.0, ASSET_KICK_3, 1.0, 0.0
- 0.5, ASSET_KICK_2, 0.8, -0.2
- 1.0, ASSET_SNARE_4, 0.95, 0.2
- 1.5, ASSET_KICK_3, 0.7, 0.1
- 2.0, ASSET_KICK_3, 1.0, 0.0
- 2.5, ASSET_KICK_2, 0.8, -0.2
- 3.0, ASSET_SNARE_4, 0.95, 0.2
- 3.5, ASSET_KICK_3, 0.6, 0.1
+# Snare on beats 2 and 4
+PATTERN snare_basic
+ 1.0, ASSET_SNARE_1, 0.9, 0.1
+ 3.0, ASSET_SNARE_1, 0.9, 0.1
-# Standard 8th note hi-hat pattern
-PATTERN hihat_8th
- 0.0, ASSET_HIHAT_2, 0.6, -0.3
- 0.5, ASSET_HIHAT_1, 0.45, 0.3
- 1.0, ASSET_HIHAT_2, 0.6, -0.3
- 1.5, ASSET_HIHAT_1, 0.45, 0.3
- 2.0, ASSET_HIHAT_2, 0.6, -0.3
- 2.5, ASSET_HIHAT_1, 0.45, 0.3
- 3.0, ASSET_HIHAT_2, 0.6, -0.3
- 3.5, ASSET_HIHAT_1, 0.45, 0.3
+# Hi-hat 8th notes with stress on beats
+PATTERN hihat_stressed
+ 0.0, ASSET_HIHAT_2, 0.8, -0.3
+ 0.5, ASSET_HIHAT_1, 0.4, 0.3
+ 1.0, ASSET_HIHAT_2, 0.8, -0.3
+ 1.5, ASSET_HIHAT_1, 0.4, 0.3
+ 2.0, ASSET_HIHAT_2, 0.8, -0.3
+ 2.5, ASSET_HIHAT_1, 0.4, 0.3
+ 3.0, ASSET_HIHAT_2, 0.8, -0.3
+ 3.5, ASSET_HIHAT_1, 0.4, 0.3
-# 16th note hi-hat for intensity
-PATTERN hihat_16th
- 0.0, ASSET_HIHAT_3, 0.7, -0.4
- 0.25, ASSET_HIHAT_1, 0.35, 0.4
- 0.5, ASSET_HIHAT_3, 0.55, -0.2
- 0.75, ASSET_HIHAT_1, 0.35, 0.2
- 1.0, ASSET_HIHAT_3, 0.7, -0.4
- 1.25, ASSET_HIHAT_1, 0.35, 0.4
- 1.5, ASSET_HIHAT_3, 0.55, -0.2
- 1.75, ASSET_HIHAT_1, 0.35, 0.2
- 2.0, ASSET_HIHAT_3, 0.7, -0.4
- 2.25, ASSET_HIHAT_1, 0.35, 0.4
- 2.5, ASSET_HIHAT_3, 0.55, -0.2
- 2.75, ASSET_HIHAT_1, 0.35, 0.2
- 3.0, ASSET_HIHAT_3, 0.7, -0.4
- 3.25, ASSET_HIHAT_1, 0.35, 0.4
- 3.5, ASSET_HIHAT_3, 0.55, -0.2
- 3.75, ASSET_HIHAT_1, 0.35, 0.2
+# Denser kick pattern for reset trick (2x faster)
+PATTERN kick_dense
+ 0.0, ASSET_KICK_1, 1.0, 0.0
+ 0.5, ASSET_KICK_2, 0.6, -0.2
+ 1.0, ASSET_KICK_1, 1.0, 0.0
+ 1.5, ASSET_KICK_2, 0.6, 0.2
+ 2.0, ASSET_KICK_1, 1.0, 0.0
+ 2.5, ASSET_KICK_2, 0.6, -0.2
+ 3.0, ASSET_KICK_1, 1.0, 0.0
+ 3.5, ASSET_KICK_2, 0.6, 0.2
-# Ride cymbal pattern for variation
-PATTERN ride_pattern
- 0.0, ASSET_RIDE_1, 0.65, 0.5
- 0.5, ASSET_RIDE_1, 0.5, -0.3
- 1.0, ASSET_RIDE_1, 0.65, 0.5
- 1.5, ASSET_RIDE_1, 0.5, -0.3
- 2.0, ASSET_RIDE_1, 0.65, 0.5
- 2.5, ASSET_RIDE_1, 0.5, -0.3
- 3.0, ASSET_RIDE_1, 0.7, 0.5
- 3.5, ASSET_RIDE_1, 0.5, -0.3
+# Denser snare pattern
+PATTERN snare_dense
+ 0.5, ASSET_SNARE_3, 0.7, 0.0
+ 1.0, ASSET_SNARE_1, 0.9, 0.1
+ 1.5, ASSET_SNARE_3, 0.7, 0.0
+ 2.5, ASSET_SNARE_3, 0.7, 0.0
+ 3.0, ASSET_SNARE_1, 0.9, 0.1
+ 3.5, ASSET_SNARE_3, 0.7, 0.0
-# Crash accents (single crash at start)
-PATTERN crash_accent
+# Crash accent
+PATTERN crash
0.0, ASSET_CRASH_1, 0.85, 0.0
-# Splash accent for transitions
-PATTERN splash_accent
- 0.0, ASSET_SPLASH_1, 0.75, 0.3
-
-# Fill pattern with snare rolls and toms
-PATTERN snare_fill
- 0.0, ASSET_SNARE_2, 0.6, -0.4
- 0.25, ASSET_SNARE_2, 0.65, -0.2
- 0.5, ASSET_SNARE_2, 0.7, 0.0
- 0.75, ASSET_SNARE_3, 0.75, 0.2
- 1.0, ASSET_SNARE_3, 0.8, 0.4
- 1.25, ASSET_SNARE_4, 0.85, 0.2
- 1.5, ASSET_SNARE_4, 0.9, 0.0
- 1.75, ASSET_SNARE_4, 0.95, -0.2
+# Bass line in E
+PATTERN bass_e
+ 0.0, E2, 0.9, 0.0
+ 1.0, E2, 0.7, 0.0
+ 2.0, E2, 0.9, 0.0
+ 2.5, E2, 0.6, 0.0
+ 3.0, E2, 0.7, 0.0
-# Power chord progression in E minor
-PATTERN power_riff
- 0.0, E2, 0.8, -0.5
- 0.5, E2, 0.6, -0.5
- 1.0, G2, 0.8, -0.3
- 1.5, G2, 0.6, -0.3
- 2.0, A2, 0.8, 0.3
- 2.5, A2, 0.6, 0.3
- 3.0, B2, 0.8, 0.5
- 3.5, B2, 0.6, 0.5
+# Bass line with variation (E-G progression)
+PATTERN bass_eg
+ 0.0, E2, 0.9, 0.0
+ 1.0, E2, 0.7, 0.0
+ 2.0, G2, 0.9, 0.0
+ 3.0, G2, 0.7, 0.0
-# Lead melody in E minor scale
-PATTERN lead_melody
+# Simple melody in E minor
+PATTERN melody_em
0.0, E4, 0.7, 0.0
- 0.5, G4, 0.65, 0.1
+ 0.5, G4, 0.6, 0.1
1.0, B4, 0.7, -0.1
- 1.5, D5, 0.65, 0.2
- 2.0, E5, 0.75, -0.2
- 2.5, D5, 0.65, 0.1
- 3.0, B4, 0.7, 0.0
- 3.5, A4, 0.65, -0.1
-
-# Bass line synced with kick
-PATTERN bass_line
- 0.0, E2, 0.9, 0.0
- 1.0, E2, 0.75, 0.0
- 2.0, E2, 0.9, 0.0
- 2.5, E2, 0.7, 0.0
- 3.0, G2, 0.85, 0.0
+ 2.0, A4, 0.6, 0.0
+ 2.5, G4, 0.6, 0.1
+ 3.0, E4, 0.7, 0.0
# Score: time_sec, pattern_name
-# NOTE: Patterns are 4 beats = 2 seconds at 120 BPM
+# NOTE: Timing in MUSIC TIME (not physical time)
+# Physical time will vary based on tempo_scale in main.cc
SCORE
-# Intro - Build up with hi-hat and kick (0-4s)
- 0.0, crash_accent
- 0.0, hihat_8th
- 0.0, rock_beat
+# Phase 1: Steady beat (0-10s music time)
+# tempo_scale = 1.0 throughout
+ 0.0, crash
+ 0.0, kick_basic
+ 0.0, snare_basic
+ 0.0, hihat_stressed
+
+ 2.0, kick_basic
+ 2.0, snare_basic
+ 2.0, hihat_stressed
+
+ 4.0, crash
+ 4.0, kick_basic
+ 4.0, snare_basic
+ 4.0, hihat_stressed
+
+ 6.0, kick_basic
+ 6.0, snare_basic
+ 6.0, hihat_stressed
+
+ 8.0, crash
+ 8.0, kick_basic
+ 8.0, snare_basic
+ 8.0, hihat_stressed
+
+# Phase 2: Acceleration section (10-15s music time)
+# tempo_scale accelerates from 1.0 to 2.0
+# Then resets to 1.0 with denser patterns
+ 10.0, crash
+ 10.0, kick_basic
+ 10.0, snare_basic
+ 10.0, hihat_stressed
+ 10.0, bass_e
- 2.0, hihat_8th
- 2.0, rock_beat
+ 12.0, kick_basic
+ 12.0, snare_basic
+ 12.0, hihat_stressed
+ 12.0, bass_e
-# Main groove - Add bass (4-8s)
- 4.0, crash_accent
- 4.0, hihat_8th
- 4.0, rock_beat
- 4.0, bass_line
+ 14.0, kick_basic
+ 14.0, snare_basic
+ 14.0, hihat_stressed
+ 14.0, bass_e
- 6.0, hihat_8th
- 6.0, rock_beat
- 6.0, bass_line
+# Phase 3: After reset - denser patterns (16-20s music time)
+# tempo_scale = 1.0 with 2x denser patterns
+ 16.0, crash
+ 16.0, kick_dense
+ 16.0, snare_dense
+ 16.0, hihat_stressed
+ 16.0, bass_e
-# Add melody and increase intensity (8-12s)
- 8.0, splash_accent
- 8.0, hihat_16th
- 8.0, double_kick
- 8.0, bass_line
- 8.0, lead_melody
+ 18.0, kick_dense
+ 18.0, snare_dense
+ 18.0, hihat_stressed
+ 18.0, bass_eg
- 10.0, hihat_16th
- 10.0, double_kick
- 10.0, bass_line
- 10.0, lead_melody
+# Phase 4: Slow-down section (20-25s music time)
+# tempo_scale decelerates from 1.0 to 0.5
+# Then resets to 1.0
+ 20.0, crash
+ 20.0, kick_dense
+ 20.0, snare_dense
+ 20.0, hihat_stressed
+ 20.0, bass_e
-# Ride variation (12-16s)
- 12.0, crash_accent
- 12.0, ride_pattern
- 12.0, double_kick
- 12.0, power_riff
+ 22.0, kick_dense
+ 22.0, snare_dense
+ 22.0, hihat_stressed
+ 22.0, bass_e
- 14.0, ride_pattern
- 14.0, double_kick
- 14.0, power_riff
+ 24.0, kick_dense
+ 24.0, snare_dense
+ 24.0, hihat_stressed
+ 24.0, bass_eg
-# Fill and breakdown (16-18s)
- 16.0, snare_fill
- 16.0, hihat_16th
+# Phase 5: After slow-down reset (26-30s music time)
+# Back to normal tempo with bass
+ 26.0, crash
+ 26.0, kick_basic
+ 26.0, snare_basic
+ 26.0, hihat_stressed
+ 26.0, bass_e
- 17.0, splash_accent
- 17.0, hihat_8th
- 17.0, rock_beat
- 17.0, bass_line
+ 28.0, kick_basic
+ 28.0, snare_basic
+ 28.0, hihat_stressed
+ 28.0, bass_eg
-# Climax with all elements (18-22s)
- 18.0, crash_accent
- 18.0, hihat_16th
- 18.0, double_kick
- 18.0, bass_line
- 18.0, lead_melody
+# Phase 6: Add melody (30s+ music time)
+ 30.0, crash
+ 30.0, kick_basic
+ 30.0, snare_basic
+ 30.0, hihat_stressed
+ 30.0, bass_e
+ 30.0, melody_em
- 20.0, hihat_16th
- 20.0, double_kick
- 20.0, bass_line
- 20.0, power_riff
+ 32.0, kick_basic
+ 32.0, snare_basic
+ 32.0, hihat_stressed
+ 32.0, bass_eg
+ 32.0, melody_em
-# Final fill and outro (22-24s)
- 22.0, snare_fill
- 22.0, hihat_16th
+ 34.0, kick_basic
+ 34.0, snare_basic
+ 34.0, hihat_stressed
+ 34.0, bass_e
+ 34.0, melody_em
- 23.0, crash_accent
- 23.0, rock_beat
- 23.0, bass_line
+ 36.0, crash
+ 36.0, kick_basic
+ 36.0, snare_basic
+ 36.0, hihat_stressed
+ 36.0, bass_eg
+ 36.0, melody_em
-# Ending crash
- 25.0, crash_accent
+# Ending
+ 38.0, crash
diff --git a/src/main.cc b/src/main.cc
index 9f61f07..3d05822 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -101,6 +101,37 @@ int main(int argc, char** argv) {
int beat_count = 0;
auto update_game_logic = [&](double t) {
+ // Variable tempo test: Accelerate and decelerate based on physical time
+ // Phase 1 (0-10s): Steady at 1.0x
+ // Phase 2 (10-15s): Accelerate from 1.0x to 2.0x
+ // Phase 3 (15-20s): Reset to 1.0x (with denser patterns in track)
+ // Phase 4 (20-25s): Decelerate from 1.0x to 0.5x
+ // Phase 5 (25s+): Reset to 1.0x (back to normal)
+ const float prev_tempo = g_tempo_scale;
+ if (t < 10.0) {
+ g_tempo_scale = 1.0f; // Phase 1: Steady
+ } else if (t < 15.0) {
+ // Phase 2: Linear acceleration
+ const float progress = (float)(t - 10.0) / 5.0f;
+ g_tempo_scale = 1.0f + progress * 1.0f; // 1.0 → 2.0
+ } else if (t < 20.0) {
+ g_tempo_scale = 1.0f; // Phase 3: Reset to normal
+ } else if (t < 25.0) {
+ // Phase 4: Linear deceleration
+ const float progress = (float)(t - 20.0) / 5.0f;
+ g_tempo_scale = 1.0f - progress * 0.5f; // 1.0 → 0.5
+ } else {
+ g_tempo_scale = 1.0f; // Phase 5: Reset to normal
+ }
+
+#if !defined(STRIP_ALL)
+ // Debug output when tempo changes significantly
+ if (fabsf(g_tempo_scale - prev_tempo) > 0.05f) {
+ printf("[Tempo] t=%.2fs, tempo=%.3fx, music_time=%.3fs\n", (float)t,
+ g_tempo_scale, g_music_time);
+ }
+#endif
+
// Calculate delta time and advance music time at scaled rate
const float dt = (float)(t - g_last_physical_time);
g_last_physical_time = t;
diff --git a/src/tests/test_tracker.cc b/src/tests/test_tracker.cc
index 2a9239c..ea1debd 100644
--- a/src/tests/test_tracker.cc
+++ b/src/tests/test_tracker.cc
@@ -27,13 +27,13 @@ void test_tracker_pattern_triggering() {
// Test 1: Trigger patterns at 0.0f
tracker_update(0.0f);
printf("Actual active voice count: %d\n", synth_get_active_voice_count());
- // Expect 3 voices (one for each pattern triggered at 0.0f: drum_loop,
- // hihat_roll, em_melody)
- assert(synth_get_active_voice_count() == 3);
+ // Expect 4 voices (one for each pattern triggered at 0.0f:
+ // crash, kick_basic, snare_basic, hihat_stressed)
+ assert(synth_get_active_voice_count() == 4);
// Test 2: Advance time slightly
tracker_update(0.1f);
- assert(synth_get_active_voice_count() == 3);
+ assert(synth_get_active_voice_count() == 4);
// Test 3: Advance further, no new triggers until 4.0f
tracker_update(3.0f);