yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
wasm_audio.h
Go to the documentation of this file.
1// wasm_audio.h - WebAudio Backend Implementation for WASM/Emscripten
2// Provides audio output for SNES emulator using browser's WebAudio API
3
4#ifndef YAZE_APP_EMU_PLATFORM_WASM_WASM_AUDIO_H
5#define YAZE_APP_EMU_PLATFORM_WASM_WASM_AUDIO_H
6
7#ifdef __EMSCRIPTEN__
8
9#include <atomic>
10#include <cstdint>
11#include <memory>
12#include <mutex>
13#include <queue>
14#include <string>
15#include <vector>
16
18
19namespace yaze {
20namespace emu {
21namespace audio {
22
37class WasmAudioBackend : public IAudioBackend {
38 public:
39 WasmAudioBackend();
40 ~WasmAudioBackend() override;
41
42 // Initialization
43 bool Initialize(const AudioConfig& config) override;
44 void Shutdown() override;
45
46 // Playback control
47 void Play() override;
48 void Pause() override;
49 void Stop() override;
50 void Clear() override;
51
52 // Audio data submission
53 bool QueueSamples(const int16_t* samples, int num_samples) override;
54 bool QueueSamples(const float* samples, int num_samples) override;
55 bool QueueSamplesNative(const int16_t* samples, int frames_per_channel,
56 int channels, int native_rate) override;
57
58 // Status queries
59 AudioStatus GetStatus() const override;
60 bool IsInitialized() const override;
61 AudioConfig GetConfig() const override;
62
63 // Volume control (0.0 to 1.0)
64 void SetVolume(float volume) override;
65 float GetVolume() const override;
66
67 // Audio stream resampling support
68 void SetAudioStreamResampling(bool enable, int native_rate,
69 int channels) override;
70 bool SupportsAudioStream() const override { return true; }
71
72 // Backend identification
73 std::string GetBackendName() const override { return "WebAudio"; }
74
75 // WASM-specific: Handle user interaction for autoplay policy
76 void HandleUserInteraction();
77
78 // WASM-specific: Check if audio context is suspended due to autoplay
79 bool IsContextSuspended() const;
80
81 private:
82 // Internal buffer management
83 struct AudioBuffer {
84 std::vector<float> samples;
85 int sample_count;
86 int channels;
87 };
88
89 // Helper functions
90 void ProcessAudioQueue();
91 bool ConvertToFloat32(const int16_t* input, float* output, int num_samples);
92 void ApplyVolumeToBuffer(float* buffer, int num_samples);
93
94 // JavaScript audio context handle (opaque pointer)
95 void* audio_context_ = nullptr;
96
97 // JavaScript script processor node handle
98 void* script_processor_ = nullptr;
99
100 // Configuration
101 AudioConfig config_;
102
103 // State management
104 std::atomic<bool> initialized_{false};
105 std::atomic<bool> playing_{false};
106 std::atomic<bool> context_suspended_{true};
107 std::atomic<float> volume_{1.0f};
108
109 // Sample queue for buffering
110 std::mutex queue_mutex_;
111 std::queue<AudioBuffer> sample_queue_;
112 std::atomic<size_t> queued_samples_{0};
113
114 // Resampling configuration
115 bool resampling_enabled_ = false;
116 int native_rate_ = 32000; // SNES native rate
117 int native_channels_ = 2;
118
119 // Working buffers
120 std::vector<float> conversion_buffer_;
121 std::vector<float> resampling_buffer_;
122
123 // Performance metrics
124 mutable std::atomic<bool> has_underrun_{false};
125 std::atomic<size_t> total_samples_played_{0};
126
127 // Buffer size configuration
128 static constexpr int kDefaultBufferSize = 2048;
129 static constexpr int kMaxQueuedBuffers = 16;
130 static constexpr float kInt16ToFloat = 1.0f / 32768.0f;
131};
132
133} // namespace audio
134} // namespace emu
135} // namespace yaze
136
137#endif // __EMSCRIPTEN__
138
139#endif // YAZE_APP_EMU_PLATFORM_WASM_WASM_AUDIO_H