VirtualBox

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

Last change on this file since 88913 was 88478, checked in by vboxsync, 4 years ago

DrvHostAudioPulse: Implemented basic device enumeration. bugref:9890

  • 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 88478 2021-04-13 00:03:47Z vboxsync $ */
2/** @file
3 * Stubs for libpulse.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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/ldr.h>
25#include <VBox/log.h>
26#include <iprt/err.h>
27
28#include <pulse/pulseaudio.h>
29
30#include "DrvHostAudioPulseAudioStubs.h"
31
32
33/*********************************************************************************************************************************
34* Defined Constants And Macros *
35*********************************************************************************************************************************/
36#define VBOX_PULSE_LIB "libpulse.so.0"
37
38#define PROXY_STUB(function, rettype, signature, shortsig) \
39 static rettype (*g_pfn_ ## function) signature; \
40 \
41 extern "C" rettype VBox_##function signature; \
42 rettype VBox_##function signature \
43 { \
44 return g_pfn_ ## function shortsig; \
45 }
46
47#define PROXY_STUB_VOID(function, signature, shortsig) \
48 static void (*g_pfn_ ## function) signature; \
49 \
50 extern "C" void VBox_##function signature; \
51 void VBox_##function signature \
52 { \
53 g_pfn_ ## function shortsig; \
54 }
55
56PROXY_STUB (pa_bytes_per_second, size_t,
57 (const pa_sample_spec *spec),
58 (spec))
59PROXY_STUB (pa_bytes_to_usec, pa_usec_t,
60 (uint64_t l, const pa_sample_spec *spec),
61 (l, spec))
62PROXY_STUB (pa_channel_map_init_auto, pa_channel_map*,
63 (pa_channel_map *m, unsigned channels, pa_channel_map_def_t def),
64 (m, channels, def))
65
66PROXY_STUB (pa_context_connect, int,
67 (pa_context *c, const char *server, pa_context_flags_t flags,
68 const pa_spawn_api *api),
69 (c, server, flags, api))
70PROXY_STUB_VOID(pa_context_disconnect,
71 (pa_context *c),
72 (c))
73PROXY_STUB (pa_context_get_server_info, pa_operation*,
74 (pa_context *c, pa_server_info_cb_t cb, void *userdata),
75 (c, cb, userdata))
76PROXY_STUB (pa_context_get_sink_info_by_name, pa_operation*,
77 (pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata),
78 (c, name, cb, userdata))
79PROXY_STUB (pa_context_get_sink_info_list, pa_operation *,
80 (pa_context *c, pa_sink_info_cb_t cb, void *userdata),
81 (c, cb, userdata))
82PROXY_STUB (pa_context_get_source_info_by_name, pa_operation*,
83 (pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata),
84 (c, name, cb, userdata))
85PROXY_STUB (pa_context_get_source_info_list, pa_operation *,
86 (pa_context *c, pa_source_info_cb_t cb, void *userdata),
87 (c, cb, userdata))
88PROXY_STUB (pa_context_get_state, pa_context_state_t,
89 (pa_context *c),
90 (c))
91PROXY_STUB_VOID(pa_context_unref,
92 (pa_context *c),
93 (c))
94PROXY_STUB (pa_context_errno, int,
95 (pa_context *c),
96 (c))
97PROXY_STUB (pa_context_new, pa_context*,
98 (pa_mainloop_api *mainloop, const char *name),
99 (mainloop, name))
100PROXY_STUB_VOID(pa_context_set_state_callback,
101 (pa_context *c, pa_context_notify_cb_t cb, void *userdata),
102 (c, cb, userdata))
103
104PROXY_STUB (pa_frame_size, size_t,
105 (const pa_sample_spec *spec),
106 (spec))
107PROXY_STUB (pa_get_library_version, const char *, (void), ())
108PROXY_STUB_VOID(pa_operation_unref,
109 (pa_operation *o),
110 (o))
111PROXY_STUB (pa_operation_get_state, pa_operation_state_t,
112 (pa_operation *o),
113 (o))
114PROXY_STUB_VOID(pa_operation_cancel,
115 (pa_operation *o),
116 (o))
117
118PROXY_STUB (pa_rtclock_now, pa_usec_t,
119 (void),
120 ())
121PROXY_STUB (pa_sample_format_to_string, const char*,
122 (pa_sample_format_t f),
123 (f))
124PROXY_STUB (pa_sample_spec_valid, int,
125 (const pa_sample_spec *spec),
126 (spec))
127PROXY_STUB (pa_strerror, const char*,
128 (int error),
129 (error))
130
131#if PA_PROTOCOL_VERSION >= 16
132PROXY_STUB (pa_stream_connect_playback, int,
133 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
134 pa_stream_flags_t flags, const pa_cvolume *volume, pa_stream *sync_stream),
135 (s, dev, attr, flags, volume, sync_stream))
136#else
137PROXY_STUB (pa_stream_connect_playback, int,
138 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
139 pa_stream_flags_t flags, pa_cvolume *volume, pa_stream *sync_stream),
140 (s, dev, attr, flags, volume, sync_stream))
141#endif
142PROXY_STUB (pa_stream_connect_record, int,
143 (pa_stream *s, const char *dev, const pa_buffer_attr *attr,
144 pa_stream_flags_t flags),
145 (s, dev, attr, flags))
146PROXY_STUB (pa_stream_disconnect, int,
147 (pa_stream *s),
148 (s))
149PROXY_STUB (pa_stream_get_sample_spec, const pa_sample_spec*,
150 (pa_stream *s),
151 (s))
152PROXY_STUB_VOID(pa_stream_set_latency_update_callback,
153 (pa_stream *p, pa_stream_notify_cb_t cb, void *userdata),
154 (p, cb, userdata))
155PROXY_STUB (pa_stream_write, int,
156 (pa_stream *p, const void *data, size_t bytes, pa_free_cb_t free_cb,
157 int64_t offset, pa_seek_mode_t seek),
158 (p, data, bytes, free_cb, offset, seek))
159PROXY_STUB_VOID(pa_stream_unref,
160 (pa_stream *s),
161 (s))
162PROXY_STUB (pa_stream_get_state, pa_stream_state_t,
163 (pa_stream *p),
164 (p))
165PROXY_STUB (pa_stream_get_latency, int,
166 (pa_stream *s, pa_usec_t *r_usec, int *negative),
167 (s, r_usec, negative))
168PROXY_STUB (pa_stream_get_timing_info, pa_timing_info*,
169 (pa_stream *s),
170 (s))
171PROXY_STUB (pa_stream_readable_size, size_t,
172 (pa_stream *p),
173 (p))
174PROXY_STUB (pa_stream_set_buffer_attr, pa_operation *,
175 (pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata),
176 (s, attr, cb, userdata))
177PROXY_STUB_VOID(pa_stream_set_state_callback,
178 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
179 (s, cb, userdata))
180PROXY_STUB_VOID(pa_stream_set_underflow_callback,
181 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
182 (s, cb, userdata))
183PROXY_STUB_VOID(pa_stream_set_overflow_callback,
184 (pa_stream *s, pa_stream_notify_cb_t cb, void *userdata),
185 (s, cb, userdata))
186PROXY_STUB_VOID(pa_stream_set_write_callback,
187 (pa_stream *s, pa_stream_request_cb_t cb, void *userdata),
188 (s, cb, userdata))
189PROXY_STUB (pa_stream_flush, pa_operation*,
190 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
191 (s, cb, userdata))
192PROXY_STUB (pa_stream_drain, pa_operation*,
193 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
194 (s, cb, userdata))
195PROXY_STUB (pa_stream_trigger, pa_operation*,
196 (pa_stream *s, pa_stream_success_cb_t cb, void *userdata),
197 (s, cb, userdata))
198PROXY_STUB (pa_stream_new, pa_stream*,
199 (pa_context *c, const char *name, const pa_sample_spec *ss,
200 const pa_channel_map *map),
201 (c, name, ss, map))
202PROXY_STUB (pa_stream_get_buffer_attr, const pa_buffer_attr*,
203 (pa_stream *s),
204 (s))
205PROXY_STUB (pa_stream_peek, int,
206 (pa_stream *p, const void **data, size_t *bytes),
207 (p, data, bytes))
208PROXY_STUB (pa_stream_cork, pa_operation*,
209 (pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata),
210 (s, b, cb, userdata))
211PROXY_STUB (pa_stream_drop, int,
212 (pa_stream *p),
213 (p))
214PROXY_STUB (pa_stream_writable_size, size_t,
215 (pa_stream *p),
216 (p))
217
218PROXY_STUB_VOID(pa_threaded_mainloop_stop,
219 (pa_threaded_mainloop *m),
220 (m))
221PROXY_STUB (pa_threaded_mainloop_get_api, pa_mainloop_api*,
222 (pa_threaded_mainloop *m),
223 (m))
224PROXY_STUB_VOID(pa_threaded_mainloop_free,
225 (pa_threaded_mainloop* m),
226 (m))
227PROXY_STUB_VOID(pa_threaded_mainloop_signal,
228 (pa_threaded_mainloop *m, int wait_for_accept),
229 (m, wait_for_accept))
230PROXY_STUB_VOID(pa_threaded_mainloop_unlock,
231 (pa_threaded_mainloop *m),
232 (m))
233PROXY_STUB (pa_threaded_mainloop_new, pa_threaded_mainloop *,
234 (void),
235 ())
236PROXY_STUB_VOID(pa_threaded_mainloop_wait,
237 (pa_threaded_mainloop *m),
238 (m))
239PROXY_STUB (pa_threaded_mainloop_start, int,
240 (pa_threaded_mainloop *m),
241 (m))
242PROXY_STUB_VOID(pa_threaded_mainloop_lock,
243 (pa_threaded_mainloop *m),
244 (m))
245
246PROXY_STUB (pa_usec_to_bytes, size_t,
247 (pa_usec_t t, const pa_sample_spec *spec),
248 (t, spec))
249
250#define FUNC_ENTRY(function) { #function , (void (**)(void)) & g_pfn_ ## function }
251static struct
252{
253 const char *pszName;
254 void (**pfn)(void);
255} const g_aImportedFunctions[] =
256{
257 FUNC_ENTRY(pa_bytes_per_second),
258 FUNC_ENTRY(pa_bytes_to_usec),
259 FUNC_ENTRY(pa_channel_map_init_auto),
260
261 FUNC_ENTRY(pa_context_connect),
262 FUNC_ENTRY(pa_context_disconnect),
263 FUNC_ENTRY(pa_context_get_server_info),
264 FUNC_ENTRY(pa_context_get_sink_info_by_name),
265 FUNC_ENTRY(pa_context_get_sink_info_list),
266 FUNC_ENTRY(pa_context_get_source_info_by_name),
267 FUNC_ENTRY(pa_context_get_source_info_list),
268 FUNC_ENTRY(pa_context_get_state),
269 FUNC_ENTRY(pa_context_unref),
270 FUNC_ENTRY(pa_context_errno),
271 FUNC_ENTRY(pa_context_new),
272 FUNC_ENTRY(pa_context_set_state_callback),
273
274 FUNC_ENTRY(pa_frame_size),
275 FUNC_ENTRY(pa_get_library_version),
276 FUNC_ENTRY(pa_operation_unref),
277 FUNC_ENTRY(pa_operation_get_state),
278 FUNC_ENTRY(pa_operation_cancel),
279 FUNC_ENTRY(pa_rtclock_now),
280 FUNC_ENTRY(pa_sample_format_to_string),
281 FUNC_ENTRY(pa_sample_spec_valid),
282 FUNC_ENTRY(pa_strerror),
283
284 FUNC_ENTRY(pa_stream_connect_playback),
285 FUNC_ENTRY(pa_stream_connect_record),
286 FUNC_ENTRY(pa_stream_disconnect),
287 FUNC_ENTRY(pa_stream_get_sample_spec),
288 FUNC_ENTRY(pa_stream_set_latency_update_callback),
289 FUNC_ENTRY(pa_stream_write),
290 FUNC_ENTRY(pa_stream_unref),
291 FUNC_ENTRY(pa_stream_get_state),
292 FUNC_ENTRY(pa_stream_get_latency),
293 FUNC_ENTRY(pa_stream_get_timing_info),
294 FUNC_ENTRY(pa_stream_readable_size),
295 FUNC_ENTRY(pa_stream_set_buffer_attr),
296 FUNC_ENTRY(pa_stream_set_state_callback),
297 FUNC_ENTRY(pa_stream_set_underflow_callback),
298 FUNC_ENTRY(pa_stream_set_overflow_callback),
299 FUNC_ENTRY(pa_stream_set_write_callback),
300 FUNC_ENTRY(pa_stream_flush),
301 FUNC_ENTRY(pa_stream_drain),
302 FUNC_ENTRY(pa_stream_trigger),
303 FUNC_ENTRY(pa_stream_new),
304 FUNC_ENTRY(pa_stream_get_buffer_attr),
305 FUNC_ENTRY(pa_stream_peek),
306 FUNC_ENTRY(pa_stream_cork),
307 FUNC_ENTRY(pa_stream_drop),
308 FUNC_ENTRY(pa_stream_writable_size),
309
310 FUNC_ENTRY(pa_threaded_mainloop_stop),
311 FUNC_ENTRY(pa_threaded_mainloop_get_api),
312 FUNC_ENTRY(pa_threaded_mainloop_free),
313 FUNC_ENTRY(pa_threaded_mainloop_signal),
314 FUNC_ENTRY(pa_threaded_mainloop_unlock),
315 FUNC_ENTRY(pa_threaded_mainloop_new),
316 FUNC_ENTRY(pa_threaded_mainloop_wait),
317 FUNC_ENTRY(pa_threaded_mainloop_start),
318 FUNC_ENTRY(pa_threaded_mainloop_lock),
319
320 FUNC_ENTRY(pa_usec_to_bytes)
321};
322#undef FUNC_ENTRY
323
324/**
325 * Try to dynamically load the PulseAudio libraries. This function is not
326 * thread-safe, and should be called before attempting to use any of the
327 * PulseAudio functions.
328 *
329 * @returns iprt status code
330 */
331int audioLoadPulseLib(void)
332{
333 static volatile int g_rc = VERR_IPE_UNINITIALIZED_STATUS;
334 RTLDRMOD hLib;
335 int rc;
336
337 LogFlowFunc(("\n"));
338
339 /* If this is not VERR_IPE_UNINITIALIZED_STATUS then the function has
340 obviously been called twice, which is likely to be a bug. */
341 rc = g_rc;
342 AssertMsgReturn(rc == VERR_IPE_UNINITIALIZED_STATUS, ("g_rc=%Rrc\n", rc), rc);
343
344 rc = RTLdrLoadSystemEx(VBOX_PULSE_LIB, RTLDRLOAD_FLAGS_NO_UNLOAD, &hLib);
345 if (RT_SUCCESS(rc))
346 {
347 unsigned i;
348 for (i = 0; i < RT_ELEMENTS(g_aImportedFunctions); i++)
349 {
350 rc = RTLdrGetSymbol(hLib, g_aImportedFunctions[i].pszName, (void **)g_aImportedFunctions[i].pfn);
351 if (RT_FAILURE(rc))
352 {
353 LogRelFunc(("Failed to resolve function #%u: '%s' (%Rrc)\n", i, g_aImportedFunctions[i].pszName, rc));
354 break;
355 }
356 }
357 }
358 else
359 LogRelFunc(("Failed to load library %s: %Rrc\n", VBOX_PULSE_LIB, rc));
360 g_rc = rc;
361 return rc;
362}
363
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