Don't try to allocate extra buffers
[dsound-openal.git] / dsound_private.h
blob94566d52645db28a90c1a48de3e78e8d13d58e34
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 #include <stdio.h>
30 #include <dsound.h>
32 #include "alc.h"
33 #include "al.h"
34 #include "alext.h"
36 #include "eax.h"
38 #ifndef AL_SOFT_map_buffer
39 #define AL_SOFT_map_buffer 1
40 typedef unsigned int ALbitfieldSOFT;
41 #define AL_MAP_READ_BIT_SOFT 0x00000001
42 #define AL_MAP_WRITE_BIT_SOFT 0x00000002
43 #define AL_MAP_PERSISTENT_BIT_SOFT 0x00000004
44 #define AL_PRESERVE_DATA_BIT_SOFT 0x00000008
45 typedef void (AL_APIENTRY*LPALBUFFERSTORAGESOFT)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq, ALbitfieldSOFT flags);
46 typedef void* (AL_APIENTRY*LPALMAPBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length, ALbitfieldSOFT access);
47 typedef void (AL_APIENTRY*LPALUNMAPBUFFERSOFT)(ALuint buffer);
48 typedef void (AL_APIENTRY*LPALFLUSHMAPPEDBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length);
49 #endif
52 #ifdef __GNUC__
53 #define LIKELY(x) __builtin_expect(!!(x), !0)
54 #define UNLIKELY(x) __builtin_expect(!!(x), !!0)
55 #else
56 #define LIKELY(x) (!!(x))
57 #define UNLIKELY(x) (!!(x))
58 #endif
61 extern int LogLevel;
62 extern FILE *LogFile;
64 #define DO_PRINT(a, ...) do { \
65 fprintf(LogFile, a, __VA_ARGS__); \
66 fflush(LogFile); \
67 } while(0)
69 #ifdef _MSC_VER
70 #define TRACE(fmt, ...) do { \
71 if(UNLIKELY(LogLevel >= 3)) \
72 DO_PRINT("%04x:trace:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
73 __FUNCTION__, __VA_ARGS__); \
74 } while(0)
75 #define WARN(fmt, ...) do { \
76 if(UNLIKELY(LogLevel >= 2)) \
77 DO_PRINT("%04x:warn:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
78 __FUNCTION__, __VA_ARGS__); \
79 } while(0)
80 #define FIXME(fmt, ...) do { \
81 if(UNLIKELY(LogLevel >= 1)) \
82 DO_PRINT("%04x:fixme:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
83 __FUNCTION__, __VA_ARGS__); \
84 } while(0)
85 #define ERR(fmt, ...) do { \
86 if(UNLIKELY(LogLevel >= 0)) \
87 DO_PRINT("%04x:err:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
88 __FUNCTION__, __VA_ARGS__); \
89 } while(0)
91 #else
93 #define TRACE(fmt, ...) do { \
94 if(UNLIKELY(LogLevel >= 3)) \
95 DO_PRINT("%04x:trace:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
96 __FUNCTION__, ## __VA_ARGS__); \
97 } while(0)
98 #define WARN(fmt, ...) do { \
99 if(UNLIKELY(LogLevel >= 2)) \
100 DO_PRINT("%04x:warn:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
101 __FUNCTION__, ## __VA_ARGS__); \
102 } while(0)
103 #define FIXME(fmt, ...) do { \
104 if(UNLIKELY(LogLevel >= 1)) \
105 DO_PRINT("%04x:fixme:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
106 __FUNCTION__, ## __VA_ARGS__); \
107 } while(0)
108 #define ERR(fmt, ...) do { \
109 if(UNLIKELY(LogLevel >= 0)) \
110 DO_PRINT("%04x:err:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
111 __FUNCTION__, ## __VA_ARGS__); \
112 } while(0)
113 #endif
115 const char *wine_dbg_sprintf( const char *format, ... );
116 const char *wine_dbgstr_wn( const WCHAR *str, int n );
117 const char *debugstr_guid( const GUID *id );
119 static inline const char *debugstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); }
122 #ifndef U64
123 #if defined(_MSC_VER)
124 #define U64(x) (x##ui64)
125 #elif SIZEOF_LONG == 8
126 #define U64(x) (x##ul)
127 #else
128 #define U64(x) (x##ull)
129 #endif
130 #endif
132 /* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
133 * is *UNDEFINED* if the value is 0.
135 #ifdef __GNUC__
137 #if SIZEOF_LONG == 8
138 #define CTZ64 __builtin_ctzl
139 #else
140 #define CTZ64 __builtin_ctzll
141 #endif
143 #elif defined(HAVE_BITSCANFORWARD64_INTRINSIC)
145 static inline int msvc64_ctz64(DWORD64 v)
147 unsigned long idx = 64;
148 _BitScanForward64(&idx, v);
149 return (int)idx;
151 #define CTZ64 msvc64_ctz64
153 #elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
155 static inline int msvc_ctz64(DWORD64 v)
157 unsigned long idx = 64;
158 if(!_BitScanForward(&idx, v&0xffffffff))
160 if(_BitScanForward(&idx, v>>32))
161 idx += 32;
163 return (int)idx;
165 #define CTZ64 msvc_ctz64
167 #else
169 /* There be black magics here. The popcnt64 method is derived from
170 * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
171 * while the ctz-utilizing-popcnt algorithm is shown here
172 * http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
173 * as the ntz2 variant. These likely aren't the most efficient methods, but
174 * they're good enough if the GCC or MSVC intrinsics aren't available.
176 static inline int fallback_popcnt64(DWORD64 v)
178 v = v - ((v >> 1) & U64(0x5555555555555555));
179 v = (v & U64(0x3333333333333333)) + ((v >> 2) & U64(0x3333333333333333));
180 v = (v + (v >> 4)) & U64(0x0f0f0f0f0f0f0f0f);
181 return (int)((v * U64(0x0101010101010101)) >> 56);
184 static inline int fallback_ctz64(DWORD64 value)
186 return fallback_popcnt64(~value & (value - 1));
188 #define CTZ64 fallback_ctz64
189 #endif
191 #ifdef __GNUC__
192 #define LIKELY(x) __builtin_expect(!!(x), !0)
193 #define UNLIKELY(x) __builtin_expect(!!(x), !!0)
194 #else
195 #define LIKELY(x) (x)
196 #define UNLIKELY(x) (x)
197 #endif
200 /* All openal functions */
201 extern int openal_loaded;
202 extern LPALCCREATECONTEXT palcCreateContext;
203 extern LPALCMAKECONTEXTCURRENT palcMakeContextCurrent;
204 extern LPALCPROCESSCONTEXT palcProcessContext;
205 extern LPALCSUSPENDCONTEXT palcSuspendContext;
206 extern LPALCDESTROYCONTEXT palcDestroyContext;
207 extern LPALCGETCURRENTCONTEXT palcGetCurrentContext;
208 extern LPALCGETCONTEXTSDEVICE palcGetContextsDevice;
209 extern LPALCOPENDEVICE palcOpenDevice;
210 extern LPALCCLOSEDEVICE palcCloseDevice;
211 extern LPALCGETERROR palcGetError;
212 extern LPALCISEXTENSIONPRESENT palcIsExtensionPresent;
213 extern LPALCGETPROCADDRESS palcGetProcAddress;
214 extern LPALCGETENUMVALUE palcGetEnumValue;
215 extern LPALCGETSTRING palcGetString;
216 extern LPALCGETINTEGERV palcGetIntegerv;
217 extern LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice;
218 extern LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice;
219 extern LPALCCAPTURESTART palcCaptureStart;
220 extern LPALCCAPTURESTOP palcCaptureStop;
221 extern LPALCCAPTURESAMPLES palcCaptureSamples;
222 extern LPALENABLE palEnable;
223 extern LPALDISABLE palDisable;
224 extern LPALISENABLED palIsEnabled;
225 extern LPALGETSTRING palGetString;
226 extern LPALGETBOOLEANV palGetBooleanv;
227 extern LPALGETINTEGERV palGetIntegerv;
228 extern LPALGETFLOATV palGetFloatv;
229 extern LPALGETDOUBLEV palGetDoublev;
230 extern LPALGETBOOLEAN palGetBoolean;
231 extern LPALGETINTEGER palGetInteger;
232 extern LPALGETFLOAT palGetFloat;
233 extern LPALGETDOUBLE palGetDouble;
234 extern LPALGETERROR palGetError;
235 extern LPALISEXTENSIONPRESENT palIsExtensionPresent;
236 extern LPALGETPROCADDRESS palGetProcAddress;
237 extern LPALGETENUMVALUE palGetEnumValue;
238 extern LPALLISTENERF palListenerf;
239 extern LPALLISTENER3F palListener3f;
240 extern LPALLISTENERFV palListenerfv;
241 extern LPALLISTENERI palListeneri;
242 extern LPALLISTENER3I palListener3i;
243 extern LPALLISTENERIV palListeneriv;
244 extern LPALGETLISTENERF palGetListenerf;
245 extern LPALGETLISTENER3F palGetListener3f;
246 extern LPALGETLISTENERFV palGetListenerfv;
247 extern LPALGETLISTENERI palGetListeneri;
248 extern LPALGETLISTENER3I palGetListener3i;
249 extern LPALGETLISTENERIV palGetListeneriv;
250 extern LPALGENSOURCES palGenSources;
251 extern LPALDELETESOURCES palDeleteSources;
252 extern LPALISSOURCE palIsSource;
253 extern LPALSOURCEF palSourcef;
254 extern LPALSOURCE3F palSource3f;
255 extern LPALSOURCEFV palSourcefv;
256 extern LPALSOURCEI palSourcei;
257 extern LPALSOURCE3I palSource3i;
258 extern LPALSOURCEIV palSourceiv;
259 extern LPALGETSOURCEF palGetSourcef;
260 extern LPALGETSOURCE3F palGetSource3f;
261 extern LPALGETSOURCEFV palGetSourcefv;
262 extern LPALGETSOURCEI palGetSourcei;
263 extern LPALGETSOURCE3I palGetSource3i;
264 extern LPALGETSOURCEIV palGetSourceiv;
265 extern LPALSOURCEPLAYV palSourcePlayv;
266 extern LPALSOURCESTOPV palSourceStopv;
267 extern LPALSOURCEREWINDV palSourceRewindv;
268 extern LPALSOURCEPAUSEV palSourcePausev;
269 extern LPALSOURCEPLAY palSourcePlay;
270 extern LPALSOURCESTOP palSourceStop;
271 extern LPALSOURCEREWIND palSourceRewind;
272 extern LPALSOURCEPAUSE palSourcePause;
273 extern LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers;
274 extern LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers;
275 extern LPALGENBUFFERS palGenBuffers;
276 extern LPALDELETEBUFFERS palDeleteBuffers;
277 extern LPALISBUFFER palIsBuffer;
278 extern LPALBUFFERF palBufferf;
279 extern LPALBUFFER3F palBuffer3f;
280 extern LPALBUFFERFV palBufferfv;
281 extern LPALBUFFERI palBufferi;
282 extern LPALBUFFER3I palBuffer3i;
283 extern LPALBUFFERIV palBufferiv;
284 extern LPALGETBUFFERF palGetBufferf;
285 extern LPALGETBUFFER3F palGetBuffer3f;
286 extern LPALGETBUFFERFV palGetBufferfv;
287 extern LPALGETBUFFERI palGetBufferi;
288 extern LPALGETBUFFER3I palGetBuffer3i;
289 extern LPALGETBUFFERIV palGetBufferiv;
290 extern LPALBUFFERDATA palBufferData;
291 extern LPALDOPPLERFACTOR palDopplerFactor;
292 extern LPALDOPPLERVELOCITY palDopplerVelocity;
293 extern LPALDISTANCEMODEL palDistanceModel;
294 extern LPALSPEEDOFSOUND palSpeedOfSound;
296 #define alcCreateContext palcCreateContext
297 #define alcMakeContextCurrent palcMakeContextCurrent
298 #define alcProcessContext palcProcessContext
299 #define alcSuspendContext palcSuspendContext
300 #define alcDestroyContext palcDestroyContext
301 #define alcGetCurrentContext palcGetCurrentContext
302 #define alcGetContextsDevice palcGetContextsDevice
303 #define alcOpenDevice palcOpenDevice
304 #define alcCloseDevice palcCloseDevice
305 #define alcGetError palcGetError
306 #define alcIsExtensionPresent palcIsExtensionPresent
307 #define alcGetProcAddress palcGetProcAddress
308 #define alcGetEnumValue palcGetEnumValue
309 #define alcGetString palcGetString
310 #define alcGetIntegerv palcGetIntegerv
311 #define alcCaptureOpenDevice palcCaptureOpenDevice
312 #define alcCaptureCloseDevice palcCaptureCloseDevice
313 #define alcCaptureStart palcCaptureStart
314 #define alcCaptureStop palcCaptureStop
315 #define alcCaptureSamples palcCaptureSamples
316 #define alEnable palEnable
317 #define alDisable palDisable
318 #define alIsEnabled palIsEnabled
319 #define alGetString palGetString
320 #define alGetBooleanv palGetBooleanv
321 #define alGetIntegerv palGetIntegerv
322 #define alGetFloatv palGetFloatv
323 #define alGetDoublev palGetDoublev
324 #define alGetBoolean palGetBoolean
325 #define alGetInteger palGetInteger
326 #define alGetFloat palGetFloat
327 #define alGetDouble palGetDouble
328 #define alGetError palGetError
329 #define alIsExtensionPresent palIsExtensionPresent
330 #define alGetProcAddress palGetProcAddress
331 #define alGetEnumValue palGetEnumValue
332 #define alListenerf palListenerf
333 #define alListener3f palListener3f
334 #define alListenerfv palListenerfv
335 #define alListeneri palListeneri
336 #define alListener3i palListener3i
337 #define alListeneriv palListeneriv
338 #define alGetListenerf palGetListenerf
339 #define alGetListener3f palGetListener3f
340 #define alGetListenerfv palGetListenerfv
341 #define alGetListeneri palGetListeneri
342 #define alGetListener3i palGetListener3i
343 #define alGetListeneriv palGetListeneriv
344 #define alGenSources palGenSources
345 #define alDeleteSources palDeleteSources
346 #define alIsSource palIsSource
347 #define alSourcef palSourcef
348 #define alSource3f palSource3f
349 #define alSourcefv palSourcefv
350 #define alSourcei palSourcei
351 #define alSource3i palSource3i
352 #define alSourceiv palSourceiv
353 #define alGetSourcef palGetSourcef
354 #define alGetSource3f palGetSource3f
355 #define alGetSourcefv palGetSourcefv
356 #define alGetSourcei palGetSourcei
357 #define alGetSource3i palGetSource3i
358 #define alGetSourceiv palGetSourceiv
359 #define alSourcePlayv palSourcePlayv
360 #define alSourceStopv palSourceStopv
361 #define alSourceRewindv palSourceRewindv
362 #define alSourcePausev palSourcePausev
363 #define alSourcePlay palSourcePlay
364 #define alSourceStop palSourceStop
365 #define alSourceRewind palSourceRewind
366 #define alSourcePause palSourcePause
367 #define alSourceQueueBuffers palSourceQueueBuffers
368 #define alSourceUnqueueBuffers palSourceUnqueueBuffers
369 #define alGenBuffers palGenBuffers
370 #define alDeleteBuffers palDeleteBuffers
371 #define alIsBuffer palIsBuffer
372 #define alBufferf palBufferf
373 #define alBuffer3f palBuffer3f
374 #define alBufferfv palBufferfv
375 #define alBufferi palBufferi
376 #define alBuffer3i palBuffer3i
377 #define alBufferiv palBufferiv
378 #define alGetBufferf palGetBufferf
379 #define alGetBuffer3f palGetBuffer3f
380 #define alGetBufferfv palGetBufferfv
381 #define alGetBufferi palGetBufferi
382 #define alGetBuffer3i palGetBuffer3i
383 #define alGetBufferiv palGetBufferiv
384 #define alBufferData palBufferData
385 #define alDopplerFactor palDopplerFactor
386 #define alDopplerVelocity palDopplerVelocity
387 #define alDistanceModel palDistanceModel
388 #define alSpeedOfSound palSpeedOfSound
390 #include <math.h>
391 #include "wingdi.h"
392 #include "mmreg.h"
394 /* OpenAL only allows for 1 single access to the device at the same time */
395 extern CRITICAL_SECTION openal_crst;
397 extern LPALCMAKECONTEXTCURRENT set_context;
398 extern LPALCGETCURRENTCONTEXT get_context;
399 extern BOOL local_contexts;
402 extern DWORD TlsThreadPtr;
403 extern void (*EnterALSection)(ALCcontext *ctx);
404 extern void (*LeaveALSection)(void);
407 typedef struct DS8Impl DS8Impl;
408 typedef struct DS8Primary DS8Primary;
409 typedef struct DS8Buffer DS8Buffer;
412 enum {
413 EXT_EFX,
414 EXT_FLOAT32,
415 EXT_MCFORMATS,
416 SOFT_DEFERRED_UPDATES,
417 SOFTX_MAP_BUFFER,
419 MAX_EXTENSIONS
422 typedef struct ExtALFuncs {
423 LPALGENEFFECTS GenEffects;
424 LPALDELETEEFFECTS DeleteEffects;
425 LPALEFFECTI Effecti;
426 LPALEFFECTF Effectf;
428 LPALGENAUXILIARYEFFECTSLOTS GenAuxiliaryEffectSlots;
429 LPALDELETEAUXILIARYEFFECTSLOTS DeleteAuxiliaryEffectSlots;
430 LPALAUXILIARYEFFECTSLOTI AuxiliaryEffectSloti;
432 LPALDEFERUPDATESSOFT DeferUpdatesSOFT;
433 LPALPROCESSUPDATESSOFT ProcessUpdatesSOFT;
435 LPALBUFFERSTORAGESOFT BufferStorageSOFT;
436 LPALMAPBUFFERSOFT MapBufferSOFT;
437 LPALUNMAPBUFFERSOFT UnmapBufferSOFT;
438 LPALFLUSHMAPPEDBUFFERSOFT FlushMappedBufferSOFT;
439 } ExtALFuncs;
441 #define MAX_SOURCES 256
442 typedef struct DeviceShare {
443 LONG ref;
445 ALCdevice *device;
446 ALCcontext *ctx;
447 ALCint refresh;
449 ALboolean SupportedExt[MAX_EXTENSIONS];
451 ExtALFuncs ExtAL;
453 CRITICAL_SECTION crst;
455 ALuint sources[MAX_SOURCES];
456 DWORD nsources, max_sources;
458 ALuint auxslot;
460 HANDLE thread_hdl;
461 DWORD thread_id;
463 HANDLE queue_timer;
464 HANDLE timer_evt;
465 volatile LONG quit_now;
467 ALsizei nprimaries;
468 DS8Primary **primaries;
470 GUID guid;
471 } DeviceShare;
474 typedef struct DS8Data {
475 LONG ref;
477 DS8Primary *primary;
479 /* Lock was called and unlock isn't? */
480 LONG locked;
482 WAVEFORMATEXTENSIBLE format;
484 ALsizei buf_size;
485 ALenum buf_format;
486 DWORD dsbflags;
487 BYTE *data;
488 ALuint bid;
489 } DS8Data;
490 /* Amount of buffers that have to be queued when
491 * bufferdatastatic and buffersubdata are not available */
492 #define QBUFFERS 4
494 union BufferParamFlags {
495 LONG flags;
496 struct {
497 BOOL pos : 1;
498 BOOL vel : 1;
499 BOOL cone_angles : 1;
500 BOOL cone_orient : 1;
501 BOOL cone_outsidevolume : 1;
502 BOOL min_distance : 1;
503 BOOL max_distance : 1;
504 BOOL mode : 1;
505 } bit;
508 struct DS8Buffer {
509 IDirectSoundBuffer8 IDirectSoundBuffer8_iface;
510 IDirectSoundBuffer IDirectSoundBuffer_iface;
511 IDirectSound3DBuffer IDirectSound3DBuffer_iface;
512 IDirectSoundNotify IDirectSoundNotify_iface;
513 IKsPropertySet IKsPropertySet_iface;
515 LONG ref, ds3d_ref, not_ref, prop_ref;
516 LONG all_ref;
518 DS8Primary *primary;
520 /* From the primary */
521 ALCcontext *ctx;
522 const ExtALFuncs *ExtAL;
523 CRITICAL_SECTION *crst;
525 DS8Data *buffer;
526 ALuint source;
528 ALsizei segsize;
529 ALsizei data_offset;
530 ALsizei queue_base;
531 ALsizei curidx;
532 ALuint stream_bids[QBUFFERS];
534 DWORD isplaying : 1;
535 DWORD islooping : 1;
536 DWORD bufferlost : 1;
537 DWORD playflags : 29;
538 DWORD ds3dmode;
540 DS3DBUFFER params;
541 union BufferParamFlags dirty;
543 DWORD nnotify, lastpos;
544 DSBPOSITIONNOTIFY *notify;
548 struct DSBufferGroup {
549 DWORD64 FreeBuffers;
550 DS8Buffer Buffers[64];
554 union PrimaryParamFlags {
555 LONG flags;
556 struct {
557 BOOL pos : 1;
558 BOOL vel : 1;
559 BOOL orientation : 1;
560 BOOL distancefactor : 1;
561 BOOL rollofffactor : 1;
562 BOOL dopplerfactor : 1;
563 BOOL effect : 1;
564 } bit;
567 struct DS8Primary {
568 IDirectSoundBuffer IDirectSoundBuffer_iface;
569 IDirectSound3DListener IDirectSound3DListener_iface;
570 IKsPropertySet IKsPropertySet_iface;
572 LONG ref, ds3d_ref, prop_ref;
573 IDirectSoundBuffer8 *write_emu;
574 DS8Buffer writable_buf;
575 DS8Impl *parent;
577 /* Taken from the share */
578 ALCcontext *ctx;
579 const ALboolean *SupportedExt;
580 const ExtALFuncs *ExtAL;
581 CRITICAL_SECTION *crst;
582 ALCint refresh;
583 ALuint *sources;
584 ALuint auxslot;
586 DWORD buf_size;
587 BOOL stopped;
588 DWORD flags;
589 WAVEFORMATEXTENSIBLE format;
591 LPALDEFERUPDATESSOFT DeferUpdates;
592 LPALPROCESSUPDATESSOFT ProcessUpdates;
594 DS8Buffer **notifies;
595 DWORD nnotifies, sizenotifies;
597 ALuint effect;
598 ALfloat rollofffactor;
600 DS3DLISTENER params;
601 union PrimaryParamFlags dirty;
603 EAXLISTENERPROPERTIES eax_prop;
605 DWORD NumBufferGroups;
606 struct DSBufferGroup *BufferGroups;
610 /* Device implementation */
611 struct DS8Impl {
612 IDirectSound8 IDirectSound8_iface;
613 IDirectSound IDirectSound_iface;
614 IUnknown IUnknown_iface;
616 LONG ref, unkref, dsref;
617 BOOL is_8;
619 DeviceShare *share;
621 /* Taken from the share */
622 ALCdevice *device;
624 DS8Primary primary;
626 DWORD speaker_config;
627 DWORD prio_level;
631 const ALCchar *DSOUND_getdevicestrings(void);
632 const ALCchar *DSOUND_getcapturedevicestrings(void);
634 HRESULT DS8Primary_PreInit(DS8Primary *prim, DS8Impl *parent);
635 void DS8Primary_Clear(DS8Primary *prim);
636 void DS8Primary_triggernots(DS8Primary *prim);
637 void DS8Primary_streamfeeder(DS8Primary *prim, BYTE *scratch_mem/*2K non-permanent memory*/);
638 HRESULT WINAPI DS8Primary_Initialize(IDirectSoundBuffer *iface, IDirectSound *ds, const DSBUFFERDESC *desc);
639 HRESULT WINAPI DS8Primary3D_CommitDeferredSettings(IDirectSound3DListener *iface);
641 HRESULT DS8Buffer_Create(DS8Buffer **ppv, DS8Primary *parent, IDirectSoundBuffer *orig, BOOL prim_emu);
642 void DS8Buffer_Destroy(DS8Buffer *buf);
643 void DS8Buffer_SetParams(DS8Buffer *buffer, const DS3DBUFFER *params, LONG flags);
644 HRESULT WINAPI DS8Buffer_GetCurrentPosition(IDirectSoundBuffer8 *iface, DWORD *playpos, DWORD *curpos);
645 HRESULT WINAPI DS8Buffer_GetStatus(IDirectSoundBuffer8 *iface, DWORD *status);
646 HRESULT WINAPI DS8Buffer_Initialize(IDirectSoundBuffer8 *iface, IDirectSound *ds, const DSBUFFERDESC *desc);
648 static inline LONG gain_to_mB(float gain)
650 return (LONG)(log10f(gain) * 2000.0f);
652 static inline float mB_to_gain(LONG millibels)
654 return powf(10.0f, (float)millibels/2000.0f);
656 static inline float mBF_to_gain(float millibels)
658 return powf(10.0f, millibels/2000.0f);
661 static inline LONG clampI(LONG val, LONG minval, LONG maxval)
663 if(val >= maxval) return maxval;
664 if(val <= minval) return minval;
665 return val;
667 static inline ULONG clampU(ULONG val, ULONG minval, ULONG maxval)
669 if(val >= maxval) return maxval;
670 if(val <= minval) return minval;
671 return val;
673 static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval)
675 if(val >= maxval) return maxval;
676 if(val <= minval) return minval;
677 return val;
681 #define checkALError() do { \
682 ALenum err = alGetError(); \
683 if(err != AL_NO_ERROR) \
684 ERR(">>>>>>>>>>>> Received AL error %#x on context %p, %s:%u\n", \
685 err, get_context(), __FUNCTION__, __LINE__); \
686 } while (0)
688 #define checkALCError(dev) do { \
689 ALenum err = alcGetError(dev); \
690 if(err != ALC_NO_ERROR) \
691 ERR(">>>>>>>>>>>> Received ALC error %#x on device %p, %s:%u\n", \
692 err, dev, __FUNCTION__, __LINE__); \
693 } while(0)
696 #define setALContext(actx) EnterALSection(actx)
697 #define popALContext() LeaveALSection()
700 HRESULT DSOUND_Create(REFIID riid, void **ppDS);
701 HRESULT DSOUND_Create8(REFIID riid, void **ppDS);
702 HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppDSFD);
703 HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **piks);
704 HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppDSC);
705 HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppDSC);
707 extern const GUID DSOUND_renderer_guid;
708 extern const GUID DSOUND_capture_guid;