9#include <audioclient.h>
11#include <mmdeviceapi.h>
28class MAYAFLUX_API WasapiBackend :
public IAudioBackend {
31 ~WasapiBackend()
override;
33 std::unique_ptr<AudioDevice> create_device_manager()
override;
35 std::unique_ptr<AudioStream> create_stream(
36 unsigned int output_device_id,
37 unsigned int input_device_id,
38 GlobalStreamInfo& stream_info,
39 void* user_data)
override;
41 [[nodiscard]] std::string get_version_string()
const override;
43 void cleanup()
override;
45 [[nodiscard]] IMMDeviceEnumerator* enumerator()
const {
return m_enumerator; }
48 IMMDeviceEnumerator* m_enumerator =
nullptr;
60class MAYAFLUX_API WasapiDevice :
public AudioDevice {
62 explicit WasapiDevice(IMMDeviceEnumerator* enumerator);
63 ~WasapiDevice()
override;
65 [[nodiscard]] std::vector<DeviceInfo> get_output_devices()
const override;
66 [[nodiscard]] std::vector<DeviceInfo> get_input_devices()
const override;
67 [[nodiscard]]
unsigned int get_default_output_device()
const override;
68 [[nodiscard]]
unsigned int get_default_input_device()
const override;
76 [[nodiscard]] IMMDevice* resolve_device(
unsigned int id, EDataFlow flow)
const;
79 struct EndpointEntry {
81 std::wstring endpoint_id;
84 void enumerate(IMMDeviceEnumerator* enumerator, EDataFlow flow,
85 std::vector<EndpointEntry>&
out,
unsigned int& default_idx);
87 IMMDeviceEnumerator* m_enumerator =
nullptr;
89 std::vector<EndpointEntry> m_outputs;
90 std::vector<EndpointEntry> m_inputs;
92 unsigned int m_default_output = 0;
93 unsigned int m_default_input = 0;
114class MAYAFLUX_API WasapiStream :
public AudioStream {
117 IMMDevice* output_device,
118 IMMDevice* input_device,
119 GlobalStreamInfo& stream_info,
122 ~WasapiStream()
override;
124 void open()
override;
125 void start()
override;
126 void stop()
override;
127 void pause()
override;
128 void resume()
override;
129 void close()
override;
131 [[nodiscard]]
bool is_running()
const override;
132 [[nodiscard]]
bool is_open()
const override;
134 void set_process_callback(
135 std::function<
int(
void*,
void*,
unsigned int)> cb)
override;
138 static DWORD WINAPI render_thread_proc(LPVOID param);
149 bool negotiate_format(
150 IAudioClient* client,
152 uint32_t sample_rate,
153 WAVEFORMATEX** out_fmt);
155 IMMDevice* m_output_device =
nullptr;
156 IMMDevice* m_input_device =
nullptr;
158 IAudioClient* m_render_client =
nullptr;
159 IAudioRenderClient* m_render_sink =
nullptr;
160 IAudioClient* m_capture_client =
nullptr;
161 IAudioCaptureClient* m_capture_src =
nullptr;
163 HANDLE m_render_event =
nullptr;
164 HANDLE m_capture_event =
nullptr;
165 HANDLE m_stop_event =
nullptr;
167 HANDLE m_render_thread =
nullptr;
169 uint32_t m_render_buffer_frames = 0;
170 uint32_t m_capture_buffer_frames = 0;
172 uint32_t m_negotiated_output_rate = 0;
173 uint32_t m_negotiated_input_rate = 0;
174 uint32_t m_negotiated_output_channels = 0;
175 uint32_t m_negotiated_input_channels = 0;
177 std::vector<float> m_render_staging;
178 std::vector<double> m_output_staging;
179 std::vector<float> m_capture_staging;
180 std::vector<double> m_input_staging;
181 std::atomic<bool> m_input_ready {
false };
183 std::vector<double> m_render_ring;
184 uint32_t m_ring_write_pos { 0 };
185 uint32_t m_ring_read_pos { 0 };
186 uint32_t m_ring_frames { 0 };
187 std::vector<double> m_capture_ring;
188 uint32_t m_cap_ring_write_pos { 0 };
189 uint32_t m_cap_ring_read_pos { 0 };
190 uint32_t m_cap_ring_frames { 0 };
192 GlobalStreamInfo& m_stream_info;
193 void* m_user_data =
nullptr;
195 std::function<int(
void*,
void*,
unsigned int)> m_process_callback;
197 std::atomic<bool> m_is_open {
false };
198 std::atomic<bool> m_is_running {
false };
199 std::atomic<bool> m_is_paused {
false };
std::vector< float > * out
void close(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological closing writing into dst.
void open(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological opening writing into dst.
void stop()
Stop all Portal::Graphics operations.