summaryrefslogtreecommitdiff
path: root/src/audio/spectrogram_resource_manager.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/spectrogram_resource_manager.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/spectrogram_resource_manager.h')
-rw-r--r--src/audio/spectrogram_resource_manager.h74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/audio/spectrogram_resource_manager.h b/src/audio/spectrogram_resource_manager.h
new file mode 100644
index 0000000..97196d1
--- /dev/null
+++ b/src/audio/spectrogram_resource_manager.h
@@ -0,0 +1,74 @@
+// This file is part of the 64k demo project.
+// SpectrogramResourceManager: Centralized resource loading and ownership.
+// Handles both asset spectrograms and procedurally generated notes.
+
+#pragma once
+
+#include "audio/gen.h"
+#include "audio/synth.h"
+#include "generated/assets.h"
+#include "util/asset_manager.h"
+#include <cstdint>
+
+// Maximum number of unique spectrogram resources
+constexpr int MAX_SPECTROGRAM_RESOURCES = 256;
+
+class SpectrogramResourceManager {
+ public:
+ // Lifecycle
+ void init();
+ void shutdown(); // Frees all owned memory
+ void reset(); // Clear state but keep registrations
+
+ // Metadata registration (no loading yet, just bookkeeping)
+ void register_asset(int sample_id, AssetId asset_id);
+ void register_procedural(int sample_id, const NoteParams& params);
+
+ // Lazy loading API (loads on first access if not cached)
+ const Spectrogram* get_or_load(int sample_id);
+
+ // Explicit pre-warming (for timeline seeking)
+ void preload(int sample_id);
+ void preload_range(int start_id, int end_id);
+
+ // Query API
+ const Spectrogram* get_spectrogram(int sample_id) const;
+ bool is_loaded(int sample_id) const;
+ int get_loaded_count() const;
+
+#if defined(DEMO_ENABLE_CACHE_EVICTION)
+ // Cache management (optional, compile-time flag)
+ void release(int sample_id);
+ void release_all();
+ void try_evict_lru(float current_time);
+#endif /* defined(DEMO_ENABLE_CACHE_EVICTION) */
+
+ private:
+ enum ResourceState {
+ UNREGISTERED = 0, // No metadata registered
+ REGISTERED, // Metadata registered, not loaded yet
+ LOADED, // Fully loaded and ready
+#if defined(DEMO_ENABLE_CACHE_EVICTION)
+ EVICTED // Was loaded, now evicted
+#endif
+ };
+
+ struct Resource {
+ Spectrogram spec;
+ float* owned_data; // nullptr if asset (not owned), allocated if procedural
+ AssetId asset_id; // ASSET_LAST_ID if procedural
+ NoteParams proc_params;
+ ResourceState state;
+
+#if defined(DEMO_ENABLE_CACHE_EVICTION)
+ float last_access_time;
+#endif
+ };
+
+ // Load implementation
+ void load_asset(Resource* resource);
+ void load_procedural(Resource* resource);
+
+ Resource resources_[MAX_SPECTROGRAM_RESOURCES];
+ int loaded_count_ = 0;
+};