summaryrefslogtreecommitdiff
path: root/src/tests/test_silent_backend.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/test_silent_backend.cc')
-rw-r--r--src/tests/test_silent_backend.cc211
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) */
+}