VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudioStubs.cpp@ 95433

Last change on this file since 95433 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.0 KB
Line 
1/* $Id: DrvHostAudioPulseAudioStubs.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * Stubs for libpulse.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
23#include <iprt/assert.h>
24#include <iprt/errcore.h>
25#include <iprt/ldr.h>
26#include <VBox/log.h>
27#include <iprt/once.h>
28
29#include <pulse/pulseaudio.h>
30
31#include "DrvHostAudioPulseAudioStubs.h"
32
33
34/*********************************************************************************************************************************
35* Defined Constants And Macros *
36*********************************************************************************************************************************/
37#define VBOX_PULSE_LIB "libpulse.so.0"
38
39#define PROXY_STUB(function, rettype, signature, shortsig) \
40 static rettype (*g_pfn_ ## function) signature; \
41 \
42 extern "C" rettype VBox_##function signature; \
43 rettype VBox_##function signature \
44 { \
45 return g_pfn_ ## function shortsig; \
46 }
47
48#define PROXY_STUB_VOID(function, signature, shortsig) \
49 static void (*g_pfn_ ## function) signature; \
50 \
51 extern "C" void VBox_##function signature; \
52 void VBox_##function signature \
53 { \
54 g_pfn_ ## function shortsig; \
55 }
56
57PROXY_STUB (pa_bytes_per_second, size_t,
58 (const pa_sample_spec *spec),
59 (spec))
60PROXY_STUB (pa_bytes_to_usec, pa_usec_t,
61 (uint64_t l, const pa_sample_spec *spec),
62 (l, spec))
63PROXY_STUB (pa_channel_map_init_auto, pa_channel_map*,
64 (pa_channel_map *m, unsigned channels, pa_channel_map_def_t def),
65 (m, channels, def))
66
67PROXY_STUB (pa_context_connect, int,
68 (pa_context *c, const char *server, pa_context_flags_t flags,
69 const pa_spawn_api *api),
70 (c, server, flags, api))
71PROXY_STUB_VOID(pa_context_disconnect,
72 (pa_context *c),
73 (c))
74PROXY_STUB (pa_context_get_server_info, pa_operation*,
75 (pa_context *c, pa_server_info_cb_t cb, void *userdata),
76 (c, cb, userdata))
77PROXY_STUB (pa_context_get_sink_info_by_name, pa_operation*,
78 (pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata),
79 (c, name, cb, userdata))
80PROXY_STUB (pa_context_get_sink_info_list, pa_operation *,
81 (pa_context *c, pa_sink_info_cb_t cb, void *userdata),
82 (c, cb, userdata))
83PROXY_STUB (pa_context_get_source_info_by_name, pa_operation*,
84 (pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata),
85 (c, name, cb, userdata))
86PROXY_STUB (pa_context_get_source_info_list, pa_operation *,
87 (pa_context *c, pa_source_info_cb_t cb, void *userdata),
88 (c, cb, userdata))
89PROXY_STUB (pa_context_get_state, pa_context_state_t,
90 (pa_context *c),
91 (c))
92PROXY_STUB_VOID(pa_context_unref,
93 (pa_context *c),
94 (c))
95PROXY_STUB (pa_context_errno, int,
96 (pa_context *c),
97 (c))
98PROXY_STUB (pa_context_new, pa_context*,
99 (pa_mainloop_api *mainloop, const char *name),
100 (mainloop, name))
101PROXY_STUB_VOID(pa_context_set_state_callback,
102 (pa_context *c, pa_context_notify_cb_t cb, void *userdata),
103 (c, cb, userdata))
104
105PROXY_STUB (pa_frame_size, size_t,
106 (const pa_sample_spec *spec),
107 (spec))
108PROXY_STUB (pa_get_library_version, const char *, (void), ())
109PROXY_STUB_VOID(pa_operation_unref,
110 (pa_operation *o),
111 (o))
112PROXY_STUB (pa_operation_get_state, pa_operation_state_t,
113 (pa_operation *o),
114 (o))
115PROXY_STUB_VOID(pa_operation_cancel,
116 (pa_operation *o),
117 (o))
118
119PROXY_STUB (pa_rtclock_now, pa_usec_t,
120 (void),
121 ())
122PROXY_STUB (pa_sample_format_to_string, const char*,
123 (pa_sample_format_t f),
124 (f))
125PROXY_STUB (pa_sample_spec_valid, int,
126 (const pa_sample_spec *spec),
127 (spec))
128PROXY_STUB (pa_strerror, const char*,
129 (int error),
130 (error))
131
132#if PA_PROTOCOL_VERSION >= 16
133PROXY_STUB (pa_stream_connect_playback, int,
134 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
135 pa_stream_flags_t flags, const pa_cvolume *volume, pa_stream *sync_stream),
136 (s, dev, attr, flags, volume, sync_stream))
137#else
138PROXY_STUB (pa_stream_connect_playback, int,
139 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
140 pa_stream_flags_t flags, pa_cvolume *volume, pa_stream *sync_stream),
141 (s, dev, attr, flags, volume, sync_stream))
142#endif
143PROXY_STUB (pa_stream_connect_record, int,
144 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
145 pa_stream_flags_t flags),
146 (s, dev, attr, flags))
147PROXY_STUB (pa_stream_disconnect, int,
148 (pa_stream *s),
149 (s))
150PROXY_STUB (pa_stream_get_sample_spec, const pa_sample_spec*,
151 (pa_stream *s),
152 (s))
153PROXY_STUB_VOID(pa_stream_set_latency_update_callback,
154 (pa_stream *p, pa_stream_notify_cb_t cb, void *userdata),
155 (p, cb, userdata))
156PROXY_STUB (pa_stream_write, int,
157 (pa_stream *p, const void *data, size_t bytes, pa_free_cb_t free_cb,
158 int64_t offset, pa_seek_mode_t seek),
159 (p, data, bytes, free_cb, offset, seek))
160PROXY_STUB_VOID(pa_stream_unref,
161 (pa_stream *s),
162 (s))
163PROXY_STUB (pa_stream_get_state, pa_stream_state_t,
164 (pa_stream *p),
165 (p))
166PROXY_STUB (pa_stream_get_latency, int,
167 (pa_stream *s, pa_usec_t *r_usec, int *negative),
168 (s, r_usec, negative))
169PROXY_STUB (pa_stream_get_timing_info, pa_timing_info*,
170 (pa_stream *s),
171 (s))
172PROXY_STUB (pa_stream_readable_size, size_t,
173 (pa_stream *p),
174 (p))
175PROXY_STUB (pa_stream_set_buffer_attr, pa_operation *,
176 (pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata),
177 (s, attr, cb, userdata))
178PROXY_STUB_VOID(pa_stream_set_state_callback,
179 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
180 (s, cb, userdata))
181PROXY_STUB_VOID(pa_stream_set_underflow_callback,
182 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
183 (s, cb, userdata))
184PROXY_STUB_VOID(pa_stream_set_overflow_callback,
185 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
186 (s, cb, userdata))
187PROXY_STUB_VOID(pa_stream_set_write_callback,
188 (pa_stream *s, pa_stream_request_cb_t cb, void *userdata),
189 (s, cb, userdata))
190PROXY_STUB (pa_stream_flush, pa_operation*,
191 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
192 (s, cb, userdata))
193PROXY_STUB (pa_stream_drain, pa_operation*,
194 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
195 (s, cb, userdata))
196PROXY_STUB (pa_stream_trigger, pa_operation*,
197 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
198 (s, cb, userdata))
199PROXY_STUB (pa_stream_new, pa_stream*,
200 (pa_context *c, const char *name, const pa_sample_spec *ss,
201 const pa_channel_map *map),
202 (c, name, ss, map))
203PROXY_STUB (pa_stream_get_buffer_attr, const pa_buffer_attr*,
204 (pa_stream *s),
205 (s))
206PROXY_STUB (pa_stream_peek, int,
207 (pa_stream *p, const void **data, size_t *bytes),
208 (p, data, bytes))
209PROXY_STUB (pa_stream_cork, pa_operation*,
210 (pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata),
211 (s, b, cb, userdata))
212PROXY_STUB (pa_stream_drop, int,
213 (pa_stream *p),
214 (p))
215PROXY_STUB (pa_stream_writable_size, size_t,
216 (pa_stream *p),
217 (p))
218
219PROXY_STUB_VOID(pa_threaded_mainloop_stop,
220 (pa_threaded_mainloop *m),
221 (m))
222PROXY_STUB (pa_threaded_mainloop_get_api, pa_mainloop_api*,
223 (pa_threaded_mainloop *m),
224 (m))
225PROXY_STUB_VOID(pa_threaded_mainloop_free,
226 (pa_threaded_mainloop* m),
227 (m))
228PROXY_STUB_VOID(pa_threaded_mainloop_signal,
229 (pa_threaded_mainloop *m, int wait_for_accept),
230 (m, wait_for_accept))
231PROXY_STUB_VOID(pa_threaded_mainloop_unlock,
232 (pa_threaded_mainloop *m),
233 (m))
234PROXY_STUB (pa_threaded_mainloop_new, pa_threaded_mainloop *,
235 (void),
236 ())
237PROXY_STUB_VOID(pa_threaded_mainloop_wait,
238 (pa_threaded_mainloop *m),
239 (m))
240PROXY_STUB (pa_threaded_mainloop_start, int,
241 (pa_threaded_mainloop *m),
242 (m))
243PROXY_STUB_VOID(pa_threaded_mainloop_lock,
244 (pa_threaded_mainloop *m),
245 (m))
246
247PROXY_STUB (pa_usec_to_bytes, size_t,
248 (pa_usec_t t, const pa_sample_spec *spec),
249 (t, spec))
250
251#define FUNC_ENTRY(function) { #function , (void (**)(void)) & g_pfn_ ## function }
252static struct
253{
254 const char *pszName;
255 void (**pfn)(void);
256} const g_aImportedFunctions[] =
257{
258 FUNC_ENTRY(pa_bytes_per_second),
259 FUNC_ENTRY(pa_bytes_to_usec),
260 FUNC_ENTRY(pa_channel_map_init_auto),
261
262 FUNC_ENTRY(pa_context_connect),
263 FUNC_ENTRY(pa_context_disconnect),
264 FUNC_ENTRY(pa_context_get_server_info),
265 FUNC_ENTRY(pa_context_get_sink_info_by_name),
266 FUNC_ENTRY(pa_context_get_sink_info_list),
267 FUNC_ENTRY(pa_context_get_source_info_by_name),
268 FUNC_ENTRY(pa_context_get_source_info_list),
269 FUNC_ENTRY(pa_context_get_state),
270 FUNC_ENTRY(pa_context_unref),
271 FUNC_ENTRY(pa_context_errno),
272 FUNC_ENTRY(pa_context_new),
273 FUNC_ENTRY(pa_context_set_state_callback),
274
275 FUNC_ENTRY(pa_frame_size),
276 FUNC_ENTRY(pa_get_library_version),
277 FUNC_ENTRY(pa_operation_unref),
278 FUNC_ENTRY(pa_operation_get_state),
279 FUNC_ENTRY(pa_operation_cancel),
280 FUNC_ENTRY(pa_rtclock_now),
281 FUNC_ENTRY(pa_sample_format_to_string),
282 FUNC_ENTRY(pa_sample_spec_valid),
283 FUNC_ENTRY(pa_strerror),
284
285 FUNC_ENTRY(pa_stream_connect_playback),
286 FUNC_ENTRY(pa_stream_connect_record),
287 FUNC_ENTRY(pa_stream_disconnect),
288 FUNC_ENTRY(pa_stream_get_sample_spec),
289 FUNC_ENTRY(pa_stream_set_latency_update_callback),
290 FUNC_ENTRY(pa_stream_write),
291 FUNC_ENTRY(pa_stream_unref),
292 FUNC_ENTRY(pa_stream_get_state),
293 FUNC_ENTRY(pa_stream_get_latency),
294 FUNC_ENTRY(pa_stream_get_timing_info),
295 FUNC_ENTRY(pa_stream_readable_size),
296 FUNC_ENTRY(pa_stream_set_buffer_attr),
297 FUNC_ENTRY(pa_stream_set_state_callback),
298 FUNC_ENTRY(pa_stream_set_underflow_callback),
299 FUNC_ENTRY(pa_stream_set_overflow_callback),
300 FUNC_ENTRY(pa_stream_set_write_callback),
301 FUNC_ENTRY(pa_stream_flush),
302 FUNC_ENTRY(pa_stream_drain),
303 FUNC_ENTRY(pa_stream_trigger),
304 FUNC_ENTRY(pa_stream_new),
305 FUNC_ENTRY(pa_stream_get_buffer_attr),
306 FUNC_ENTRY(pa_stream_peek),
307 FUNC_ENTRY(pa_stream_cork),
308 FUNC_ENTRY(pa_stream_drop),
309 FUNC_ENTRY(pa_stream_writable_size),
310
311 FUNC_ENTRY(pa_threaded_mainloop_stop),
312 FUNC_ENTRY(pa_threaded_mainloop_get_api),
313 FUNC_ENTRY(pa_threaded_mainloop_free),
314 FUNC_ENTRY(pa_threaded_mainloop_signal),
315 FUNC_ENTRY(pa_threaded_mainloop_unlock),
316 FUNC_ENTRY(pa_threaded_mainloop_new),
317 FUNC_ENTRY(pa_threaded_mainloop_wait),
318 FUNC_ENTRY(pa_threaded_mainloop_start),
319 FUNC_ENTRY(pa_threaded_mainloop_lock),
320
321 FUNC_ENTRY(pa_usec_to_bytes)
322};
323#undef FUNC_ENTRY
324
325/** Init once. */
326static RTONCE g_PulseAudioLibInitOnce = RTONCE_INITIALIZER;
327
328/** @callback_method_impl{FNRTONCE} */
329static DECLCALLBACK(int32_t) drvHostAudioPulseLibInitOnce(void *pvUser)
330{
331 RT_NOREF(pvUser);
332 LogFlowFunc(("\n"));
333
334 RTLDRMOD hMod = NIL_RTLDRMOD;
335 int rc = RTLdrLoadSystemEx(VBOX_PULSE_LIB, RTLDRLOAD_FLAGS_NO_UNLOAD, &hMod);
336 if (RT_SUCCESS(rc))
337 {
338 for (unsigned i = 0; i < RT_ELEMENTS(g_aImportedFunctions); i++)
339 {
340 rc = RTLdrGetSymbol(hMod, g_aImportedFunctions[i].pszName, (void **)g_aImportedFunctions[i].pfn);
341 if (RT_FAILURE(rc))
342 {
343 LogRelFunc(("Failed to resolve function #%u: '%s' (%Rrc)\n", i, g_aImportedFunctions[i].pszName, rc));
344 break;
345 }
346 }
347
348 RTLdrClose(hMod);
349 }
350 else
351 LogRelFunc(("Failed to load library %s: %Rrc\n", VBOX_PULSE_LIB, rc));
352 return rc;
353}
354
355/**
356 * Try to dynamically load the PulseAudio libraries.
357 *
358 * @returns VBox status code.
359 */
360int audioLoadPulseLib(void)
361{
362 LogFlowFunc(("\n"));
363 return RTOnce(&g_PulseAudioLibInitOnce, drvHostAudioPulseLibInitOnce, NULL);
364}
365
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette