summaryrefslogtreecommitdiff
path: root/src/audio/tracker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/tracker.cc')
-rw-r--r--src/audio/tracker.cc42
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 %