// This file is part of the 64k demo project. // It tests the audio backend abstraction layer. // Verifies backend injection and event hooks work correctly. #include "audio/audio.h" #include "audio/audio_backend.h" #include "audio/synth.h" #include #include #include #if !defined(STRIP_ALL) // Simple test backend that records events class TestBackend : public AudioBackend { public: struct Event { float timestamp; int spectrogram_id; float volume; float pan; }; std::vector events; bool init_called = false; bool start_called = false; bool shutdown_called = false; void init() override { init_called = true; } void start() override { start_called = true; } void shutdown() override { shutdown_called = true; } void on_voice_triggered(float timestamp, int spectrogram_id, float volume, float pan) override { events.push_back({timestamp, spectrogram_id, volume, pan}); } }; void test_backend_injection() { TestBackend backend; // Inject test backend before audio_init audio_set_backend(&backend); audio_init(); assert(backend.init_called); audio_start(); assert(backend.start_called); audio_shutdown(); assert(backend.shutdown_called); printf("Backend injection test PASSED\n"); } void test_event_recording() { TestBackend backend; audio_set_backend(&backend); synth_init(); // Create a dummy spectrogram float data[DCT_SIZE * 2] = {0}; Spectrogram spec = {data, data, 2}; int id = synth_register_spectrogram(&spec); // Trigger a voice synth_trigger_voice(id, 0.8f, -0.5f); // Render some frames to advance time float output[1024] = {0}; synth_render(output, 256); // ~0.008 sec at 32kHz // Verify event was recorded assert(backend.events.size() == 1); assert(backend.events[0].spectrogram_id == id); assert(backend.events[0].volume == 0.8f); assert(backend.events[0].pan == -0.5f); assert(backend.events[0].timestamp == 0.0f); // Triggered before any render // Trigger another voice after rendering synth_trigger_voice(id, 1.0f, 0.0f); assert(backend.events.size() == 2); assert(backend.events[1].timestamp > 0.0f); // Should be > 0 now printf("Event recording test PASSED\n"); } void test_default_backend() { // Reset backend to nullptr to test default audio_set_backend(nullptr); // This should use MiniaudioBackend by default audio_init(); audio_start(); audio_shutdown(); printf("Default backend test PASSED\n"); } #endif /* !defined(STRIP_ALL) */ int main() { #if !defined(STRIP_ALL) printf("Running Audio Backend tests...\n"); test_backend_injection(); test_event_recording(); test_default_backend(); printf("All Audio Backend tests PASSED\n"); return 0; #else printf("Audio Backend tests skipped (STRIP_ALL enabled)\n"); return 0; #endif /* !defined(STRIP_ALL) */ }