diff options
Diffstat (limited to 'src/tests/test_silent_backend.cc')
| -rw-r--r-- | src/tests/test_silent_backend.cc | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/src/tests/test_silent_backend.cc b/src/tests/test_silent_backend.cc new file mode 100644 index 0000000..8daacf7 --- /dev/null +++ b/src/tests/test_silent_backend.cc @@ -0,0 +1,211 @@ +// This file is part of the 64k demo project. +// It tests the SilentBackend for audio testing without hardware. +// Verifies audio.cc functionality using silent backend. + +#include "audio/audio.h" +#include "audio/audio_engine.h" +#include "audio/backend/silent_backend.h" +#include "audio/synth.h" +#include <assert.h> +#include <stdio.h> + +#if !defined(STRIP_ALL) + +// Test: SilentBackend initialization and lifecycle +void test_silent_backend_lifecycle() { + SilentBackend backend; + + assert(!backend.is_initialized()); + assert(!backend.is_started()); + + backend.init(); + assert(backend.is_initialized()); + assert(!backend.is_started()); + + backend.start(); + assert(backend.is_initialized()); + assert(backend.is_started()); + + backend.shutdown(); + assert(!backend.is_initialized()); + assert(!backend.is_started()); + + printf("SilentBackend lifecycle test PASSED\n"); +} + +// Test: Audio system with SilentBackend +void test_audio_with_silent_backend() { + SilentBackend backend; + audio_set_backend(&backend); + + audio_init(); + assert(backend.is_initialized()); + + audio_start(); + assert(backend.is_started()); + + audio_shutdown(); + assert(!backend.is_initialized()); + + printf("Audio with SilentBackend test PASSED\n"); +} + +// Test: Peak control in SilentBackend +void test_silent_backend_peak() { + SilentBackend backend; + audio_set_backend(&backend); + + audio_init(); + + // Default peak should be 0 + assert(backend.get_realtime_peak() == 0.0f); + assert(audio_get_realtime_peak() == 0.0f); + + // Set test peak + backend.set_peak(0.75f); + assert(backend.get_realtime_peak() == 0.75f); + assert(audio_get_realtime_peak() == 0.75f); + + // Reset + backend.set_peak(0.0f); + assert(backend.get_realtime_peak() == 0.0f); + + audio_shutdown(); + + printf("SilentBackend peak control test PASSED\n"); +} + +// Test: Frame and voice tracking +void test_silent_backend_tracking() { + SilentBackend backend; + audio_set_backend(&backend); + + AudioEngine engine; + engine.init(); + + // Initial state + assert(backend.get_frames_rendered() == 0); + assert(backend.get_voice_trigger_count() == 0); + + // 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.0f); + assert(backend.get_voice_trigger_count() == 1); + + // Render audio (calls on_frames_rendered) + audio_render_ahead(0.0f, 0.1f); // Render ~0.1 seconds + assert(backend.get_frames_rendered() > 0); + + // Reset stats + backend.reset_stats(); + assert(backend.get_frames_rendered() == 0); + assert(backend.get_voice_trigger_count() == 0); + + engine.shutdown(); + audio_shutdown(); + + printf("SilentBackend tracking test PASSED\n"); +} + +// Test: Playback time with SilentBackend +void test_audio_playback_time() { + SilentBackend backend; + audio_set_backend(&backend); + + AudioEngine engine; + engine.init(); + audio_start(); + + // Initial playback time should be 0 + float t0 = audio_get_playback_time(); + assert(t0 == 0.0f); + + // Render some audio + audio_render_ahead(0.5f, 0.1f); // Advance music time to 0.5s + + // Playback time should advance based on frames rendered + // Note: audio_get_playback_time() tracks cumulative frames consumed + float t1 = audio_get_playback_time(); + assert(t1 >= 0.0f); // Should have advanced + + // Render more + audio_render_ahead(1.0f, 0.5f); + float t2 = audio_get_playback_time(); + assert(t2 >= t1); // Should continue advancing + + engine.shutdown(); + audio_shutdown(); + + printf("Audio playback time test PASSED\n"); +} + +// Test: Buffer management with partial writes +void test_audio_buffer_partial_writes() { + SilentBackend backend; + audio_set_backend(&backend); + + AudioEngine engine; + engine.init(); + audio_start(); + + // Fill buffer multiple times to test wraparound + // Note: With SilentBackend, frames_rendered won't increase because + // there's no audio callback consuming from the ring buffer + for (int i = 0; i < 10; ++i) { + audio_render_ahead((float)i * 0.1f, 0.1f); + } + + // Buffer should have handled multiple writes correctly (no crash) + // We can't check frames_rendered with SilentBackend since there's + // no audio callback to consume from the ring buffer + audio_update(); // Should not crash + + engine.shutdown(); + audio_shutdown(); + + printf("Audio buffer partial writes test PASSED\n"); +} + +// Test: audio_update() with SilentBackend +void test_audio_update() { + SilentBackend backend; + audio_set_backend(&backend); + + AudioEngine engine; + engine.init(); + audio_start(); + + // audio_update() should be callable without crashing + audio_update(); + audio_update(); + audio_update(); + + engine.shutdown(); + audio_shutdown(); + + printf("Audio update test PASSED\n"); +} + +#endif /* !defined(STRIP_ALL) */ + +int main() { +#if !defined(STRIP_ALL) + printf("Running SilentBackend tests...\n"); + test_silent_backend_lifecycle(); + test_audio_with_silent_backend(); + test_silent_backend_peak(); + test_silent_backend_tracking(); + test_audio_playback_time(); + test_audio_buffer_partial_writes(); + test_audio_update(); + printf("All SilentBackend tests PASSED\n"); + return 0; +#else + printf("SilentBackend tests skipped (STRIP_ALL enabled)\n"); + return 0; +#endif /* !defined(STRIP_ALL) */ +} |
