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
));
178 ERR("Couldn't load " SONAME_LIBOPENAL
": %s\n", error
);
182 #define LOAD_FUNCPTR(f) \
183 if((p##f = wine_dlsym(openal_handle, #f, NULL, 0)) == NULL) { \
184 ERR("Couldn't lookup %s in libopenal\n", #f); \
188 LOAD_FUNCPTR(alcCreateContext
);
189 LOAD_FUNCPTR(alcMakeContextCurrent
);
190 LOAD_FUNCPTR(alcProcessContext
);
191 LOAD_FUNCPTR(alcSuspendContext
);
192 LOAD_FUNCPTR(alcDestroyContext
);
193 LOAD_FUNCPTR(alcGetCurrentContext
);
194 LOAD_FUNCPTR(alcGetContextsDevice
);
195 LOAD_FUNCPTR(alcOpenDevice
);
196 LOAD_FUNCPTR(alcCloseDevice
);
197 LOAD_FUNCPTR(alcGetError
);
198 LOAD_FUNCPTR(alcIsExtensionPresent
);
199 LOAD_FUNCPTR(alcGetProcAddress
);
200 LOAD_FUNCPTR(alcGetEnumValue
);
201 LOAD_FUNCPTR(alcGetString
);
202 LOAD_FUNCPTR(alcGetIntegerv
);
203 LOAD_FUNCPTR(alcCaptureOpenDevice
);
204 LOAD_FUNCPTR(alcCaptureCloseDevice
);
205 LOAD_FUNCPTR(alcCaptureStart
);
206 LOAD_FUNCPTR(alcCaptureStop
);
207 LOAD_FUNCPTR(alcCaptureSamples
);
208 LOAD_FUNCPTR(alEnable
);
209 LOAD_FUNCPTR(alDisable
);
210 LOAD_FUNCPTR(alIsEnabled
);
211 LOAD_FUNCPTR(alGetString
);
212 LOAD_FUNCPTR(alGetBooleanv
);
213 LOAD_FUNCPTR(alGetIntegerv
);
214 LOAD_FUNCPTR(alGetFloatv
);
215 LOAD_FUNCPTR(alGetDoublev
);
216 LOAD_FUNCPTR(alGetBoolean
);
217 LOAD_FUNCPTR(alGetInteger
);
218 LOAD_FUNCPTR(alGetFloat
);
219 LOAD_FUNCPTR(alGetDouble
);
220 LOAD_FUNCPTR(alGetError
);
221 LOAD_FUNCPTR(alIsExtensionPresent
);
222 LOAD_FUNCPTR(alGetProcAddress
);
223 LOAD_FUNCPTR(alGetEnumValue
);
224 LOAD_FUNCPTR(alListenerf
);
225 LOAD_FUNCPTR(alListener3f
);
226 LOAD_FUNCPTR(alListenerfv
);
227 LOAD_FUNCPTR(alListeneri
);
228 LOAD_FUNCPTR(alListener3i
);
229 LOAD_FUNCPTR(alListeneriv
);
230 LOAD_FUNCPTR(alGetListenerf
);
231 LOAD_FUNCPTR(alGetListener3f
);
232 LOAD_FUNCPTR(alGetListenerfv
);
233 LOAD_FUNCPTR(alGetListeneri
);
234 LOAD_FUNCPTR(alGetListener3i
);
235 LOAD_FUNCPTR(alGetListeneriv
);
236 LOAD_FUNCPTR(alGenSources
);
237 LOAD_FUNCPTR(alDeleteSources
);
238 LOAD_FUNCPTR(alIsSource
);
239 LOAD_FUNCPTR(alSourcef
);
240 LOAD_FUNCPTR(alSource3f
);
241 LOAD_FUNCPTR(alSourcefv
);
242 LOAD_FUNCPTR(alSourcei
);
243 LOAD_FUNCPTR(alSource3i
);
244 LOAD_FUNCPTR(alSourceiv
);
245 LOAD_FUNCPTR(alGetSourcef
);
246 LOAD_FUNCPTR(alGetSource3f
);
247 LOAD_FUNCPTR(alGetSourcefv
);
248 LOAD_FUNCPTR(alGetSourcei
);
249 LOAD_FUNCPTR(alGetSource3i
);
250 LOAD_FUNCPTR(alGetSourceiv
);
251 LOAD_FUNCPTR(alSourcePlayv
);
252 LOAD_FUNCPTR(alSourceStopv
);
253 LOAD_FUNCPTR(alSourceRewindv
);
254 LOAD_FUNCPTR(alSourcePausev
);
255 LOAD_FUNCPTR(alSourcePlay
);
256 LOAD_FUNCPTR(alSourceStop
);
257 LOAD_FUNCPTR(alSourceRewind
);
258 LOAD_FUNCPTR(alSourcePause
);
259 LOAD_FUNCPTR(alSourceQueueBuffers
);
260 LOAD_FUNCPTR(alSourceUnqueueBuffers
);
261 LOAD_FUNCPTR(alGenBuffers
);
262 LOAD_FUNCPTR(alDeleteBuffers
);
263 LOAD_FUNCPTR(alIsBuffer
);
264 LOAD_FUNCPTR(alBufferf
);
265 LOAD_FUNCPTR(alBuffer3f
);
266 LOAD_FUNCPTR(alBufferfv
);
267 LOAD_FUNCPTR(alBufferi
);
268 LOAD_FUNCPTR(alBuffer3i
);
269 LOAD_FUNCPTR(alBufferiv
);
270 LOAD_FUNCPTR(alGetBufferf
);
271 LOAD_FUNCPTR(alGetBuffer3f
);
272 LOAD_FUNCPTR(alGetBufferfv
);
273 LOAD_FUNCPTR(alGetBufferi
);
274 LOAD_FUNCPTR(alGetBuffer3i
);
275 LOAD_FUNCPTR(alGetBufferiv
);
276 LOAD_FUNCPTR(alBufferData
);
277 LOAD_FUNCPTR(alDopplerFactor
);
278 LOAD_FUNCPTR(alDopplerVelocity
);
279 LOAD_FUNCPTR(alDistanceModel
);
280 LOAD_FUNCPTR(alSpeedOfSound
);
286 WARN("Unloading openal\n");
287 if (openal_handle
!= RTLD_DEFAULT
)
288 wine_dlclose(openal_handle
, NULL
, 0);
289 openal_handle
= NULL
;
295 local_contexts
= palcIsExtensionPresent(NULL
, "ALC_EXT_thread_local_context");
298 set_context
= palcGetProcAddress(NULL
, "alcSetThreadContext");
299 get_context
= palcGetProcAddress(NULL
, "alcGetThreadContext");
300 if (!set_context
|| !get_context
)
302 ERR("TLS advertised but functions not found, disabling thread local context\n");
308 set_context
= palcMakeContextCurrent
;
309 get_context
= palcGetCurrentContext
;
314 #endif /*HAVE_OPENAL*/
316 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
318 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
322 case DLL_PROCESS_ATTACH
:
323 DisableThreadLibraryCalls(hinstDLL
);
326 #endif /*HAVE_OPENAL*/
328 case DLL_PROCESS_DETACH
:
336 HRESULT WINAPI
DllCanUnloadNow(void)
341 typedef HRESULT (*FnCreateInstance
)(REFIID riid
, LPVOID
*ppobj
);
344 const IClassFactoryVtbl
*lpVtbl
;
346 FnCreateInstance pfnCreateInstance
;
349 static HRESULT WINAPI
350 MMCF_QueryInterface(LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppobj
)
352 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
353 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
356 if (IsEqualIID(riid
, &IID_IUnknown
) ||
357 IsEqualIID(riid
, &IID_IClassFactory
))
360 IUnknown_AddRef(iface
);
364 return E_NOINTERFACE
;
367 static ULONG WINAPI
MMCF_AddRef(LPCLASSFACTORY iface
)
372 static ULONG WINAPI
MMCF_Release(LPCLASSFACTORY iface
)
374 /* static class, won't be freed */
378 static HRESULT WINAPI
MMCF_CreateInstance(
379 LPCLASSFACTORY iface
,
384 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
385 TRACE("(%p, %p, %s, %p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
388 return CLASS_E_NOAGGREGATION
;
391 WARN("invalid parameter\n");
395 return This
->pfnCreateInstance(riid
, ppobj
);
398 static HRESULT WINAPI
MMCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
400 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
401 FIXME("(%p, %d) stub!\n", This
, dolock
);
405 static const IClassFactoryVtbl MMCF_Vtbl
= {
413 static IClassFactoryImpl MMDEVAPI_CF
[] = {
414 { &MMCF_Vtbl
, &CLSID_MMDeviceEnumerator
, (FnCreateInstance
)MMDevEnum_Create
}
417 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
420 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
423 WARN("invalid parameter\n");
429 if (!IsEqualIID(riid
, &IID_IClassFactory
) &&
430 !IsEqualIID(riid
, &IID_IUnknown
)) {
431 WARN("no interface for %s\n", debugstr_guid(riid
));
432 return E_NOINTERFACE
;
435 for (i
= 0; i
< sizeof(MMDEVAPI_CF
)/sizeof(MMDEVAPI_CF
[0]); ++i
)
437 if (IsEqualGUID(rclsid
, MMDEVAPI_CF
[i
].rclsid
)) {
438 IUnknown_AddRef((IClassFactory
*) &MMDEVAPI_CF
[i
]);
439 *ppv
= &MMDEVAPI_CF
[i
];
445 WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid
),
446 debugstr_guid(riid
), ppv
);
447 return CLASS_E_CLASSNOTAVAILABLE
;