// 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; };