2 * Copyright 2009 Maarten Lankhorst
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
27 #elif defined(HAVE_OPENAL_AL_H)
28 #include <OpenAL/al.h>
29 #include <OpenAL/alc.h>
37 #include "wine/library.h"
42 #include "mmdeviceapi.h"
45 #include "audioclient.h"
46 #include "endpointvolume.h"
47 #include "audiopolicy.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi
);
59 static CRITICAL_SECTION_DEBUG openal_crst_debug
=
62 { &openal_crst_debug
.ProcessLocksList
,
63 &openal_crst_debug
.ProcessLocksList
},
64 0, 0, { (DWORD_PTR
)(__FILE__
": openal_crst_debug") }
66 CRITICAL_SECTION openal_crst
= { &openal_crst_debug
, -1, 0, 0, 0, 0 };
68 static void *openal_handle
= RTLD_DEFAULT
;
70 #ifdef SONAME_LIBOPENAL
71 LPALCCREATECONTEXT palcCreateContext
= NULL
;
72 LPALCMAKECONTEXTCURRENT palcMakeContextCurrent
= NULL
;
73 LPALCPROCESSCONTEXT palcProcessContext
= NULL
;
74 LPALCSUSPENDCONTEXT palcSuspendContext
= NULL
;
75 LPALCDESTROYCONTEXT palcDestroyContext
= NULL
;
76 LPALCGETCURRENTCONTEXT palcGetCurrentContext
= NULL
;
77 LPALCGETCONTEXTSDEVICE palcGetContextsDevice
= NULL
;
78 LPALCOPENDEVICE palcOpenDevice
= NULL
;
79 LPALCCLOSEDEVICE palcCloseDevice
= NULL
;
80 LPALCGETERROR palcGetError
= NULL
;
81 LPALCISEXTENSIONPRESENT palcIsExtensionPresent
= NULL
;
82 LPALCGETPROCADDRESS palcGetProcAddress
= NULL
;
83 LPALCGETENUMVALUE palcGetEnumValue
= NULL
;
84 LPALCGETSTRING palcGetString
= NULL
;
85 LPALCGETINTEGERV palcGetIntegerv
= NULL
;
86 LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice
= NULL
;
87 LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice
= NULL
;
88 LPALCCAPTURESTART palcCaptureStart
= NULL
;
89 LPALCCAPTURESTOP palcCaptureStop
= NULL
;
90 LPALCCAPTURESAMPLES palcCaptureSamples
= NULL
;
91 LPALENABLE palEnable
= NULL
;
92 LPALDISABLE palDisable
= NULL
;
93 LPALISENABLED palIsEnabled
= NULL
;
94 LPALGETSTRING palGetString
= NULL
;
95 LPALGETBOOLEANV palGetBooleanv
= NULL
;
96 LPALGETINTEGERV palGetIntegerv
= NULL
;
97 LPALGETFLOATV palGetFloatv
= NULL
;
98 LPALGETDOUBLEV palGetDoublev
= NULL
;
99 LPALGETBOOLEAN palGetBoolean
= NULL
;
100 LPALGETINTEGER palGetInteger
= NULL
;
101 LPALGETFLOAT palGetFloat
= NULL
;
102 LPALGETDOUBLE palGetDouble
= NULL
;
103 LPALGETERROR palGetError
= NULL
;
104 LPALISEXTENSIONPRESENT palIsExtensionPresent
= NULL
;
105 LPALGETPROCADDRESS palGetProcAddress
= NULL
;
106 LPALGETENUMVALUE palGetEnumValue
= NULL
;
107 LPALLISTENERF palListenerf
= NULL
;
108 LPALLISTENER3F palListener3f
= NULL
;
109 LPALLISTENERFV palListenerfv
= NULL
;
110 LPALLISTENERI palListeneri
= NULL
;
111 LPALLISTENER3I palListener3i
= NULL
;
112 LPALLISTENERIV palListeneriv
= NULL
;
113 LPALGETLISTENERF palGetListenerf
= NULL
;
114 LPALGETLISTENER3F palGetListener3f
= NULL
;
115 LPALGETLISTENERFV palGetListenerfv
= NULL
;
116 LPALGETLISTENERI palGetListeneri
= NULL
;
117 LPALGETLISTENER3I palGetListener3i
= NULL
;
118 LPALGETLISTENERIV palGetListeneriv
= NULL
;
119 LPALGENSOURCES palGenSources
= NULL
;
120 LPALDELETESOURCES palDeleteSources
= NULL
;
121 LPALISSOURCE palIsSource
= NULL
;
122 LPALSOURCEF palSourcef
= NULL
;
123 LPALSOURCE3F palSource3f
= NULL
;
124 LPALSOURCEFV palSourcefv
= NULL
;
125 LPALSOURCEI palSourcei
= NULL
;
126 LPALSOURCE3I palSource3i
= NULL
;
127 LPALSOURCEIV palSourceiv
= NULL
;
128 LPALGETSOURCEF palGetSourcef
= NULL
;
129 LPALGETSOURCE3F palGetSource3f
= NULL
;
130 LPALGETSOURCEFV palGetSourcefv
= NULL
;
131 LPALGETSOURCEI palGetSourcei
= NULL
;
132 LPALGETSOURCE3I palGetSource3i
= NULL
;
133 LPALGETSOURCEIV palGetSourceiv
= NULL
;
134 LPALSOURCEPLAYV palSourcePlayv
= NULL
;
135 LPALSOURCESTOPV palSourceStopv
= NULL
;
136 LPALSOURCEREWINDV palSourceRewindv
= NULL
;
137 LPALSOURCEPAUSEV palSourcePausev
= NULL
;
138 LPALSOURCEPLAY palSourcePlay
= NULL
;
139 LPALSOURCESTOP palSourceStop
= NULL
;
140 LPALSOURCEREWIND palSourceRewind
= NULL
;
141 LPALSOURCEPAUSE palSourcePause
= NULL
;
142 LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers
= NULL
;
143 LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers
= NULL
;
144 LPALGENBUFFERS palGenBuffers
= NULL
;
145 LPALDELETEBUFFERS palDeleteBuffers
= NULL
;
146 LPALISBUFFER palIsBuffer
= NULL
;
147 LPALBUFFERF palBufferf
= NULL
;
148 LPALBUFFER3F palBuffer3f
= NULL
;
149 LPALBUFFERFV palBufferfv
= NULL
;
150 LPALBUFFERI palBufferi
= NULL
;
151 LPALBUFFER3I palBuffer3i
= NULL
;
152 LPALBUFFERIV palBufferiv
= NULL
;
153 LPALGETBUFFERF palGetBufferf
= NULL
;
154 LPALGETBUFFER3F palGetBuffer3f
= NULL
;
155 LPALGETBUFFERFV palGetBufferfv
= NULL
;
156 LPALGETBUFFERI palGetBufferi
= NULL
;
157 LPALGETBUFFER3I palGetBuffer3i
= NULL
;
158 LPALGETBUFFERIV palGetBufferiv
= NULL
;
159 LPALBUFFERDATA palBufferData
= NULL
;
160 LPALDOPPLERFACTOR palDopplerFactor
= NULL
;
161 LPALDOPPLERVELOCITY palDopplerVelocity
= NULL
;
162 LPALDISTANCEMODEL palDistanceModel
= NULL
;
163 LPALSPEEDOFSOUND palSpeedOfSound
= NULL
;
166 typeof(alcGetCurrentContext
) *get_context
;
167 typeof(alcMakeContextCurrent
) *set_context
;
169 static void load_libopenal(void)
173 #ifdef SONAME_LIBOPENAL
175 openal_handle
= wine_dlopen(SONAME_LIBOPENAL
, RTLD_NOW
, error
, sizeof(error
));
177 ERR("Couldn't load " SONAME_LIBOPENAL
": %s\n", error
);
178 #define LOAD_FUNCPTR(f) \
179 if((p##f = wine_dlsym(openal_handle, #f, NULL, 0)) == NULL) { \
180 ERR("Couldn't lookup %s in libopenal\n", #f); \
184 LOAD_FUNCPTR(alcCreateContext
);
185 LOAD_FUNCPTR(alcMakeContextCurrent
);
186 LOAD_FUNCPTR(alcProcessContext
);
187 LOAD_FUNCPTR(alcSuspendContext
);
188 LOAD_FUNCPTR(alcDestroyContext
);
189 LOAD_FUNCPTR(alcGetCurrentContext
);
190 LOAD_FUNCPTR(alcGetContextsDevice
);
191 LOAD_FUNCPTR(alcOpenDevice
);
192 LOAD_FUNCPTR(alcCloseDevice
);
193 LOAD_FUNCPTR(alcGetError
);
194 LOAD_FUNCPTR(alcIsExtensionPresent
);
195 LOAD_FUNCPTR(alcGetProcAddress
);
196 LOAD_FUNCPTR(alcGetEnumValue
);
197 LOAD_FUNCPTR(alcGetString
);
198 LOAD_FUNCPTR(alcGetIntegerv
);
199 LOAD_FUNCPTR(alcCaptureOpenDevice
);
200 LOAD_FUNCPTR(alcCaptureCloseDevice
);
201 LOAD_FUNCPTR(alcCaptureStart
);
202 LOAD_FUNCPTR(alcCaptureStop
);
203 LOAD_FUNCPTR(alcCaptureSamples
);
204 LOAD_FUNCPTR(alEnable
);
205 LOAD_FUNCPTR(alDisable
);
206 LOAD_FUNCPTR(alIsEnabled
);
207 LOAD_FUNCPTR(alGetString
);
208 LOAD_FUNCPTR(alGetBooleanv
);
209 LOAD_FUNCPTR(alGetIntegerv
);
210 LOAD_FUNCPTR(alGetFloatv
);
211 LOAD_FUNCPTR(alGetDoublev
);
212 LOAD_FUNCPTR(alGetBoolean
);
213 LOAD_FUNCPTR(alGetInteger
);
214 LOAD_FUNCPTR(alGetFloat
);
215 LOAD_FUNCPTR(alGetDouble
);
216 LOAD_FUNCPTR(alGetError
);
217 LOAD_FUNCPTR(alIsExtensionPresent
);
218 LOAD_FUNCPTR(alGetProcAddress
);
219 LOAD_FUNCPTR(alGetEnumValue
);
220 LOAD_FUNCPTR(alListenerf
);
221 LOAD_FUNCPTR(alListener3f
);
222 LOAD_FUNCPTR(alListenerfv
);
223 LOAD_FUNCPTR(alListeneri
);
224 LOAD_FUNCPTR(alListener3i
);
225 LOAD_FUNCPTR(alListeneriv
);
226 LOAD_FUNCPTR(alGetListenerf
);
227 LOAD_FUNCPTR(alGetListener3f
);
228 LOAD_FUNCPTR(alGetListenerfv
);
229 LOAD_FUNCPTR(alGetListeneri
);
230 LOAD_FUNCPTR(alGetListener3i
);
231 LOAD_FUNCPTR(alGetListeneriv
);
232 LOAD_FUNCPTR(alGenSources
);
233 LOAD_FUNCPTR(alDeleteSources
);
234 LOAD_FUNCPTR(alIsSource
);
235 LOAD_FUNCPTR(alSourcef
);
236 LOAD_FUNCPTR(alSource3f
);
237 LOAD_FUNCPTR(alSourcefv
);
238 LOAD_FUNCPTR(alSourcei
);
239 LOAD_FUNCPTR(alSource3i
);
240 LOAD_FUNCPTR(alSourceiv
);
241 LOAD_FUNCPTR(alGetSourcef
);
242 LOAD_FUNCPTR(alGetSource3f
);
243 LOAD_FUNCPTR(alGetSourcefv
);
244 LOAD_FUNCPTR(alGetSourcei
);
245 LOAD_FUNCPTR(alGetSource3i
);
246 LOAD_FUNCPTR(alGetSourceiv
);
247 LOAD_FUNCPTR(alSourcePlayv
);
248 LOAD_FUNCPTR(alSourceStopv
);
249 LOAD_FUNCPTR(alSourceRewindv
);
250 LOAD_FUNCPTR(alSourcePausev
);
251 LOAD_FUNCPTR(alSourcePlay
);
252 LOAD_FUNCPTR(alSourceStop
);
253 LOAD_FUNCPTR(alSourceRewind
);
254 LOAD_FUNCPTR(alSourcePause
);
255 LOAD_FUNCPTR(alSourceQueueBuffers
);
256 LOAD_FUNCPTR(alSourceUnqueueBuffers
);
257 LOAD_FUNCPTR(alGenBuffers
);
258 LOAD_FUNCPTR(alDeleteBuffers
);
259 LOAD_FUNCPTR(alIsBuffer
);
260 LOAD_FUNCPTR(alBufferf
);
261 LOAD_FUNCPTR(alBuffer3f
);
262 LOAD_FUNCPTR(alBufferfv
);
263 LOAD_FUNCPTR(alBufferi
);
264 LOAD_FUNCPTR(alBuffer3i
);
265 LOAD_FUNCPTR(alBufferiv
);
266 LOAD_FUNCPTR(alGetBufferf
);
267 LOAD_FUNCPTR(alGetBuffer3f
);
268 LOAD_FUNCPTR(alGetBufferfv
);
269 LOAD_FUNCPTR(alGetBufferi
);
270 LOAD_FUNCPTR(alGetBuffer3i
);
271 LOAD_FUNCPTR(alGetBufferiv
);
272 LOAD_FUNCPTR(alBufferData
);
273 LOAD_FUNCPTR(alDopplerFactor
);
274 LOAD_FUNCPTR(alDopplerVelocity
);
275 LOAD_FUNCPTR(alDistanceModel
);
276 LOAD_FUNCPTR(alSpeedOfSound
);
282 WARN("Unloading openal\n");
283 if (openal_handle
!= RTLD_DEFAULT
)
284 wine_dlclose(openal_handle
, NULL
, 0);
285 openal_handle
= NULL
;
291 local_contexts
= palcIsExtensionPresent(NULL
, "ALC_EXT_thread_local_context");
294 set_context
= palcGetProcAddress(NULL
, "alcSetThreadContext");
295 get_context
= palcGetProcAddress(NULL
, "alcGetThreadContext");
296 if (!set_context
|| !get_context
)
298 ERR("TLS advertised but functions not found, disabling thread local context\n");
304 set_context
= palcMakeContextCurrent
;
305 get_context
= palcGetCurrentContext
;
310 #endif /*HAVE_OPENAL*/
312 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
314 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
318 case DLL_PROCESS_ATTACH
:
319 DisableThreadLibraryCalls(hinstDLL
);
322 #endif /*HAVE_OPENAL*/
324 case DLL_PROCESS_DETACH
:
332 HRESULT WINAPI
DllCanUnloadNow(void)
337 typedef HRESULT (*FnCreateInstance
)(REFIID riid
, LPVOID
*ppobj
);
340 const IClassFactoryVtbl
*lpVtbl
;
342 FnCreateInstance pfnCreateInstance
;
345 static HRESULT WINAPI
346 MMCF_QueryInterface(LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppobj
)
348 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
349 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
352 if (IsEqualIID(riid
, &IID_IUnknown
) ||
353 IsEqualIID(riid
, &IID_IClassFactory
))
356 IUnknown_AddRef(iface
);
360 return E_NOINTERFACE
;
363 static ULONG WINAPI
MMCF_AddRef(LPCLASSFACTORY iface
)
368 static ULONG WINAPI
MMCF_Release(LPCLASSFACTORY iface
)
370 /* static class, won't be freed */
374 static HRESULT WINAPI
MMCF_CreateInstance(
375 LPCLASSFACTORY iface
,
380 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
381 TRACE("(%p, %p, %s, %p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
384 return CLASS_E_NOAGGREGATION
;
387 WARN("invalid parameter\n");
391 return This
->pfnCreateInstance(riid
, ppobj
);
394 static HRESULT WINAPI
MMCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
396 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
397 FIXME("(%p, %d) stub!\n", This
, dolock
);
401 static const IClassFactoryVtbl MMCF_Vtbl
= {
409 static IClassFactoryImpl MMDEVAPI_CF
[] = {
410 { &MMCF_Vtbl
, &CLSID_MMDeviceEnumerator
, (FnCreateInstance
)MMDevEnum_Create
}
413 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
416 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
419 WARN("invalid parameter\n");
425 if (!IsEqualIID(riid
, &IID_IClassFactory
) &&
426 !IsEqualIID(riid
, &IID_IUnknown
)) {
427 WARN("no interface for %s\n", debugstr_guid(riid
));
428 return E_NOINTERFACE
;
431 for (i
= 0; i
< sizeof(MMDEVAPI_CF
)/sizeof(MMDEVAPI_CF
[0]); ++i
)
433 if (IsEqualGUID(rclsid
, MMDEVAPI_CF
[i
].rclsid
)) {
434 IUnknown_AddRef((IClassFactory
*) &MMDEVAPI_CF
[i
]);
435 *ppv
= &MMDEVAPI_CF
[i
];
441 WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid
),
442 debugstr_guid(riid
), ppv
);
443 return CLASS_E_CLASSNOTAVAILABLE
;