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