summaryrefslogtreecommitdiff
path: root/src/tests/test_audio_backend.cc
blob: 6a748aa9d637021d71338539a55f7ca7a6c4db95 (plain)
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) */
}