Avoid holding the device lock when it isn't needed
[dsound-openal.git] / dsound_private.h
blob1421d22de85e4f9f39e61f49770923fa57f97345
1 /* DirectSound
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 /* Linux does not support better timing than 10ms */
23 #define DS_TIME_RES 2 /* Resolution of multimedia timer */
24 #define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
25 /* Default refresh count, can be overridden */
26 #define FAKE_REFRESH_COUNT (1000/DS_TIME_DEL/2)
29 #ifdef __WINESRC__
31 #ifdef __APPLE__
32 #include <OpenAL/al.h>
33 #include <OpenAL/alc.h>
34 #else
35 #include <AL/al.h>
36 #include <AL/alc.h>
37 #endif
39 #define LONGFMT
40 #else
42 #include <al.h>
43 #include <alc.h>
45 #include <stdio.h>
47 extern int LogLevel;
49 #ifdef DEBUG_INFO
50 #define TRACE(fmt,args...) do { \
51 if(LogLevel >= 3) \
52 fprintf(stderr, "%04x:trace:dsound:%s " fmt, (UINT)GetCurrentThreadId(), __FUNCTION__, ##args); \
53 } while(0)
54 #define WARN(fmt,args...) do { \
55 if(LogLevel >= 2) \
56 fprintf(stderr, "%04x:warn:dsound:%s " fmt, (UINT)GetCurrentThreadId(), __FUNCTION__, ##args); \
57 } while(0)
58 #define FIXME(fmt,args...) do { \
59 if(LogLevel >= 1) \
60 fprintf(stderr, "%04x:fixme:dsound:%s " fmt, (UINT)GetCurrentThreadId(), __FUNCTION__, ##args); \
61 } while(0)
62 #define ERR(fmt,args...) do { \
63 if(LogLevel >= 0) \
64 fprintf(stderr, "%04x:err:dsound:%s " fmt, (UINT)GetCurrentThreadId(), __FUNCTION__, ##args); \
65 } while(0)
66 #else
67 #define TRACE(args...)
68 #define WARN(args...)
69 #define FIXME(args...)
70 #define ERR(args...)
71 #endif
73 const char *wine_dbg_sprintf( const char *format, ... );
74 const char *wine_dbgstr_wn( const WCHAR *str, int n );
75 const char *debugstr_guid( const GUID *id );
77 static inline const char *debugstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); }
79 #define LONGFMT "l"
80 #endif
83 #include "alext.h"
84 #include "eax.h"
86 /* Set to 1 to build a DLL that can be used in an app that uses OpenAL itself.
87 * Thread-local contexts are needed for true concurrency, however. Disallowing
88 * concurrency can avoid a save and restore of the context. */
89 #define ALLOW_CONCURRENT_AL 0
91 /* All openal functions */
92 extern int openal_loaded;
93 #ifdef SONAME_LIBOPENAL
94 extern LPALCCREATECONTEXT palcCreateContext;
95 extern LPALCMAKECONTEXTCURRENT palcMakeContextCurrent;
96 extern LPALCPROCESSCONTEXT palcProcessContext;
97 extern LPALCSUSPENDCONTEXT palcSuspendContext;
98 extern LPALCDESTROYCONTEXT palcDestroyContext;
99 extern LPALCGETCURRENTCONTEXT palcGetCurrentContext;
100 extern LPALCGETCONTEXTSDEVICE palcGetContextsDevice;
101 extern LPALCOPENDEVICE palcOpenDevice;
102 extern LPALCCLOSEDEVICE palcCloseDevice;
103 extern LPALCGETERROR palcGetError;
104 extern LPALCISEXTENSIONPRESENT palcIsExtensionPresent;
105 extern LPALCGETPROCADDRESS palcGetProcAddress;
106 extern LPALCGETENUMVALUE palcGetEnumValue;
107 extern LPALCGETSTRING palcGetString;
108 extern LPALCGETINTEGERV palcGetIntegerv;
109 extern LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice;
110 extern LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice;
111 extern LPALCCAPTURESTART palcCaptureStart;
112 extern LPALCCAPTURESTOP palcCaptureStop;
113 extern LPALCCAPTURESAMPLES palcCaptureSamples;
114 extern LPALENABLE palEnable;
115 extern LPALDISABLE palDisable;
116 extern LPALISENABLED palIsEnabled;
117 extern LPALGETSTRING palGetString;
118 extern LPALGETBOOLEANV palGetBooleanv;
119 extern LPALGETINTEGERV palGetIntegerv;
120 extern LPALGETFLOATV palGetFloatv;
121 extern LPALGETDOUBLEV palGetDoublev;
122 extern LPALGETBOOLEAN palGetBoolean;
123 extern LPALGETINTEGER palGetInteger;
124 extern LPALGETFLOAT palGetFloat;
125 extern LPALGETDOUBLE palGetDouble;
126 extern LPALGETERROR palGetError;
127 extern LPALISEXTENSIONPRESENT palIsExtensionPresent;
128 extern LPALGETPROCADDRESS palGetProcAddress;
129 extern LPALGETENUMVALUE palGetEnumValue;
130 extern LPALLISTENERF palListenerf;
131 extern LPALLISTENER3F palListener3f;
132 extern LPALLISTENERFV palListenerfv;
133 extern LPALLISTENERI palListeneri;
134 extern LPALLISTENER3I palListener3i;
135 extern LPALLISTENERIV palListeneriv;
136 extern LPALGETLISTENERF palGetListenerf;
137 extern LPALGETLISTENER3F palGetListener3f;
138 extern LPALGETLISTENERFV palGetListenerfv;
139 extern LPALGETLISTENERI palGetListeneri;
140 extern LPALGETLISTENER3I palGetListener3i;
141 extern LPALGETLISTENERIV palGetListeneriv;
142 extern LPALGENSOURCES palGenSources;
143 extern LPALDELETESOURCES palDeleteSources;
144 extern LPALISSOURCE palIsSource;
145 extern LPALSOURCEF palSourcef;
146 extern LPALSOURCE3F palSource3f;
147 extern LPALSOURCEFV palSourcefv;
148 extern LPALSOURCEI palSourcei;
149 extern LPALSOURCE3I palSource3i;
150 extern LPALSOURCEIV palSourceiv;
151 extern LPALGETSOURCEF palGetSourcef;
152 extern LPALGETSOURCE3F palGetSource3f;
153 extern LPALGETSOURCEFV palGetSourcefv;
154 extern LPALGETSOURCEI palGetSourcei;
155 extern LPALGETSOURCE3I palGetSource3i;
156 extern LPALGETSOURCEIV palGetSourceiv;
157 extern LPALSOURCEPLAYV palSourcePlayv;
158 extern LPALSOURCESTOPV palSourceStopv;
159 extern LPALSOURCEREWINDV palSourceRewindv;
160 extern LPALSOURCEPAUSEV palSourcePausev;
161 extern LPALSOURCEPLAY palSourcePlay;
162 extern LPALSOURCESTOP palSourceStop;
163 extern LPALSOURCEREWIND palSourceRewind;
164 extern LPALSOURCEPAUSE palSourcePause;
165 extern LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers;
166 extern LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers;
167 extern LPALGENBUFFERS palGenBuffers;
168 extern LPALDELETEBUFFERS palDeleteBuffers;
169 extern LPALISBUFFER palIsBuffer;
170 extern LPALBUFFERF palBufferf;
171 extern LPALBUFFER3F palBuffer3f;
172 extern LPALBUFFERFV palBufferfv;
173 extern LPALBUFFERI palBufferi;
174 extern LPALBUFFER3I palBuffer3i;
175 extern LPALBUFFERIV palBufferiv;
176 extern LPALGETBUFFERF palGetBufferf;
177 extern LPALGETBUFFER3F palGetBuffer3f;
178 extern LPALGETBUFFERFV palGetBufferfv;
179 extern LPALGETBUFFERI palGetBufferi;
180 extern LPALGETBUFFER3I palGetBuffer3i;
181 extern LPALGETBUFFERIV palGetBufferiv;
182 extern LPALBUFFERDATA palBufferData;
183 extern LPALDOPPLERFACTOR palDopplerFactor;
184 extern LPALDOPPLERVELOCITY palDopplerVelocity;
185 extern LPALDISTANCEMODEL palDistanceModel;
186 extern LPALSPEEDOFSOUND palSpeedOfSound;
188 #define alcCreateContext palcCreateContext
189 #define alcMakeContextCurrent palcMakeContextCurrent
190 #define alcProcessContext palcProcessContext
191 #define alcSuspendContext palcSuspendContext
192 #define alcDestroyContext palcDestroyContext
193 #define alcGetCurrentContext palcGetCurrentContext
194 #define alcGetContextsDevice palcGetContextsDevice
195 #define alcOpenDevice palcOpenDevice
196 #define alcCloseDevice palcCloseDevice
197 #define alcGetError palcGetError
198 #define alcIsExtensionPresent palcIsExtensionPresent
199 #define alcGetProcAddress palcGetProcAddress
200 #define alcGetEnumValue palcGetEnumValue
201 #define alcGetString palcGetString
202 #define alcGetIntegerv palcGetIntegerv
203 #define alcCaptureOpenDevice palcCaptureOpenDevice
204 #define alcCaptureCloseDevice palcCaptureCloseDevice
205 #define alcCaptureStart palcCaptureStart
206 #define alcCaptureStop palcCaptureStop
207 #define alcCaptureSamples palcCaptureSamples
208 #define alEnable palEnable
209 #define alDisable palDisable
210 #define alIsEnabled palIsEnabled
211 #define alGetString palGetString
212 #define alGetBooleanv palGetBooleanv
213 #define alGetIntegerv palGetIntegerv
214 #define alGetFloatv palGetFloatv
215 #define alGetDoublev palGetDoublev
216 #define alGetBoolean palGetBoolean
217 #define alGetInteger palGetInteger
218 #define alGetFloat palGetFloat
219 #define alGetDouble palGetDouble
220 #define alGetError palGetError
221 #define alIsExtensionPresent palIsExtensionPresent
222 #define alGetProcAddress palGetProcAddress
223 #define alGetEnumValue palGetEnumValue
224 #define alListenerf palListenerf
225 #define alListener3f palListener3f
226 #define alListenerfv palListenerfv
227 #define alListeneri palListeneri
228 #define alListener3i palListener3i
229 #define alListeneriv palListeneriv
230 #define alGetListenerf palGetListenerf
231 #define alGetListener3f palGetListener3f
232 #define alGetListenerfv palGetListenerfv
233 #define alGetListeneri palGetListeneri
234 #define alGetListener3i palGetListener3i
235 #define alGetListeneriv palGetListeneriv
236 #define alGenSources palGenSources
237 #define alDeleteSources palDeleteSources
238 #define alIsSource palIsSource
239 #define alSourcef palSourcef
240 #define alSource3f palSource3f
241 #define alSourcefv palSourcefv
242 #define alSourcei palSourcei
243 #define alSource3i palSource3i
244 #define alSourceiv palSourceiv
245 #define alGetSourcef palGetSourcef
246 #define alGetSource3f palGetSource3f
247 #define alGetSourcefv palGetSourcefv
248 #define alGetSourcei palGetSourcei
249 #define alGetSource3i palGetSource3i
250 #define alGetSourceiv palGetSourceiv
251 #define alSourcePlayv palSourcePlayv
252 #define alSourceStopv palSourceStopv
253 #define alSourceRewindv palSourceRewindv
254 #define alSourcePausev palSourcePausev
255 #define alSourcePlay palSourcePlay
256 #define alSourceStop palSourceStop
257 #define alSourceRewind palSourceRewind
258 #define alSourcePause palSourcePause
259 #define alSourceQueueBuffers palSourceQueueBuffers
260 #define alSourceUnqueueBuffers palSourceUnqueueBuffers
261 #define alGenBuffers palGenBuffers
262 #define alDeleteBuffers palDeleteBuffers
263 #define alIsBuffer palIsBuffer
264 #define alBufferf palBufferf
265 #define alBuffer3f palBuffer3f
266 #define alBufferfv palBufferfv
267 #define alBufferi palBufferi
268 #define alBuffer3i palBuffer3i
269 #define alBufferiv palBufferiv
270 #define alGetBufferf palGetBufferf
271 #define alGetBuffer3f palGetBuffer3f
272 #define alGetBufferfv palGetBufferfv
273 #define alGetBufferi palGetBufferi
274 #define alGetBuffer3i palGetBuffer3i
275 #define alGetBufferiv palGetBufferiv
276 #define alBufferData palBufferData
277 #define alDopplerFactor palDopplerFactor
278 #define alDopplerVelocity palDopplerVelocity
279 #define alDistanceModel palDistanceModel
280 #define alSpeedOfSound palSpeedOfSound
281 #endif
283 #include <math.h>
284 #include "wingdi.h"
285 #include "mmreg.h"
287 /* OpenAL only allows for 1 single access to the device at the same time */
288 extern CRITICAL_SECTION openal_crst;
290 extern LPALCMAKECONTEXTCURRENT set_context;
291 extern LPALCGETCURRENTCONTEXT get_context;
292 extern BOOL local_contexts;
295 typedef struct DS8Impl DS8Impl;
296 typedef struct DS8Primary DS8Primary;
297 typedef struct DS8Buffer DS8Buffer;
300 /* Sample types */
301 #define AL_BYTE 0x1400
302 #define AL_UNSIGNED_BYTE 0x1401
303 #define AL_SHORT 0x1402
304 #define AL_UNSIGNED_SHORT 0x1403
305 #define AL_INT 0x1404
306 #define AL_UNSIGNED_INT 0x1405
307 #define AL_FLOAT 0x1406
308 #define AL_DOUBLE 0x1407
309 #define AL_BYTE3 0x1408
310 #define AL_UNSIGNED_BYTE3 0x1409
311 #define AL_MULAW 0x1410
312 #define AL_IMA4 0x1411
314 /* Channel configurations */
315 #define AL_MONO 0x1500
316 #define AL_STEREO 0x1501
317 #define AL_REAR 0x1502
318 #define AL_QUAD 0x1503
319 #define AL_5POINT1 0x1504 /* (WFX order) */
320 #define AL_6POINT1 0x1505 /* (WFX order) */
321 #define AL_7POINT1 0x1506 /* (WFX order) */
323 /* Storage formats */
324 #define AL_MONO8 0x1100
325 #define AL_MONO16 0x1101
326 #define AL_MONO32F 0x10010
327 #define AL_STEREO8 0x1102
328 #define AL_STEREO16 0x1103
329 #define AL_STEREO32F 0x10011
330 #define AL_QUAD8 0x1204
331 #define AL_QUAD16 0x1205
332 #define AL_QUAD32F 0x1206
333 #define AL_REAR8 0x1207
334 #define AL_REAR16 0x1208
335 #define AL_REAR32F 0x1209
336 #define AL_5POINT1_8 0x120A
337 #define AL_5POINT1_16 0x120B
338 #define AL_5POINT1_32F 0x120C
339 #define AL_6POINT1_8 0x120D
340 #define AL_6POINT1_16 0x120E
341 #define AL_6POINT1_32F 0x120F
342 #define AL_7POINT1_8 0x1210
343 #define AL_7POINT1_16 0x1211
344 #define AL_7POINT1_32F 0x1212
346 enum {
347 EXT_EFX,
348 EXT_FLOAT32,
349 EXT_MCFORMATS,
350 EXT_STATIC_BUFFER,
351 SOFT_BUFFER_SAMPLES,
352 SOFT_BUFFER_SUB_DATA,
353 SOFT_DEFERRED_UPDATES,
355 MAX_EXTENSIONS
358 typedef struct ExtALFuncs {
359 PFNALBUFFERSUBDATASOFTPROC BufferSubData;
360 PFNALBUFFERDATASTATICPROC BufferDataStatic;
362 LPALGENEFFECTS GenEffects;
363 LPALDELETEEFFECTS DeleteEffects;
364 LPALEFFECTI Effecti;
365 LPALEFFECTF Effectf;
367 LPALGENAUXILIARYEFFECTSLOTS GenAuxiliaryEffectSlots;
368 LPALDELETEAUXILIARYEFFECTSLOTS DeleteAuxiliaryEffectSlots;
369 LPALAUXILIARYEFFECTSLOTI AuxiliaryEffectSloti;
371 void (AL_APIENTRY*BufferSamplesSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
372 void (AL_APIENTRY*BufferSubSamplesSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*);
373 void (AL_APIENTRY*GetBufferSamplesSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
374 ALboolean (AL_APIENTRY*IsBufferFormatSupportedSOFT)(ALenum);
376 void (AL_APIENTRY*DeferUpdatesSOFT)(void);
377 void (AL_APIENTRY*ProcessUpdatesSOFT)(void);
378 } ExtALFuncs;
380 #define MAX_SOURCES 256
381 typedef struct DeviceShare {
382 LONG ref;
384 ALCdevice *device;
385 ALCcontext *ctx;
387 ALboolean SupportedExt[MAX_EXTENSIONS];
389 ExtALFuncs ExtAL;
391 CRITICAL_SECTION crst;
393 ALuint sources[MAX_SOURCES];
394 DWORD nsources, max_sources;
396 ALuint auxslot;
398 GUID guid;
399 } DeviceShare;
402 union PrimaryParamFlags {
403 LONG flags;
404 struct {
405 BOOL pos : 1;
406 BOOL vel : 1;
407 BOOL orientation : 1;
408 BOOL distancefactor : 1;
409 BOOL rollofffactor : 1;
410 BOOL dopplerfactor : 1;
411 BOOL effect : 1;
412 } bit;
415 struct DS8Primary {
416 IDirectSoundBuffer IDirectSoundBuffer_iface;
417 IDirectSound3DListener IDirectSound3DListener_iface;
418 IKsPropertySet IKsPropertySet_iface;
420 LONG ref, ds3d_ref, prop_ref;
421 IDirectSoundBuffer8 *write_emu;
422 DS8Impl *parent;
424 /* Taken from the share */
425 ALCcontext *ctx;
426 const ALboolean *SupportedExt;
427 const ExtALFuncs *ExtAL;
428 CRITICAL_SECTION *crst;
429 ALuint *sources;
430 ALuint auxslot;
432 DWORD buf_size;
433 BOOL stopped;
434 DWORD flags;
435 WAVEFORMATEXTENSIBLE format;
437 UINT timer_id;
438 DWORD timer_res;
439 HANDLE thread_hdl;
440 DWORD thread_id;
442 DS8Buffer **buffers;
443 DWORD nbuffers, sizebuffers;
444 DS8Buffer **notifies;
445 DWORD nnotifies, sizenotifies;
447 ALuint effect;
448 ALfloat rollofffactor;
450 DS3DLISTENER params;
451 union PrimaryParamFlags dirty;
453 EAXLISTENERPROPERTIES eax_prop;
455 void (AL_APIENTRY*DeferUpdates)(void);
456 void (AL_APIENTRY*ProcessUpdates)(void);
460 /* Device implementation */
461 struct DS8Impl {
462 IDirectSound8 IDirectSound8_iface;
463 IDirectSound IDirectSound_iface;
465 LONG ref;
466 BOOL is_8;
468 DeviceShare *share;
470 /* Taken from the share */
471 ALCdevice *device;
473 DS8Primary primary;
475 DWORD speaker_config;
476 DWORD prio_level;
480 typedef struct DS8Data {
481 LONG ref;
483 /* Lock was called and unlock isn't? */
484 LONG locked;
486 WAVEFORMATEXTENSIBLE format;
488 ALuint buf_size;
489 ALenum buf_format;
490 ALenum in_type, in_chans;
491 DWORD dsbflags;
492 BYTE *data;
493 ALuint *buffers;
494 ALuint numsegs;
495 ALuint segsize;
496 ALuint lastsegsize;
497 } DS8Data;
498 /* Amount of buffers that have to be queued when
499 * bufferdatastatic and buffersubdata are not available */
500 #define QBUFFERS 3
502 union BufferParamFlags {
503 LONG flags;
504 struct {
505 BOOL pos : 1;
506 BOOL vel : 1;
507 BOOL cone_angles : 1;
508 BOOL cone_orient : 1;
509 BOOL cone_outsidevolume : 1;
510 BOOL min_distance : 1;
511 BOOL max_distance : 1;
512 BOOL mode : 1;
513 } bit;
516 struct DS8Buffer {
517 IDirectSoundBuffer8 IDirectSoundBuffer8_iface;
518 IDirectSoundBuffer IDirectSoundBuffer_iface;
519 IDirectSound3DBuffer IDirectSound3DBuffer_iface;
520 IDirectSoundNotify IDirectSoundNotify_iface;
521 IKsPropertySet IKsPropertySet_iface;
523 LONG ref, ds3d_ref, not_ref, prop_ref;
524 LONG all_ref;
526 DS8Primary *primary;
528 /* From the primary */
529 ALCcontext *ctx;
530 const ExtALFuncs *ExtAL;
531 CRITICAL_SECTION *crst;
533 DS8Data *buffer;
534 ALuint source;
535 ALuint curidx;
536 BOOL isplaying, islooping, bufferlost;
537 DWORD ds3dmode;
539 DS3DBUFFER params;
540 union BufferParamFlags dirty;
542 DWORD nnotify, lastpos;
543 DSBPOSITIONNOTIFY *notify;
546 const ALCchar *DSOUND_getdevicestrings(void);
547 const ALCchar *DSOUND_getcapturedevicestrings(void);
549 HRESULT DS8Primary_PreInit(DS8Primary *prim, DS8Impl *parent);
550 void DS8Primary_Clear(DS8Primary *prim);
551 void DS8Primary_starttimer(DS8Primary *prim);
553 HRESULT DS8Buffer_Create(DS8Buffer **ppv, DS8Primary *parent, IDirectSoundBuffer *orig);
554 void DS8Buffer_Destroy(DS8Buffer *buf);
555 void DS8Buffer_SetParams(DS8Buffer *buffer, const DS3DBUFFER *params, LONG flags);
557 static inline ALdouble gain_to_mB(ALdouble gain)
559 return log10(gain) * 2000.0;
561 static inline ALdouble mB_to_gain(ALdouble millibels)
563 return pow(10.0, millibels/2000.0);
566 static inline LONG clampI(LONG val, LONG minval, LONG maxval)
568 if(val >= maxval) return maxval;
569 if(val <= minval) return minval;
570 return val;
572 static inline ULONG clampU(ULONG val, ULONG minval, ULONG maxval)
574 if(val >= maxval) return maxval;
575 if(val <= minval) return minval;
576 return val;
578 static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval)
580 if(val >= maxval) return maxval;
581 if(val <= minval) return minval;
582 return val;
586 #define checkALError() do { \
587 ALenum err = alGetError(); \
588 if(err != AL_NO_ERROR) \
589 ERR(">>>>>>>>>>>> Received AL error %#x on context %p, %s:%u\n", \
590 err, get_context(), __FUNCTION__, __LINE__); \
591 } while (0)
593 #define checkALCError(dev) do { \
594 ALenum err = alcGetError(dev); \
595 if(err != ALC_NO_ERROR) \
596 ERR(">>>>>>>>>>>> Received ALC error %#x on device %p, %s:%u\n", \
597 err, dev, __FUNCTION__, __LINE__); \
598 } while(0)
600 #if ALLOW_CONCURRENT_AL
602 #define setALContext(actx) do { \
603 ALCcontext *__old_ctx, *cur_ctx = actx; \
604 if(!local_contexts) EnterCriticalSection(&openal_crst); \
605 __old_ctx = get_context(); \
606 if(__old_ctx != cur_ctx && set_context(cur_ctx) == ALC_FALSE) { \
607 ERR("Couldn't set current context!!\n"); \
608 checkALCError(alcGetContextsDevice(cur_ctx)); \
610 /* Only restore a NULL context if using global contexts, for TLS contexts always restore */
611 #define popALContext() \
612 if(__old_ctx != cur_ctx && (local_contexts || __old_ctx) && \
613 set_context(__old_ctx) == ALC_FALSE) { \
614 ERR("Couldn't restore old context!!\n"); \
615 checkALCError(alcGetContextsDevice(__old_ctx)); \
617 if (!local_contexts) LeaveCriticalSection(&openal_crst); \
618 } while(0)
620 #else
622 #define setALContext(actx) do { \
623 ALCcontext *cur_ctx = actx; \
624 if(!local_contexts) EnterCriticalSection(&openal_crst); \
625 if(set_context(cur_ctx) == ALC_FALSE) { \
626 ERR("Couldn't set current context!!\n"); \
627 checkALCError(alcGetContextsDevice(cur_ctx)); \
629 #define popALContext() \
630 if (!local_contexts) LeaveCriticalSection(&openal_crst); \
631 } while (0)
633 #endif
635 HRESULT DSOUND_Create(REFIID riid, void **ppDS);
636 HRESULT DSOUND_Create8(REFIID riid, void **ppDS);
637 HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppDSFD);
638 HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **piks);
639 HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppDSC);
640 HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppDSC);
642 extern const GUID DSOUND_renderer_guid;
643 extern const GUID DSOUND_capture_guid;