summaryrefslogtreecommitdiff
path: root/src/tests/audio/test_synth.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/audio/test_synth.cc')
-rw-r--r--src/tests/audio/test_synth.cc113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/tests/audio/test_synth.cc b/src/tests/audio/test_synth.cc
new file mode 100644
index 0000000..12cbc54
--- /dev/null
+++ b/src/tests/audio/test_synth.cc
@@ -0,0 +1,113 @@
+// This file is part of the 64k demo project.
+// It tests the core functionality of the audio synthesis engine.
+// Verifies voice triggering, registration, and rendering state.
+
+#include "audio/synth.h"
+#include <assert.h>
+#include <cmath>
+#include <stdio.h>
+
+void test_registration() {
+ synth_init();
+ float data[DCT_SIZE * 2] = {0};
+ Spectrogram spec = {data, data, 2};
+
+ int id = synth_register_spectrogram(&spec);
+ assert(id >= 0);
+ assert(synth_get_active_voice_count() == 0);
+
+ synth_unregister_spectrogram(id);
+ // Re-register to check slot reuse
+ int id2 = synth_register_spectrogram(&spec);
+ assert(id2 == id); // Should reuse the slot 0
+}
+
+void test_trigger() {
+ synth_init();
+ float data[DCT_SIZE * 2] = {0};
+ Spectrogram spec = {data, data, 2};
+ int id = synth_register_spectrogram(&spec);
+
+ synth_trigger_voice(id, 1.0f, 0.0f);
+ assert(synth_get_active_voice_count() == 1);
+}
+
+void test_render() {
+ synth_init();
+ float data[DCT_SIZE * 2] = {0};
+ // Put some signal in (DC component)
+ data[0] = 100.0f;
+
+ Spectrogram spec = {data, data, 2};
+ int id = synth_register_spectrogram(&spec);
+
+ synth_trigger_voice(id, 1.0f, 0.0f);
+
+ float output[1024] = {0};
+ synth_render(output, 256);
+
+ // Verify output is not all zero (IDCT of DC component should be constant)
+ bool non_zero = false;
+ for (int i = 0; i < 256; ++i) {
+ if (std::abs(output[i]) > 1e-6f)
+ non_zero = true;
+ }
+ assert(non_zero);
+
+ // Test render with no voices
+ synth_init(); // Reset
+ float output2[1024] = {0};
+ synth_render(output2, 256);
+ for (int i = 0; i < 256; ++i)
+ assert(output2[i] == 0.0f);
+}
+
+void test_update() {
+ synth_init();
+ float data[DCT_SIZE * 2] = {0};
+ Spectrogram spec = {data, data, 2};
+ int id = synth_register_spectrogram(&spec);
+
+ float* back_buf = synth_begin_update(id);
+ assert(back_buf != nullptr);
+ // Write something
+ back_buf[0] = 50.0f;
+ synth_commit_update(id);
+
+ // Test invalid ID
+ assert(synth_begin_update(-1) == nullptr);
+ synth_commit_update(-1); // Should not crash
+}
+
+void test_exhaustion() {
+ synth_init();
+ float data[DCT_SIZE * 2] = {0};
+ Spectrogram spec = {data, data, 2};
+
+ for (int i = 0; i < MAX_SPECTROGRAMS; ++i) {
+ int id = synth_register_spectrogram(&spec);
+ assert(id >= 0);
+ }
+ // Next one should fail
+ int id = synth_register_spectrogram(&spec);
+ assert(id == -1);
+}
+
+void test_peak() {
+ // Already called render in test_render.
+ // Just call the getter.
+ float peak = synth_get_output_peak();
+ assert(peak >= 0.0f);
+}
+
+int main() {
+ printf("Running SynthEngine tests...\n");
+ test_registration();
+ test_trigger();
+ test_render();
+ test_update();
+ test_exhaustion();
+ test_peak();
+ printf("SynthEngine tests PASSED\n");
+ return 0;
+} \ No newline at end of file