yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
audio_backend.h
Go to the documentation of this file.
1// audio_backend.h - Audio Backend Abstraction Layer
2// Provides interface for swapping audio implementations (SDL2, SDL3, other
3// libs)
4
5#ifndef YAZE_APP_EMU_AUDIO_AUDIO_BACKEND_H
6#define YAZE_APP_EMU_AUDIO_AUDIO_BACKEND_H
7
9
10#include <cstdint>
11#include <memory>
12#include <string>
13#include <vector>
14
15namespace yaze {
16namespace emu {
17namespace audio {
18
19// Audio sample format
20enum class SampleFormat {
21 INT16, // 16-bit signed PCM
22 FLOAT32 // 32-bit float
23};
24
25// Audio configuration
27 int sample_rate = 48000;
28 int channels = 2; // Stereo
29 int buffer_frames = 1024;
31};
32
33// Audio backend status
35 bool is_playing = false;
36 uint32_t queued_bytes = 0;
37 uint32_t queued_frames = 0;
38 bool has_underrun = false;
39};
40
48 public:
49 virtual ~IAudioBackend() = default;
50
51 // Initialization
52 virtual bool Initialize(const AudioConfig& config) = 0;
53 virtual void Shutdown() = 0;
54
55 // Playback control
56 virtual void Play() = 0;
57 virtual void Pause() = 0;
58 virtual void Stop() = 0;
59 virtual void Clear() = 0;
60
61 // Audio data
62 virtual bool QueueSamples(const int16_t* samples, int num_samples) = 0;
63 virtual bool QueueSamples(const float* samples, int num_samples) = 0;
64 virtual bool QueueSamplesNative(const int16_t* samples,
65 int frames_per_channel, int channels,
66 int native_rate) {
67 return false;
68 }
69
70 // Status queries
71 virtual AudioStatus GetStatus() const = 0;
72 virtual bool IsInitialized() const = 0;
73 virtual AudioConfig GetConfig() const = 0;
74
75 // Volume control (0.0 to 1.0)
76 virtual void SetVolume(float volume) = 0;
77 virtual float GetVolume() const = 0;
78
79 // Optional: enable/disable SDL_AudioStream-based resampling
80 virtual void SetAudioStreamResampling(bool enable, int native_rate,
81 int channels) {}
82 virtual bool SupportsAudioStream() const { return false; }
83
84 // Check if audio stream resampling is currently active
85 // Returns true if resampling from native rate to device rate is enabled
86 virtual bool IsAudioStreamEnabled() const { return false; }
87
88 // Get backend name for debugging
89 virtual std::string GetBackendName() const = 0;
90};
91
96 public:
97 SDL2AudioBackend() = default;
98 ~SDL2AudioBackend() override;
99
100 bool Initialize(const AudioConfig& config) override;
101 void Shutdown() override;
102
103 void Play() override;
104 void Pause() override;
105 void Stop() override;
106 void Clear() override;
107
108 bool QueueSamples(const int16_t* samples, int num_samples) override;
109 bool QueueSamples(const float* samples, int num_samples) override;
110 bool QueueSamplesNative(const int16_t* samples, int frames_per_channel,
111 int channels, int native_rate) override;
112
113 AudioStatus GetStatus() const override;
114 bool IsInitialized() const override;
115 AudioConfig GetConfig() const override;
116
117 void SetVolume(float volume) override;
118 float GetVolume() const override;
119
120 void SetAudioStreamResampling(bool enable, int native_rate,
121 int channels) override;
122 bool SupportsAudioStream() const override { return true; }
123 bool IsAudioStreamEnabled() const override;
124
125 std::string GetBackendName() const override { return "SDL2"; }
126
127 private:
128 uint32_t device_id_ = 0;
130 bool initialized_ = false;
131 float volume_ = 1.0f;
132 int call_count_ = 0; // Track calls per backend instance
133#ifdef YAZE_USE_SDL3
134 SDL_AudioFormat device_format_ = SDL_AUDIO_S16;
135#else
136 SDL_AudioFormat device_format_ = AUDIO_S16;
137#endif
139 int device_freq_ = 48000;
142 SDL_AudioStream* audio_stream_ = nullptr;
143 std::vector<int16_t> stream_buffer_;
144};
145
153 public:
154 NullAudioBackend() = default;
155 ~NullAudioBackend() override = default;
156
157 bool Initialize(const AudioConfig& config) override;
158 void Shutdown() override;
159
160 void Play() override;
161 void Pause() override;
162 void Stop() override;
163 void Clear() override;
164
165 bool QueueSamples(const int16_t* samples, int num_samples) override;
166 bool QueueSamples(const float* samples, int num_samples) override;
167 bool QueueSamplesNative(const int16_t* samples, int frames_per_channel,
168 int channels, int native_rate) override;
169
170 AudioStatus GetStatus() const override;
171 bool IsInitialized() const override;
172 AudioConfig GetConfig() const override;
173
174 void SetVolume(float volume) override;
175 float GetVolume() const override;
176
177 void SetAudioStreamResampling(bool enable, int native_rate,
178 int channels) override;
179 bool SupportsAudioStream() const override { return true; }
180 bool IsAudioStreamEnabled() const override;
181
182 std::string GetBackendName() const override { return "Null"; }
183
184 // Test helpers - access queued sample counts for verification
185 uint64_t GetTotalQueuedSamples() const { return total_queued_samples_; }
186 uint64_t GetTotalQueuedFrames() const { return total_queued_frames_; }
187 void ResetCounters();
188
189 private:
191 bool initialized_ = false;
192 bool playing_ = false;
193 float volume_ = 1.0f;
197
198 // Counters for testing
202};
203
208 public:
209 enum class BackendType {
210 SDL2,
211 SDL3, // Future
212 WASM, // WebAudio for Emscripten
213 NULL_BACKEND // For testing/headless
214 };
215
216 static std::unique_ptr<IAudioBackend> Create(BackendType type);
217};
218
219} // namespace audio
220} // namespace emu
221} // namespace yaze
222
223#endif // YAZE_APP_EMU_AUDIO_AUDIO_BACKEND_H
Factory for creating audio backends.
static std::unique_ptr< IAudioBackend > Create(BackendType type)
Abstract audio backend interface.
virtual std::string GetBackendName() const =0
virtual bool QueueSamples(const float *samples, int num_samples)=0
virtual void SetVolume(float volume)=0
virtual bool Initialize(const AudioConfig &config)=0
virtual bool QueueSamplesNative(const int16_t *samples, int frames_per_channel, int channels, int native_rate)
virtual void SetAudioStreamResampling(bool enable, int native_rate, int channels)
virtual AudioStatus GetStatus() const =0
virtual bool SupportsAudioStream() const
virtual bool IsInitialized() const =0
virtual ~IAudioBackend()=default
virtual AudioConfig GetConfig() const =0
virtual float GetVolume() const =0
virtual bool IsAudioStreamEnabled() const
virtual bool QueueSamples(const int16_t *samples, int num_samples)=0
Null audio backend for testing/headless operation.
bool QueueSamplesNative(const int16_t *samples, int frames_per_channel, int channels, int native_rate) override
AudioStatus GetStatus() const override
void SetAudioStreamResampling(bool enable, int native_rate, int channels) override
bool IsAudioStreamEnabled() const override
AudioConfig GetConfig() const override
std::string GetBackendName() const override
bool IsInitialized() const override
bool SupportsAudioStream() const override
~NullAudioBackend() override=default
bool QueueSamples(const int16_t *samples, int num_samples) override
bool Initialize(const AudioConfig &config) override
void SetVolume(float volume) override
SDL2 audio backend implementation.
AudioConfig GetConfig() const override
bool SupportsAudioStream() const override
bool IsAudioStreamEnabled() const override
void SetVolume(float volume) override
bool Initialize(const AudioConfig &config) override
bool IsInitialized() const override
std::vector< int16_t > stream_buffer_
std::string GetBackendName() const override
AudioStatus GetStatus() const override
bool QueueSamplesNative(const int16_t *samples, int frames_per_channel, int channels, int native_rate) override
bool QueueSamples(const int16_t *samples, int num_samples) override
void SetAudioStreamResampling(bool enable, int native_rate, int channels) override
SDL2/SDL3 compatibility layer.