summaryrefslogtreecommitdiff
path: root/src/audio/audio_engine.h
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-05 19:13:34 +0100
committerskal <pascal.massimino@gmail.com>2026-02-05 19:13:34 +0100
commit798fc6d471a70ed930e5b1fc084818cb337ca5b1 (patch)
treebf89015f733bc7c52e4b9c37593669cb69ae8bd8 /src/audio/audio_engine.h
parent4a3f7a2c379a3e9554e720685e03842180b021ce (diff)
feat(audio): Implement AudioEngine and SpectrogramResourceManager (Task #56 Phase 1)
Implements Phase 1 of the audio lifecycle refactor to eliminate initialization order dependencies between synth and tracker. New Components: 1. SpectrogramResourceManager (src/audio/spectrogram_resource_manager.{h,cc}) - Centralized resource loading and ownership - Lazy loading: resources registered but not loaded until needed - Handles both asset spectrograms and procedural notes - Clear ownership: assets borrowed, procedurals owned - Optional cache eviction under DEMO_ENABLE_CACHE_EVICTION flag 2. AudioEngine (src/audio/audio_engine.{h,cc}) - Unified audio subsystem manager - Single initialization point eliminates order dependencies - Manages synth, tracker, and resource manager lifecycle - Timeline seeking API for debugging (!STRIP_ALL) - Clean API: init(), shutdown(), reset(), seek() Features: - Lazy loading strategy with manual preload API - Reset functionality for timeline seeking - Zero impact on production builds - Debug-only seeking support Testing: - Comprehensive test suite (test_audio_engine.cc) - Tests lifecycle, resource loading, reset, seeking - All 20 tests passing (100% pass rate) Bug Fixes: - Fixed infinite recursion in AudioEngine::tracker_reset() Integration: - Added to CMakeLists.txt audio library - No changes to existing code (backward compatible) Binary Size Impact: ~700 bytes (within budget) Next: Phase 2 (Test Migration) - Update existing tests to use AudioEngine Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/audio/audio_engine.h')
-rw-r--r--src/audio/audio_engine.h67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/audio/audio_engine.h b/src/audio/audio_engine.h
new file mode 100644
index 0000000..ef3c163
--- /dev/null
+++ b/src/audio/audio_engine.h
@@ -0,0 +1,67 @@
+// This file is part of the 64k demo project.
+// AudioEngine: Unified audio subsystem manager.
+// Eliminates initialization order dependencies between synth and tracker.
+
+#pragma once
+
+#include "audio/spectrogram_resource_manager.h"
+#include "audio/synth.h"
+#include "audio/tracker.h"
+
+// Unified audio engine managing synth, tracker, and resources
+class AudioEngine {
+ public:
+ // Lifecycle
+ void init();
+ void shutdown();
+ void reset(); // Clear all state (for seeking/rewinding)
+
+ // Music data loading
+ void load_music_data(const TrackerScore* score,
+ const NoteParams* samples,
+ const AssetId* sample_assets,
+ uint32_t sample_count);
+
+ // Update loop
+ void update(float music_time);
+
+#if !defined(STRIP_ALL)
+ // Timeline seeking (debugging only)
+ void seek(float target_time);
+ float get_time() const { return current_time_; }
+#endif /* !defined(STRIP_ALL) */
+
+ // Synth interface (delegates to internal synth)
+ void render(float* output_buffer, int num_frames);
+ int get_active_voice_count() const;
+
+ // Tracker interface
+ void tracker_reset();
+
+ // Resource access
+ SpectrogramResourceManager* get_resource_manager() { return &resource_mgr_; }
+
+ private:
+ // Trigger a sample (loads resource if needed, registers with synth)
+ void trigger_sample(int sample_id, float volume, float pan);
+
+ // Get or create synth ID for a sample
+ int get_or_register_synth_id(int sample_id);
+
+#if !defined(STRIP_ALL)
+ // Seeking support
+ void prewarm_for_time_range(float start_time, float end_time);
+ void update_silent(float music_time); // Update without triggering audio
+#endif
+
+ SpectrogramResourceManager resource_mgr_;
+
+ // NOTE: For now, synth and tracker are global C functions (not members)
+ // Future refactoring will convert them to member objects
+
+ // Mapping: sample_id → synth_id (lazy registration)
+ int sample_to_synth_id_[MAX_SPECTROGRAM_RESOURCES];
+
+ float current_time_ = 0.0f;
+ bool initialized_ = false;
+};