diff options
Diffstat (limited to 'src/audio/tracker.cc')
| -rw-r--r-- | src/audio/tracker.cc | 42 |
1 files changed, 14 insertions, 28 deletions
diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc index d9beb56..651c4d2 100644 --- a/src/audio/tracker.cc +++ b/src/audio/tracker.cc @@ -1,6 +1,7 @@ #include "tracker.h" #include "audio.h" #include "audio/synth.h" +#include "ring_buffer.h" #include "util/asset_manager.h" #include "util/debug.h" #include "util/fatal_error.h" @@ -101,30 +102,24 @@ static float* convert_mp3_to_spectrogram(const uint8_t* data, size_t size, void tracker_init() { g_last_trigger_idx = 0; g_next_pool_slot = 0; - for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { - g_spec_pool[i].synth_id = -1; - g_spec_pool[i].data = nullptr; - g_spec_pool[i].active = false; - g_active_patterns[i].active = false; - } - - // Always re-initialize cache to ensure spectrograms are registered - // This handles the case where synth_init() was called multiple times - for (int i = 0; i < 256; ++i) { - g_sample_synth_cache[i] = -1; - } - // Free any previously allocated generated note data to prevent leaks + // Free any previously allocated generated note data to prevent leaks. + // Must run before the pool is zeroed (relies on .active/.data still set). if (g_cache_initialized) { for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { if (g_spec_pool[i].data != nullptr && g_spec_pool[i].active) { delete[] g_spec_pool[i].data; - g_spec_pool[i].data = nullptr; - g_spec_pool[i].active = false; } } } + for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { + g_spec_pool[i].synth_id = -1; + g_spec_pool[i].data = nullptr; + g_spec_pool[i].active = false; + g_active_patterns[i].active = false; + } + // Initialize sample cache { for (int i = 0; i < 256; ++i) { @@ -321,16 +316,6 @@ static void trigger_note_event(const TrackerEvent& event, } void tracker_update(float music_time_sec, float dt_music_sec) { - // TODO(timing): CRITICAL BUG - Events trigger ~180ms early over 63 beats @ - // BPM=90 Observed: Beat 63 snare at 41.82s in WAV, should be at 42.00s (180ms - // drift) NOTE: This is NOT a float vs double precision issue - floats handle - // <500s times fine Root cause unknown - suspects: - // 1. Systematic bias in time calculation (not random accumulation) - // 2. Truncation in audio.cc:103 chunk_frames = (int)(dt * sample_rate) - // 3. BPM calculation precision below (unit_duration_sec) - // 4. Mismatch between tracker time and actual sample rendering - // See also: audio.cc sample rendering truncation - // Unit-less timing: 1 unit = 4 beats (by convention) const float BEATS_PER_UNIT = 4.0f; const float unit_duration_sec = @@ -382,8 +367,8 @@ void tracker_update(float music_time_sec, float dt_music_sec) { // Offset = (music_time_delta / tempo_scale) * sample_rate int sample_offset = 0; if (event_music_time > music_time_sec) { - sample_offset = - (int)((event_music_time - music_time_sec) / tempo_scale * 32000.0f); + sample_offset = (int)((event_music_time - music_time_sec) / tempo_scale * + RING_BUFFER_SAMPLE_RATE); } // Apply humanization if enabled @@ -401,7 +386,8 @@ void tracker_update(float music_time_sec, float dt_music_sec) { float jitter = dist(rng) * (g_tracker_score.timing_variation_pct / 100.0f) * beat_sec; - sample_offset += (int)(jitter / tempo_scale * 32000.0f); + sample_offset += + (int)(jitter / tempo_scale * RING_BUFFER_SAMPLE_RATE); } // Volume variation: vary by % |
