From 8a41ac7cb95c65d68892810d89c9c80a0463f06d Mon Sep 17 00:00:00 2001 From: skal Date: Fri, 13 Feb 2026 13:17:29 +0100 Subject: Tracker: Sort pattern events + add validation/sanitize modes - tracker_compiler: Sort events by time before C++ generation (required for runtime early-exit optimization) - tracker.cc: Add FATAL_CHECK validating sorted events at init - Add --check mode: Validate .track file without compiling - Add --sanitize mode: Rewrite .track with sorted events and normalized formatting - Fix parser: Skip indented comment lines in patterns All audio tests passing. Co-Authored-By: Claude Sonnet 4.5 --- src/audio/tracker.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/audio') diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc index d887208..67c197f 100644 --- a/src/audio/tracker.cc +++ b/src/audio/tracker.cc @@ -3,6 +3,7 @@ #include "audio/synth.h" #include "util/asset_manager.h" #include "util/debug.h" +#include "util/fatal_error.h" #include #include @@ -140,6 +141,21 @@ void tracker_init() { g_tracker_samples_count); #endif /* defined(DEBUG_LOG_TRACKER) */ } + + // Validate that all pattern events are sorted by unit_time + // (required for early-exit optimization in tracker_update) + FATAL_CODE_BEGIN + for (uint32_t pid = 0; pid < g_tracker_patterns_count; ++pid) { + const TrackerPattern& pattern = g_tracker_patterns[pid]; + for (uint32_t i = 1; i < pattern.num_events; ++i) { + FATAL_CHECK(pattern.events[i].unit_time < pattern.events[i - 1].unit_time, + "Pattern %d has unsorted events: event[%d].time=%.3f < " + "event[%d].time=%.3f\n", + pid, i, pattern.events[i].unit_time, i - 1, + pattern.events[i - 1].unit_time); + } + } + FATAL_CODE_END } void tracker_reset() { -- cgit v1.2.3