1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// 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 <assert.h>
#include <stdio.h>
#include <vector>
#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<Event> 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;
}
float get_realtime_peak() override {
// Test backend: return synthetic peak
return 0.5f;
}
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) */
}
|