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)
32 #include <mmdeviceapi.h>
33 #include <devpropdef.h>
44 #ifndef AL_SOFT_map_buffer
45 #define AL_SOFT_map_buffer 1
46 typedef unsigned int ALbitfieldSOFT
;
47 #define AL_MAP_READ_BIT_SOFT 0x00000001
48 #define AL_MAP_WRITE_BIT_SOFT 0x00000002
49 #define AL_MAP_PERSISTENT_BIT_SOFT 0x00000004
50 #define AL_PRESERVE_DATA_BIT_SOFT 0x00000008
51 typedef void (AL_APIENTRY
*LPALBUFFERSTORAGESOFT
)(ALuint buffer
, ALenum format
, const ALvoid
*data
, ALsizei size
, ALsizei freq
, ALbitfieldSOFT flags
);
52 typedef void* (AL_APIENTRY
*LPALMAPBUFFERSOFT
)(ALuint buffer
, ALsizei offset
, ALsizei length
, ALbitfieldSOFT access
);
53 typedef void (AL_APIENTRY
*LPALUNMAPBUFFERSOFT
)(ALuint buffer
);
54 typedef void (AL_APIENTRY
*LPALFLUSHMAPPEDBUFFERSOFT
)(ALuint buffer
, ALsizei offset
, ALsizei length
);
59 #define LIKELY(x) __builtin_expect(!!(x), !0)
60 #define UNLIKELY(x) __builtin_expect(!!(x), !!0)
62 #define LIKELY(x) (!!(x))
63 #define UNLIKELY(x) (!!(x))
70 #define DO_PRINT(a, ...) do { \
71 fprintf(LogFile, a, __VA_ARGS__); \
76 #define TRACE(fmt, ...) do { \
77 if(UNLIKELY(LogLevel >= 3)) \
78 DO_PRINT("%04x:trace:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
79 __FUNCTION__, __VA_ARGS__); \
81 #define WARN(fmt, ...) do { \
82 if(UNLIKELY(LogLevel >= 2)) \
83 DO_PRINT("%04x:warn:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
84 __FUNCTION__, __VA_ARGS__); \
86 #define FIXME(fmt, ...) do { \
87 if(UNLIKELY(LogLevel >= 1)) \
88 DO_PRINT("%04x:fixme:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
89 __FUNCTION__, __VA_ARGS__); \
91 #define ERR(fmt, ...) do { \
92 if(UNLIKELY(LogLevel >= 0)) \
93 DO_PRINT("%04x:err:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
94 __FUNCTION__, __VA_ARGS__); \
99 #define TRACE(fmt, ...) do { \
100 if(UNLIKELY(LogLevel >= 3)) \
101 DO_PRINT("%04x:trace:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
102 __FUNCTION__, ## __VA_ARGS__); \
104 #define WARN(fmt, ...) do { \
105 if(UNLIKELY(LogLevel >= 2)) \
106 DO_PRINT("%04x:warn:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
107 __FUNCTION__, ## __VA_ARGS__); \
109 #define FIXME(fmt, ...) do { \
110 if(UNLIKELY(LogLevel >= 1)) \
111 DO_PRINT("%04x:fixme:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
112 __FUNCTION__, ## __VA_ARGS__); \
114 #define ERR(fmt, ...) do { \
115 if(UNLIKELY(LogLevel >= 0)) \
116 DO_PRINT("%04x:err:dsound:%s " fmt, (UINT)GetCurrentThreadId(), \
117 __FUNCTION__, ## __VA_ARGS__); \
121 const char *wine_dbg_sprintf( const char *format
, ... );
122 const char *wine_dbgstr_wn( const WCHAR
*str
, int n
);
123 const char *debugstr_guid( const GUID
*id
);
125 static inline const char *debugstr_w( const WCHAR
*s
) { return wine_dbgstr_wn( s
, -1 ); }
129 #if defined(_MSC_VER)
130 #define U64(x) (x##ui64)
131 #elif SIZEOF_LONG == 8
132 #define U64(x) (x##ul)
134 #define U64(x) (x##ull)
138 /* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
139 * is *UNDEFINED* if the value is 0.
144 #define POPCNT64 __builtin_popcountl
145 #define CTZ64 __builtin_ctzl
147 #define POPCNT64 __builtin_popcountll
148 #define CTZ64 __builtin_ctzll
153 /* There be black magics here. The popcnt64 method is derived from
154 * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
156 static inline int fallback_popcnt64(DWORD64 v
)
158 v
= v
- ((v
>> 1) & U64(0x5555555555555555));
159 v
= (v
& U64(0x3333333333333333)) + ((v
>> 2) & U64(0x3333333333333333));
160 v
= (v
+ (v
>> 4)) & U64(0x0f0f0f0f0f0f0f0f);
161 return (int)((v
* U64(0x0101010101010101)) >> 56);
163 #define POPCNT64 fallback_popcnt64
165 #if defined(HAVE_BITSCANFORWARD64_INTRINSIC)
167 static inline int msvc64_ctz64(DWORD64 v
)
169 unsigned long idx
= 64;
170 _BitScanForward64(&idx
, v
);
173 #define CTZ64 msvc64_ctz64
175 #elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
177 static inline int msvc_ctz64(DWORD64 v
)
179 unsigned long idx
= 64;
180 if(!_BitScanForward(&idx
, v
&0xffffffff))
182 if(_BitScanForward(&idx
, v
>>32))
187 #define CTZ64 msvc_ctz64
191 static inline int fallback_ctz64(DWORD64 value
)
193 return fallback_popcnt64(~value
& (value
- 1));
195 #define CTZ64 fallback_ctz64
200 #define LIKELY(x) __builtin_expect(!!(x), !0)
201 #define UNLIKELY(x) __builtin_expect(!!(x), !!0)
203 #define LIKELY(x) (x)
204 #define UNLIKELY(x) (x)
208 /* All openal functions */
209 extern int openal_loaded
;
210 extern LPALCCREATECONTEXT palcCreateContext
;
211 extern LPALCMAKECONTEXTCURRENT palcMakeContextCurrent
;
212 extern LPALCPROCESSCONTEXT palcProcessContext
;
213 extern LPALCSUSPENDCONTEXT palcSuspendContext
;
214 extern LPALCDESTROYCONTEXT palcDestroyContext
;
215 extern LPALCGETCURRENTCONTEXT palcGetCurrentContext
;
216 extern LPALCGETCONTEXTSDEVICE palcGetContextsDevice
;
217 extern LPALCOPENDEVICE palcOpenDevice
;
218 extern LPALCCLOSEDEVICE palcCloseDevice
;
219 extern LPALCGETERROR palcGetError
;
220 extern LPALCISEXTENSIONPRESENT palcIsExtensionPresent
;
221 extern LPALCGETPROCADDRESS palcGetProcAddress
;
222 extern LPALCGETENUMVALUE palcGetEnumValue
;
223 extern LPALCGETSTRING palcGetString
;
224 extern LPALCGETINTEGERV palcGetIntegerv
;
225 extern LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice
;
226 extern LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice
;
227 extern LPALCCAPTURESTART palcCaptureStart
;
228 extern LPALCCAPTURESTOP palcCaptureStop
;
229 extern LPALCCAPTURESAMPLES palcCaptureSamples
;
230 extern LPALENABLE palEnable
;
231 extern LPALDISABLE palDisable
;
232 extern LPALISENABLED palIsEnabled
;
233 extern LPALGETSTRING palGetString
;
234 extern LPALGETBOOLEANV palGetBooleanv
;
235 extern LPALGETINTEGERV palGetIntegerv
;
236 extern LPALGETFLOATV palGetFloatv
;
237 extern LPALGETDOUBLEV palGetDoublev
;
238 extern LPALGETBOOLEAN palGetBoolean
;
239 extern LPALGETINTEGER palGetInteger
;
240 extern LPALGETFLOAT palGetFloat
;
241 extern LPALGETDOUBLE palGetDouble
;
242 extern LPALGETERROR palGetError
;
243 extern LPALISEXTENSIONPRESENT palIsExtensionPresent
;
244 extern LPALGETPROCADDRESS palGetProcAddress
;
245 extern LPALGETENUMVALUE palGetEnumValue
;
246 extern LPALLISTENERF palListenerf
;
247 extern LPALLISTENER3F palListener3f
;
248 extern LPALLISTENERFV palListenerfv
;
249 extern LPALLISTENERI palListeneri
;
250 extern LPALLISTENER3I palListener3i
;
251 extern LPALLISTENERIV palListeneriv
;
252 extern LPALGETLISTENERF palGetListenerf
;
253 extern LPALGETLISTENER3F palGetListener3f
;
254 extern LPALGETLISTENERFV palGetListenerfv
;
255 extern LPALGETLISTENERI palGetListeneri
;
256 extern LPALGETLISTENER3I palGetListener3i
;
257 extern LPALGETLISTENERIV palGetListeneriv
;
258 extern LPALGENSOURCES palGenSources
;
259 extern LPALDELETESOURCES palDeleteSources
;
260 extern LPALISSOURCE palIsSource
;
261 extern LPALSOURCEF palSourcef
;
262 extern LPALSOURCE3F palSource3f
;
263 extern LPALSOURCEFV palSourcefv
;
264 extern LPALSOURCEI palSourcei
;
265 extern LPALSOURCE3I palSource3i
;
266 extern LPALSOURCEIV palSourceiv
;
267 extern LPALGETSOURCEF palGetSourcef
;
268 extern LPALGETSOURCE3F palGetSource3f
;
269 extern LPALGETSOURCEFV palGetSourcefv
;
270 extern LPALGETSOURCEI palGetSourcei
;
271 extern LPALGETSOURCE3I palGetSource3i
;
272 extern LPALGETSOURCEIV palGetSourceiv
;
273 extern LPALSOURCEPLAYV palSourcePlayv
;
274 extern LPALSOURCESTOPV palSourceStopv
;
275 extern LPALSOURCEREWINDV palSourceRewindv
;
276 extern LPALSOURCEPAUSEV palSourcePausev
;
277 extern LPALSOURCEPLAY palSourcePlay
;
278 extern LPALSOURCESTOP palSourceStop
;
279 extern LPALSOURCEREWIND palSourceRewind
;
280 extern LPALSOURCEPAUSE palSourcePause
;
281 extern LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers
;
282 extern LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers
;
283 extern LPALGENBUFFERS palGenBuffers
;
284 extern LPALDELETEBUFFERS palDeleteBuffers
;
285 extern LPALISBUFFER palIsBuffer
;
286 extern LPALBUFFERF palBufferf
;
287 extern LPALBUFFER3F palBuffer3f
;
288 extern LPALBUFFERFV palBufferfv
;
289 extern LPALBUFFERI palBufferi
;
290 extern LPALBUFFER3I palBuffer3i
;
291 extern LPALBUFFERIV palBufferiv
;
292 extern LPALGETBUFFERF palGetBufferf
;
293 extern LPALGETBUFFER3F palGetBuffer3f
;
294 extern LPALGETBUFFERFV palGetBufferfv
;
295 extern LPALGETBUFFERI palGetBufferi
;
296 extern LPALGETBUFFER3I palGetBuffer3i
;
297 extern LPALGETBUFFERIV palGetBufferiv
;
298 extern LPALBUFFERDATA palBufferData
;
299 extern LPALDOPPLERFACTOR palDopplerFactor
;
300 extern LPALDOPPLERVELOCITY palDopplerVelocity
;
301 extern LPALDISTANCEMODEL palDistanceModel
;
302 extern LPALSPEEDOFSOUND palSpeedOfSound
;
304 #define alcCreateContext palcCreateContext
305 #define alcMakeContextCurrent palcMakeContextCurrent
306 #define alcProcessContext palcProcessContext
307 #define alcSuspendContext palcSuspendContext
308 #define alcDestroyContext palcDestroyContext
309 #define alcGetCurrentContext palcGetCurrentContext
310 #define alcGetContextsDevice palcGetContextsDevice
311 #define alcOpenDevice palcOpenDevice
312 #define alcCloseDevice palcCloseDevice
313 #define alcGetError palcGetError
314 #define alcIsExtensionPresent palcIsExtensionPresent
315 #define alcGetProcAddress palcGetProcAddress
316 #define alcGetEnumValue palcGetEnumValue
317 #define alcGetString palcGetString
318 #define alcGetIntegerv palcGetIntegerv
319 #define alcCaptureOpenDevice palcCaptureOpenDevice
320 #define alcCaptureCloseDevice palcCaptureCloseDevice
321 #define alcCaptureStart palcCaptureStart
322 #define alcCaptureStop palcCaptureStop
323 #define alcCaptureSamples palcCaptureSamples
324 #define alEnable palEnable
325 #define alDisable palDisable
326 #define alIsEnabled palIsEnabled
327 #define alGetString palGetString
328 #define alGetBooleanv palGetBooleanv
329 #define alGetIntegerv palGetIntegerv
330 #define alGetFloatv palGetFloatv
331 #define alGetDoublev palGetDoublev
332 #define alGetBoolean palGetBoolean
333 #define alGetInteger palGetInteger
334 #define alGetFloat palGetFloat
335 #define alGetDouble palGetDouble
336 #define alGetError palGetError
337 #define alIsExtensionPresent palIsExtensionPresent
338 #define alGetProcAddress palGetProcAddress
339 #define alGetEnumValue palGetEnumValue
340 #define alListenerf palListenerf
341 #define alListener3f palListener3f
342 #define alListenerfv palListenerfv
343 #define alListeneri palListeneri
344 #define alListener3i palListener3i
345 #define alListeneriv palListeneriv
346 #define alGetListenerf palGetListenerf
347 #define alGetListener3f palGetListener3f
348 #define alGetListenerfv palGetListenerfv
349 #define alGetListeneri palGetListeneri
350 #define alGetListener3i palGetListener3i
351 #define alGetListeneriv palGetListeneriv
352 #define alGenSources palGenSources
353 #define alDeleteSources palDeleteSources
354 #define alIsSource palIsSource
355 #define alSourcef palSourcef
356 #define alSource3f palSource3f
357 #define alSourcefv palSourcefv
358 #define alSourcei palSourcei
359 #define alSource3i palSource3i
360 #define alSourceiv palSourceiv
361 #define alGetSourcef palGetSourcef
362 #define alGetSource3f palGetSource3f
363 #define alGetSourcefv palGetSourcefv
364 #define alGetSourcei palGetSourcei
365 #define alGetSource3i palGetSource3i
366 #define alGetSourceiv palGetSourceiv
367 #define alSourcePlayv palSourcePlayv
368 #define alSourceStopv palSourceStopv
369 #define alSourceRewindv palSourceRewindv
370 #define alSourcePausev palSourcePausev
371 #define alSourcePlay palSourcePlay
372 #define alSourceStop palSourceStop
373 #define alSourceRewind palSourceRewind
374 #define alSourcePause palSourcePause
375 #define alSourceQueueBuffers palSourceQueueBuffers
376 #define alSourceUnqueueBuffers palSourceUnqueueBuffers
377 #define alGenBuffers palGenBuffers
378 #define alDeleteBuffers palDeleteBuffers
379 #define alIsBuffer palIsBuffer
380 #define alBufferf palBufferf
381 #define alBuffer3f palBuffer3f
382 #define alBufferfv palBufferfv
383 #define alBufferi palBufferi
384 #define alBuffer3i palBuffer3i
385 #define alBufferiv palBufferiv
386 #define alGetBufferf palGetBufferf
387 #define alGetBuffer3f palGetBuffer3f
388 #define alGetBufferfv palGetBufferfv
389 #define alGetBufferi palGetBufferi
390 #define alGetBuffer3i palGetBuffer3i
391 #define alGetBufferiv palGetBufferiv
392 #define alBufferData palBufferData
393 #define alDopplerFactor palDopplerFactor
394 #define alDopplerVelocity palDopplerVelocity
395 #define alDistanceModel palDistanceModel
396 #define alSpeedOfSound palSpeedOfSound
398 /* Extension functions. Technically device- or driver-specific, but as long as
399 * they're pulled from the NULL device it should be routed correctly.
401 extern LPALGENFILTERS palGenFilters
;
402 extern LPALDELETEFILTERS palDeleteFilters
;
403 extern LPALFILTERI palFilteri
;
404 extern LPALFILTERF palFilterf
;
405 extern LPALGENEFFECTS palGenEffects
;
406 extern LPALDELETEEFFECTS palDeleteEffects
;
407 extern LPALEFFECTI palEffecti
;
408 extern LPALEFFECTF palEffectf
;
409 extern LPALEFFECTFV palEffectfv
;
410 extern LPALGENAUXILIARYEFFECTSLOTS palGenAuxiliaryEffectSlots
;
411 extern LPALDELETEAUXILIARYEFFECTSLOTS palDeleteAuxiliaryEffectSlots
;
412 extern LPALAUXILIARYEFFECTSLOTI palAuxiliaryEffectSloti
;
413 extern LPALAUXILIARYEFFECTSLOTF palAuxiliaryEffectSlotf
;
414 extern LPALDEFERUPDATESSOFT palDeferUpdatesSOFT
;
415 extern LPALPROCESSUPDATESSOFT palProcessUpdatesSOFT
;
416 extern LPALBUFFERSTORAGESOFT palBufferStorageSOFT
;
417 extern LPALMAPBUFFERSOFT palMapBufferSOFT
;
418 extern LPALUNMAPBUFFERSOFT palUnmapBufferSOFT
;
419 extern LPALFLUSHMAPPEDBUFFERSOFT palFlushMappedBufferSOFT
;
421 #define alGenFilters palGenFilters
422 #define alDeleteFilters palDeleteFilters
423 #define alFilteri palFilteri
424 #define alFilterf palFilterf
425 #define alGenEffects palGenEffects
426 #define alDeleteEffects palDeleteEffects
427 #define alEffecti palEffecti
428 #define alEffectf palEffectf
429 #define alEffectfv palEffectfv
430 #define alGenAuxiliaryEffectSlots palGenAuxiliaryEffectSlots
431 #define alDeleteAuxiliaryEffectSlots palDeleteAuxiliaryEffectSlots
432 #define alAuxiliaryEffectSloti palAuxiliaryEffectSloti
433 #define alAuxiliaryEffectSlotf palAuxiliaryEffectSlotf
434 #define alDeferUpdatesSOFT palDeferUpdatesSOFT
435 #define alProcessUpdatesSOFT palProcessUpdatesSOFT
436 #define alBufferStorageSOFT palBufferStorageSOFT
437 #define alMapBufferSOFT palMapBufferSOFT
438 #define alUnmapBufferSOFT palUnmapBufferSOFT
439 #define alFlushMappedBufferSOFT palFlushMappedBufferSOFT
442 #ifndef E_PROP_ID_UNSUPPORTED
443 #define E_PROP_ID_UNSUPPORTED ((HRESULT)0x80070490)
446 /* OpenAL only allows for 1 single access to the device at the same time */
447 extern CRITICAL_SECTION openal_crst
;
449 extern LPALCMAKECONTEXTCURRENT set_context
;
450 extern LPALCGETCURRENTCONTEXT get_context
;
451 extern BOOL local_contexts
;
454 extern DWORD TlsThreadPtr
;
455 extern void (*EnterALSection
)(ALCcontext
*ctx
);
456 extern void (*LeaveALSection
)(void);
459 typedef struct DSDevice DSDevice
;
460 typedef struct DSPrimary DSPrimary
;
461 typedef struct DSBuffer DSBuffer
;
468 SOFT_DEFERRED_UPDATES
,
469 SOFT_SOURCE_SPATIALIZE
,
470 SOFTX_FILTER_GAIN_EX
,
477 #define BITFIELD_ARRAY_SIZE(b) ((b+7) / 8)
478 #define BITFIELD_SET(arr, b) ((arr)[(b)>>3] |= 1<<((b)&7))
479 #define BITFIELD_TEST(arr, b) ((arr)[(b)>>3] & (1<<((b)&7)))
481 /* Maximum number of emulated hardware buffers. May be less depending on source
484 #define MAX_HWBUFFERS 256
486 #define MAX_SOURCES 512
487 typedef struct SourceCollection
{
488 DWORD maxhw_alloc
, availhw_num
;
489 DWORD maxsw_alloc
, availsw_num
;
490 /* "Hardware" sources start at 0, and "software" sources start at
491 * maxhw_alloc. Total sources is maxhw_alloc+maxsw_alloc.
493 ALuint ids
[MAX_SOURCES
];
496 typedef struct DeviceShare
{
504 ALboolean Exts
[BITFIELD_ARRAY_SIZE(MAX_EXTENSIONS
)];
506 CRITICAL_SECTION crst
;
508 SourceCollection sources
;
510 ALuint auxslot
[EAX_MAX_FXSLOTS
];
517 volatile LONG quit_now
;
520 DSPrimary
**primaries
;
523 DWORD speaker_config
;
526 #define HAS_EXTENSION(s, e) BITFIELD_TEST((s)->Exts, e)
529 typedef struct DSData
{
534 /* Lock was called and unlock isn't? */
537 WAVEFORMATEXTENSIBLE format
;
545 /* Amount of buffers that have to be queued when
546 * bufferdatastatic and buffersubdata are not available */
549 union BufferParamFlags
{
554 BOOL cone_angles
: 1;
555 BOOL cone_orient
: 1;
556 BOOL cone_outsidevolume
: 1;
557 BOOL min_distance
: 1;
558 BOOL max_distance
: 1;
563 BOOL send0_filter
: 1;
564 BOOL send1_filter
: 1;
567 BOOL room_rolloff
: 1;
568 BOOL cone_outsidevolumehf
: 1;
579 FXSLOT_TARGET_PRIMARY
,
584 IDirectSoundBuffer8 IDirectSoundBuffer8_iface
;
585 IDirectSound3DBuffer IDirectSound3DBuffer_iface
;
586 IDirectSoundNotify IDirectSoundNotify_iface
;
587 IKsPropertySet IKsPropertySet_iface
;
589 LONG ref
, ds3d_ref
, not_ref
, prop_ref
;
595 /* From the primary */
605 ALuint stream_bids
[QBUFFERS
];
612 /* Must be 0 (deferred, not yet placed), DSBSTATUS_LOCSOFTWARE, or
613 * DSBSTATUS_LOCHARDWARE.
621 EAXSOURCEPROPERTIES eax
;
622 /* See FXSLOT_TARGET enums */
623 DWORD fxslot_targets
[EAX_MAX_ACTIVE_FXSLOTS
];
624 float eax1_reverbmix
; /* Mirrored by eax.lRoom. */
628 EAXSOURCEPROPERTIES eax
;
629 DWORD fxslot_targets
[EAX_MAX_ACTIVE_FXSLOTS
];
630 float eax1_reverbmix
;
632 union BufferParamFlags dirty
;
634 ALfloat filter_mBLimit
;
635 ALuint filter
[1+EAX_MAX_ACTIVE_FXSLOTS
];
637 DWORD nnotify
, lastpos
;
638 DSBPOSITIONNOTIFY
*notify
;
642 struct DSBufferGroup
{
649 FXSLOT_EFFECT_REVERB
,
650 FXSLOT_EFFECT_CHORUS
,
656 /* See FXSLOT_EFFECT enums */
659 EAXREVERBPROPERTIES reverb
;
660 EAXCHORUSPROPERTIES chorus
;
662 EAXFXSLOTPROPERTIES props
;
665 union PrimaryParamFlags
{
670 LONG orientation
: 1;
671 LONG distancefactor
: 1;
672 LONG rollofffactor
: 1;
673 LONG dopplerfactor
: 1;
675 LONG prim_slotid
: 1;
676 LONG distancefactor2
: 1;
677 LONG air_absorbhf
: 1;
678 LONG hfreference
: 1;
680 /* Can't use a proper array for the fxslots here since this is a
681 * bitfield, and each slot only needs 4 bits. So make a sub-bitfield
682 * with macros to access it.
684 #define FXSLOT_EFFECT_BIT 0
685 #define FXSLOT_VOL_BIT 1
686 #define FXSLOT_LOCK_BIT 2
687 #define FXSLOT_FLAGS_BIT 3
688 #define FXSLOT_NUM_BITS 4
690 #define FXSLOT_IS_DIRTY(_flags, _idx, _bit) \
691 (((_flags).fxslots & (1 << ((_idx)*FXSLOT_NUM_BITS + (_bit)))) != 0)
692 #define FXSLOT_SET_DIRTY(_flags, _idx, _bit) \
693 ((_flags).fxslots |= (1 << ((_idx)*FXSLOT_NUM_BITS + (_bit))))
695 LONG fxslots
: (FXSLOT_NUM_BITS
*EAX_MAX_FXSLOTS
);
700 IDirectSoundBuffer IDirectSoundBuffer_iface
;
701 IDirectSound3DListener IDirectSound3DListener_iface
;
702 IKsPropertySet IKsPropertySet_iface
;
704 LONG ref
, ds3d_ref
, prop_ref
;
705 IDirectSoundBuffer
*write_emu
;
709 /* Taken from the share */
712 ALuint auxslot
[EAX_MAX_FXSLOTS
];
717 WAVEFORMATEXTENSIBLE format
;
720 DWORD nnotifies
, sizenotifies
;
722 ALfloat filter_mBLimit
;
724 ALuint effect
[EAX_MAX_FXSLOTS
];
730 EAXCONTEXTPROPERTIES ctx
;
731 struct FXSlot fxslot
[EAX_MAX_FXSLOTS
];
732 float eax1_volume
; /* Mirrored by fxslot[0].fx.reverb.lRoom. */
733 float eax1_dampening
; /* Not used. */
737 EAXCONTEXTPROPERTIES ctx
;
738 struct FXSlot fxslot
[EAX_MAX_FXSLOTS
];
740 float eax1_dampening
;
742 union PrimaryParamFlags dirty
;
744 DWORD NumBufferGroups
;
745 struct DSBufferGroup
*BufferGroups
;
749 /* Device implementation */
751 IDirectSound8 IDirectSound8_iface
;
752 IDirectSound IDirectSound_iface
;
753 IUnknown IUnknown_iface
;
755 LONG ref
, unkref
, dsref
;
760 /* Taken from the share */
769 DEFINE_GUID(GUID_NULL
, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
771 DEFINE_GUID(CLSID_DirectSoundPrivate
, 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca);
773 DEFINE_GUID(DSPROPSETID_DirectSoundDevice
, 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca);
775 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM
, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
776 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
778 DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName
, 0xa45c254e,0xdf1c,0x4efd,0x80,0x20,0x67,0xd1,0x46,0xa8,0x50,0xe0, 14);
781 HRESULT
DSPrimary_PreInit(DSPrimary
*prim
, DSDevice
*parent
);
782 void DSPrimary_Clear(DSPrimary
*prim
);
783 void DSPrimary_triggernots(DSPrimary
*prim
);
784 void DSPrimary_streamfeeder(DSPrimary
*prim
, BYTE
*scratch_mem
/*2K non-permanent memory*/);
785 HRESULT WINAPI
DSPrimary_Initialize(IDirectSoundBuffer
*iface
, IDirectSound
*ds
, const DSBUFFERDESC
*desc
);
786 HRESULT WINAPI
DSPrimary3D_CommitDeferredSettings(IDirectSound3DListener
*iface
);
788 HRESULT
DSBuffer_Create(DSBuffer
**ppv
, DSPrimary
*parent
, IDirectSoundBuffer
*orig
);
789 void DSBuffer_Destroy(DSBuffer
*buf
);
790 HRESULT
DSBuffer_GetInterface(DSBuffer
*buf
, REFIID riid
, void **ppv
);
791 void DSBuffer_SetParams(DSBuffer
*buffer
, const DS3DBUFFER
*params
, LONG flags
);
792 HRESULT WINAPI
DSBuffer_GetCurrentPosition(IDirectSoundBuffer8
*iface
, DWORD
*playpos
, DWORD
*curpos
);
793 HRESULT WINAPI
DSBuffer_GetStatus(IDirectSoundBuffer8
*iface
, DWORD
*status
);
794 HRESULT WINAPI
DSBuffer_Initialize(IDirectSoundBuffer8
*iface
, IDirectSound
*ds
, const DSBUFFERDESC
*desc
);
796 HRESULT
EAX1_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
);
797 HRESULT
EAX1_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
798 HRESULT
EAX1_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
799 HRESULT
EAX1Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
);
800 HRESULT
EAX1Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
801 HRESULT
EAX1Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
803 HRESULT
EAX2_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
);
804 HRESULT
EAX2_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
805 HRESULT
EAX2_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
806 HRESULT
EAX2Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
);
807 HRESULT
EAX2Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
808 HRESULT
EAX2Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
810 HRESULT
EAX3_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
);
811 HRESULT
EAX3_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
812 HRESULT
EAX3_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
813 HRESULT
EAX3Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
);
814 HRESULT
EAX3Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
);
815 HRESULT
EAX3Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
);
818 static inline LONG
gain_to_mB(float gain
)
820 return (gain
> 1e-5f
) ? (LONG
)(log10f(gain
) * 2000.0f
) : -10000l;
822 static inline float mB_to_gain(float millibels
)
824 return (millibels
> -10000.0f
) ? powf(10.0f
, millibels
/2000.0f
) : 0.0f
;
827 static inline LONG
clampI(LONG val
, LONG minval
, LONG maxval
)
829 if(val
>= maxval
) return maxval
;
830 if(val
<= minval
) return minval
;
833 static inline ULONG
clampU(ULONG val
, ULONG minval
, ULONG maxval
)
835 if(val
>= maxval
) return maxval
;
836 if(val
<= minval
) return minval
;
839 static inline FLOAT
clampF(FLOAT val
, FLOAT minval
, FLOAT maxval
)
841 if(val
>= maxval
) return maxval
;
842 if(val
<= minval
) return minval
;
847 #define checkALError() do { \
848 ALenum err = alGetError(); \
849 if(err != AL_NO_ERROR) \
850 ERR(">>>>>>>>>>>> Received AL error %#x on context %p, %s:%u\n", \
851 err, get_context(), __FUNCTION__, __LINE__); \
854 #define checkALCError(dev) do { \
855 ALenum err = alcGetError(dev); \
856 if(err != ALC_NO_ERROR) \
857 ERR(">>>>>>>>>>>> Received ALC error %#x on device %p, %s:%u\n", \
858 err, dev, __FUNCTION__, __LINE__); \
862 #define setALContext(actx) EnterALSection(actx)
863 #define popALContext() LeaveALSection()
866 HRESULT
DSOUND_Create(REFIID riid
, void **ppDS
);
867 HRESULT
DSOUND_Create8(REFIID riid
, void **ppDS
);
868 HRESULT
DSOUND_FullDuplexCreate(REFIID riid
, void **ppDSFD
);
869 HRESULT
IKsPrivatePropertySetImpl_Create(REFIID riid
, void **piks
);
870 HRESULT
DSOUND_CaptureCreate(REFIID riid
, void **ppDSC
);
871 HRESULT
DSOUND_CaptureCreate8(REFIID riid
, void **ppDSC
);
873 typedef BOOL (CALLBACK
*PRVTENUMCALLBACK
)(EDataFlow flow
, LPGUID guid
, LPCWSTR descW
, LPCWSTR modW
, LPVOID data
);
874 HRESULT
enumerate_mmdevices(EDataFlow flow
, PRVTENUMCALLBACK cb
, void *user
);
875 HRESULT
get_mmdevice(EDataFlow flow
, const GUID
*tgt
, IMMDevice
**device
);
877 extern const WCHAR aldriver_name
[];