3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2002 TransGaming Technologies, Inc.
6 * Copyright 2004 Robert Reif
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
35 #include "wine/debug.h"
38 #include "dsound_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
42 static ULONG WINAPI
IDirectSound_IUnknown_AddRef(LPUNKNOWN iface
);
43 static ULONG WINAPI
IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface
);
44 static ULONG WINAPI
IDirectSound8_IUnknown_AddRef(LPUNKNOWN iface
);
45 static ULONG WINAPI
IDirectSound8_IDirectSound_AddRef(LPDIRECTSOUND iface
);
46 static ULONG WINAPI
IDirectSound8_IDirectSound8_AddRef(LPDIRECTSOUND8 iface
);
48 static HRESULT
DirectSoundDevice_Create(DirectSoundDevice
** ppDevice
);
49 static ULONG
DirectSoundDevice_AddRef(DirectSoundDevice
* device
);
50 static ULONG
DirectSoundDevice_Release(DirectSoundDevice
* device
);
52 static const char * dumpCooperativeLevel(DWORD level
)
54 static char unknown
[32];
55 #define LE(x) case x: return #x
60 LE(DSSCL_WRITEPRIMARY
);
63 sprintf(unknown
, "Unknown(%08lx)", level
);
67 static void _dump_DSCAPS(DWORD xmask
) {
72 #define FE(x) { x, #x },
73 FE(DSCAPS_PRIMARYMONO
)
74 FE(DSCAPS_PRIMARYSTEREO
)
75 FE(DSCAPS_PRIMARY8BIT
)
76 FE(DSCAPS_PRIMARY16BIT
)
77 FE(DSCAPS_CONTINUOUSRATE
)
80 FE(DSCAPS_SECONDARYMONO
)
81 FE(DSCAPS_SECONDARYSTEREO
)
82 FE(DSCAPS_SECONDARY8BIT
)
83 FE(DSCAPS_SECONDARY16BIT
)
88 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
89 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
)
90 DPRINTF("%s ",flags
[i
].name
);
93 static void _dump_DSBCAPS(DWORD xmask
) {
98 #define FE(x) { x, #x },
99 FE(DSBCAPS_PRIMARYBUFFER
)
101 FE(DSBCAPS_LOCHARDWARE
)
102 FE(DSBCAPS_LOCSOFTWARE
)
104 FE(DSBCAPS_CTRLFREQUENCY
)
106 FE(DSBCAPS_CTRLVOLUME
)
107 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
108 FE(DSBCAPS_STICKYFOCUS
)
109 FE(DSBCAPS_GLOBALFOCUS
)
110 FE(DSBCAPS_GETCURRENTPOSITION2
)
111 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
116 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
117 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
)
118 DPRINTF("%s ",flags
[i
].name
);
121 /*******************************************************************************
122 * IDirectSoundImpl_DirectSound
124 static HRESULT WINAPI
IDirectSoundImpl_QueryInterface(
125 LPDIRECTSOUND8 iface
,
129 TRACE("(%p,%s,%p)\n",iface
,debugstr_guid(riid
),ppobj
);
130 FIXME("shouldn't be called directly\n");
131 return E_NOINTERFACE
;
134 static HRESULT WINAPI
DSOUND_QueryInterface(
135 LPDIRECTSOUND8 iface
,
139 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
140 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
143 WARN("invalid parameter\n");
147 if (IsEqualIID(riid
, &IID_IUnknown
)) {
148 if (!This
->pUnknown
) {
149 IDirectSound_IUnknown_Create(iface
, &This
->pUnknown
);
150 if (!This
->pUnknown
) {
151 WARN("IDirectSound_IUnknown_Create() failed\n");
153 return E_NOINTERFACE
;
156 IDirectSound_IUnknown_AddRef(This
->pUnknown
);
157 *ppobj
= This
->pUnknown
;
159 } else if (IsEqualIID(riid
, &IID_IDirectSound
)) {
161 IDirectSound_IDirectSound_Create(iface
, &This
->pDS
);
163 WARN("IDirectSound_IDirectSound_Create() failed\n");
165 return E_NOINTERFACE
;
168 IDirectSound_IDirectSound_AddRef(This
->pDS
);
174 WARN("Unknown IID %s\n",debugstr_guid(riid
));
175 return E_NOINTERFACE
;
178 static HRESULT WINAPI
DSOUND_QueryInterface8(
179 LPDIRECTSOUND8 iface
,
183 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
184 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
187 WARN("invalid parameter\n");
191 if (IsEqualIID(riid
, &IID_IUnknown
)) {
192 if (!This
->pUnknown
) {
193 IDirectSound8_IUnknown_Create(iface
, &This
->pUnknown
);
194 if (!This
->pUnknown
) {
195 WARN("IDirectSound8_IUnknown_Create() failed\n");
197 return E_NOINTERFACE
;
200 IDirectSound8_IUnknown_AddRef(This
->pUnknown
);
201 *ppobj
= This
->pUnknown
;
203 } else if (IsEqualIID(riid
, &IID_IDirectSound
)) {
205 IDirectSound8_IDirectSound_Create(iface
, &This
->pDS
);
207 WARN("IDirectSound8_IDirectSound_Create() failed\n");
209 return E_NOINTERFACE
;
212 IDirectSound8_IDirectSound_AddRef(This
->pDS
);
215 } else if (IsEqualIID(riid
, &IID_IDirectSound8
)) {
217 IDirectSound8_IDirectSound8_Create(iface
, &This
->pDS8
);
219 WARN("IDirectSound8_IDirectSound8_Create() failed\n");
221 return E_NOINTERFACE
;
224 IDirectSound8_IDirectSound8_AddRef(This
->pDS8
);
230 WARN("Unknown IID %s\n",debugstr_guid(riid
));
231 return E_NOINTERFACE
;
234 static ULONG WINAPI
IDirectSoundImpl_AddRef(
235 LPDIRECTSOUND8 iface
)
237 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
238 ULONG ref
= InterlockedIncrement(&(This
->ref
));
239 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
243 static ULONG WINAPI
IDirectSoundImpl_Release(
244 LPDIRECTSOUND8 iface
)
246 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
247 ULONG ref
= InterlockedDecrement(&(This
->ref
));
248 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
252 if (DirectSoundDevice_Release(This
->device
) != 0) {
253 /* device not released so make sure primary reference to This removed */
254 if (This
->device
->primary
)
255 This
->device
->primary
->dsound
= NULL
;
258 HeapFree(GetProcessHeap(),0,This
);
259 TRACE("(%p) released\n", This
);
264 static HRESULT WINAPI
IDirectSoundImpl_CreateSoundBuffer(
265 LPDIRECTSOUND8 iface
,
266 LPCDSBUFFERDESC dsbd
,
267 LPLPDIRECTSOUNDBUFFER ppdsb
,
270 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
271 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
272 FIXME("shouldn't be called directly\n");
273 return DSERR_GENERIC
;
276 static HRESULT WINAPI
DSOUND_CreateSoundBuffer(
277 LPDIRECTSOUND8 iface
,
278 LPCDSBUFFERDESC dsbd
,
279 LPLPDIRECTSOUNDBUFFER ppdsb
,
283 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
284 HRESULT hres
= DS_OK
;
285 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
288 WARN("invalid parameter: This == NULL\n");
289 return DSERR_INVALIDPARAM
;
292 if (This
->device
== NULL
) {
293 WARN("not initialized\n");
294 return DSERR_UNINITIALIZED
;
298 WARN("invalid parameter: dsbd == NULL\n");
299 return DSERR_INVALIDPARAM
;
302 if (dsbd
->dwSize
!= sizeof(DSBUFFERDESC
) &&
303 dsbd
->dwSize
!= sizeof(DSBUFFERDESC1
)) {
304 WARN("invalid parameter: dsbd\n");
305 return DSERR_INVALIDPARAM
;
309 WARN("invalid parameter: ppdsb == NULL\n");
310 return DSERR_INVALIDPARAM
;
313 if (TRACE_ON(dsound
)) {
314 TRACE("(structsize=%ld)\n",dsbd
->dwSize
);
315 TRACE("(flags=0x%08lx:\n",dsbd
->dwFlags
);
316 _dump_DSBCAPS(dsbd
->dwFlags
);
318 TRACE("(bufferbytes=%ld)\n",dsbd
->dwBufferBytes
);
319 TRACE("(lpwfxFormat=%p)\n",dsbd
->lpwfxFormat
);
322 if (dsbd
->dwFlags
& DSBCAPS_PRIMARYBUFFER
) {
323 if (dsbd
->lpwfxFormat
!= NULL
) {
324 WARN("invalid parameter: dsbd->lpwfxFormat must be NULL for "
326 return DSERR_INVALIDPARAM
;
329 if (This
->device
->primary
) {
330 WARN("Primary Buffer already created\n");
331 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8
)(This
->device
->primary
));
332 *ppdsb
= (LPDIRECTSOUNDBUFFER
)(This
->device
->primary
);
333 This
->device
->primary
->dsound
= This
;
335 This
->device
->dsbd
= *dsbd
;
336 hres
= PrimaryBufferImpl_Create(This
, (PrimaryBufferImpl
**)&(This
->device
->primary
), &(This
->device
->dsbd
));
337 if (This
->device
->primary
) {
338 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8
)(This
->device
->primary
));
339 *ppdsb
= (LPDIRECTSOUNDBUFFER
)(This
->device
->primary
);
341 WARN("PrimaryBufferImpl_Create failed\n");
344 IDirectSoundBufferImpl
* dsb
;
346 if (dsbd
->lpwfxFormat
== NULL
) {
347 WARN("invalid parameter: dsbd->lpwfxFormat can't be NULL for "
348 "secondary buffer\n");
349 return DSERR_INVALIDPARAM
;
352 TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
353 "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
354 dsbd
->lpwfxFormat
->wFormatTag
, dsbd
->lpwfxFormat
->nChannels
,
355 dsbd
->lpwfxFormat
->nSamplesPerSec
,
356 dsbd
->lpwfxFormat
->nAvgBytesPerSec
,
357 dsbd
->lpwfxFormat
->nBlockAlign
,
358 dsbd
->lpwfxFormat
->wBitsPerSample
, dsbd
->lpwfxFormat
->cbSize
);
360 if (from8
&& (dsbd
->dwFlags
& DSBCAPS_CTRL3D
) && (dsbd
->lpwfxFormat
->nChannels
!= 1)) {
361 WARN("invalid parameter: 3D buffer format must be mono\n");
362 return DSERR_INVALIDPARAM
;
365 hres
= IDirectSoundBufferImpl_Create(This
, (IDirectSoundBufferImpl
**)&dsb
, dsbd
);
367 hres
= SecondaryBufferImpl_Create(dsb
, (SecondaryBufferImpl
**)ppdsb
);
369 dsb
->dsb
= (SecondaryBufferImpl
*)*ppdsb
;
370 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER
)*ppdsb
);
372 WARN("SecondaryBufferImpl_Create failed\n");
374 WARN("IDirectSoundBufferImpl_Create failed\n");
380 static HRESULT WINAPI
IDirectSoundImpl_GetCaps(
381 LPDIRECTSOUND8 iface
,
384 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
385 DirectSoundDevice
*device
;
386 TRACE("(%p,%p)\n",This
,lpDSCaps
);
389 WARN("invalid parameter: This == NULL\n");
390 return DSERR_INVALIDPARAM
;
393 device
= This
->device
;
395 if (device
== NULL
) {
396 WARN("not initialized\n");
397 return DSERR_UNINITIALIZED
;
400 if (lpDSCaps
== NULL
) {
401 WARN("invalid parameter: lpDSCaps = NULL\n");
402 return DSERR_INVALIDPARAM
;
405 /* check if there is enough room */
406 if (lpDSCaps
->dwSize
< sizeof(*lpDSCaps
)) {
407 WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
408 lpDSCaps
->dwSize
, sizeof(*lpDSCaps
));
409 return DSERR_INVALIDPARAM
;
412 lpDSCaps
->dwFlags
= device
->drvcaps
.dwFlags
;
413 if (TRACE_ON(dsound
)) {
414 TRACE("(flags=0x%08lx:\n",lpDSCaps
->dwFlags
);
415 _dump_DSCAPS(lpDSCaps
->dwFlags
);
418 lpDSCaps
->dwMinSecondarySampleRate
= device
->drvcaps
.dwMinSecondarySampleRate
;
419 lpDSCaps
->dwMaxSecondarySampleRate
= device
->drvcaps
.dwMaxSecondarySampleRate
;
420 lpDSCaps
->dwPrimaryBuffers
= device
->drvcaps
.dwPrimaryBuffers
;
421 lpDSCaps
->dwMaxHwMixingAllBuffers
= device
->drvcaps
.dwMaxHwMixingAllBuffers
;
422 lpDSCaps
->dwMaxHwMixingStaticBuffers
= device
->drvcaps
.dwMaxHwMixingStaticBuffers
;
423 lpDSCaps
->dwMaxHwMixingStreamingBuffers
= device
->drvcaps
.dwMaxHwMixingStreamingBuffers
;
424 lpDSCaps
->dwFreeHwMixingAllBuffers
= device
->drvcaps
.dwFreeHwMixingAllBuffers
;
425 lpDSCaps
->dwFreeHwMixingStaticBuffers
= device
->drvcaps
.dwFreeHwMixingStaticBuffers
;
426 lpDSCaps
->dwFreeHwMixingStreamingBuffers
= device
->drvcaps
.dwFreeHwMixingStreamingBuffers
;
427 lpDSCaps
->dwMaxHw3DAllBuffers
= device
->drvcaps
.dwMaxHw3DAllBuffers
;
428 lpDSCaps
->dwMaxHw3DStaticBuffers
= device
->drvcaps
.dwMaxHw3DStaticBuffers
;
429 lpDSCaps
->dwMaxHw3DStreamingBuffers
= device
->drvcaps
.dwMaxHw3DStreamingBuffers
;
430 lpDSCaps
->dwFreeHw3DAllBuffers
= device
->drvcaps
.dwFreeHw3DAllBuffers
;
431 lpDSCaps
->dwFreeHw3DStaticBuffers
= device
->drvcaps
.dwFreeHw3DStaticBuffers
;
432 lpDSCaps
->dwFreeHw3DStreamingBuffers
= device
->drvcaps
.dwFreeHw3DStreamingBuffers
;
433 lpDSCaps
->dwTotalHwMemBytes
= device
->drvcaps
.dwTotalHwMemBytes
;
434 lpDSCaps
->dwFreeHwMemBytes
= device
->drvcaps
.dwFreeHwMemBytes
;
435 lpDSCaps
->dwMaxContigFreeHwMemBytes
= device
->drvcaps
.dwMaxContigFreeHwMemBytes
;
437 /* driver doesn't have these */
438 lpDSCaps
->dwUnlockTransferRateHwBuffers
= 4096; /* But we have none... */
439 lpDSCaps
->dwPlayCpuOverheadSwBuffers
= 1; /* 1% */
444 static HRESULT WINAPI
IDirectSoundImpl_DuplicateSoundBuffer(
445 LPDIRECTSOUND8 iface
,
446 LPDIRECTSOUNDBUFFER psb
,
447 LPLPDIRECTSOUNDBUFFER ppdsb
)
449 IDirectSoundBufferImpl
* pdsb
;
450 IDirectSoundBufferImpl
* dsb
;
451 HRESULT hres
= DS_OK
;
453 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
455 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
458 WARN("invalid parameter: This == NULL\n");
459 return DSERR_INVALIDPARAM
;
462 if (This
->device
== NULL
) {
463 WARN("not initialized\n");
464 return DSERR_UNINITIALIZED
;
468 WARN("invalid parameter: psb == NULL\n");
469 return DSERR_INVALIDPARAM
;
473 WARN("invalid parameter: ppdsb == NULL\n");
474 return DSERR_INVALIDPARAM
;
477 /* FIXME: hack to make sure we have a secondary buffer */
478 if ((IDirectSoundImpl
*)((SecondaryBufferImpl
*)psb
)->dsb
== This
) {
479 WARN("trying to duplicate primary buffer\n");
481 return DSERR_INVALIDCALL
;
484 pdsb
= ((SecondaryBufferImpl
*)psb
)->dsb
;
486 dsb
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(*dsb
));
489 WARN("out of memory\n");
491 return DSERR_OUTOFMEMORY
;
494 CopyMemory(dsb
, pdsb
, sizeof(IDirectSoundBufferImpl
));
497 TRACE("duplicating hardware buffer\n");
499 hres
= IDsDriver_DuplicateSoundBuffer(This
->device
->driver
, pdsb
->hwbuf
, (LPVOID
*)&dsb
->hwbuf
);
501 TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
503 /* allocate buffer */
504 if (This
->device
->drvdesc
.dwFlags
& DSDDESC_USESYSTEMMEMORY
) {
505 dsb
->buffer
= HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb
->buffer
)));
506 if (dsb
->buffer
== NULL
) {
507 WARN("out of memory\n");
508 HeapFree(GetProcessHeap(),0,dsb
);
510 return DSERR_OUTOFMEMORY
;
513 dsb
->buffer
->memory
= HeapAlloc(GetProcessHeap(),0,dsb
->buflen
);
514 if (dsb
->buffer
->memory
== NULL
) {
515 WARN("out of memory\n");
516 HeapFree(GetProcessHeap(),0,dsb
->buffer
);
517 HeapFree(GetProcessHeap(),0,dsb
);
519 return DSERR_OUTOFMEMORY
;
521 dsb
->buffer
->ref
= 1;
523 /* FIXME: copy buffer ? */
532 dsb
->state
= STATE_STOPPED
;
537 dsb
->iks
= NULL
; /* FIXME? */
540 /* variable sized struct so calculate size based on format */
541 size
= sizeof(WAVEFORMATEX
) + pdsb
->pwfx
->cbSize
;
543 dsb
->pwfx
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
);
544 if (dsb
->pwfx
== NULL
) {
545 WARN("out of memory\n");
546 HeapFree(GetProcessHeap(),0,dsb
->buffer
);
547 HeapFree(GetProcessHeap(),0,dsb
);
549 return DSERR_OUTOFMEMORY
;
552 CopyMemory(dsb
->pwfx
, pdsb
->pwfx
, size
);
554 InitializeCriticalSection(&(dsb
->lock
));
555 dsb
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)"DSOUNDBUFFER_lock";
557 /* register buffer */
558 hres
= DSOUND_AddBuffer(This
, dsb
);
560 IDirectSoundBuffer8_Release(psb
);
561 dsb
->lock
.DebugInfo
->Spare
[0] = 0;
562 DeleteCriticalSection(&(dsb
->lock
));
563 HeapFree(GetProcessHeap(),0,dsb
->buffer
);
564 HeapFree(GetProcessHeap(),0,dsb
->pwfx
);
565 HeapFree(GetProcessHeap(),0,dsb
);
568 hres
= SecondaryBufferImpl_Create(dsb
, (SecondaryBufferImpl
**)ppdsb
);
570 dsb
->dsb
= (SecondaryBufferImpl
*)*ppdsb
;
571 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8
)*ppdsb
);
573 WARN("SecondaryBufferImpl_Create failed\n");
579 static HRESULT WINAPI
IDirectSoundImpl_SetCooperativeLevel(
580 LPDIRECTSOUND8 iface
,
584 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
585 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
587 if (level
==DSSCL_PRIORITY
|| level
==DSSCL_EXCLUSIVE
) {
588 WARN("level=%s not fully supported\n",
589 level
==DSSCL_PRIORITY
? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
591 This
->device
->priolevel
= level
;
595 static HRESULT WINAPI
IDirectSoundImpl_Compact(
596 LPDIRECTSOUND8 iface
)
598 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
599 TRACE("(%p)\n",This
);
601 if (This
->device
== NULL
) {
602 WARN("not initialized\n");
603 return DSERR_UNINITIALIZED
;
606 if (This
->device
->priolevel
!= DSSCL_PRIORITY
) {
607 WARN("incorrect priority level\n");
608 return DSERR_PRIOLEVELNEEDED
;
614 static HRESULT WINAPI
IDirectSoundImpl_GetSpeakerConfig(
615 LPDIRECTSOUND8 iface
,
616 LPDWORD lpdwSpeakerConfig
)
618 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
619 TRACE("(%p, %p)\n",This
,lpdwSpeakerConfig
);
621 if (This
->device
== NULL
) {
622 WARN("not initialized\n");
623 return DSERR_UNINITIALIZED
;
626 if (lpdwSpeakerConfig
== NULL
) {
627 WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
628 return DSERR_INVALIDPARAM
;
631 WARN("not fully functional\n");
632 *lpdwSpeakerConfig
= This
->device
->speaker_config
;
636 static HRESULT WINAPI
IDirectSoundImpl_SetSpeakerConfig(
637 LPDIRECTSOUND8 iface
,
640 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
641 TRACE("(%p,0x%08lx)\n",This
,config
);
643 if (This
->device
== NULL
) {
644 WARN("not initialized\n");
645 return DSERR_UNINITIALIZED
;
648 This
->device
->speaker_config
= config
;
649 WARN("not fully functional\n");
653 static HRESULT WINAPI
IDirectSoundImpl_Initialize(
654 LPDIRECTSOUND8 iface
,
657 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
658 DirectSoundDevice
*device
= This
->device
;
661 BOOLEAN found
= FALSE
;
663 TRACE("(%p,%s)\n",This
,debugstr_guid(lpcGUID
));
665 if (device
!= NULL
) {
666 WARN("already initialized\n");
667 return DSERR_ALREADYINITIALIZED
;
670 /* Default device? */
671 if (!lpcGUID
|| IsEqualGUID(lpcGUID
, &GUID_NULL
))
672 lpcGUID
= &DSDEVID_DefaultPlayback
;
674 if (GetDeviceID(lpcGUID
, &devGUID
) != DS_OK
) {
675 WARN("invalid parameter: lpcGUID\n");
676 return DSERR_INVALIDPARAM
;
679 /* Enumerate WINMM audio devices and find the one we want */
680 wodn
= waveOutGetNumDevs();
683 return DSERR_NODRIVER
;
686 for (wod
=0; wod
<wodn
; wod
++) {
687 if (IsEqualGUID( &devGUID
, &DSOUND_renderer_guids
[wod
])) {
693 if (found
== FALSE
) {
694 WARN("No device found matching given ID!\n");
695 return DSERR_NODRIVER
;
698 if (DSOUND_renderer
[wod
]) {
699 if (IsEqualGUID(&devGUID
, &DSOUND_renderer
[wod
]->guid
)) {
700 device
= DSOUND_renderer
[wod
];
701 DirectSoundDevice_AddRef(device
);
702 This
->device
= device
;
705 ERR("device GUID doesn't match\n");
710 hr
= DirectSoundDevice_Create(&(device
));
712 WARN("DirectSoundDevice_Create failed\n");
717 This
->device
= device
;
718 device
->guid
= devGUID
;
720 /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
721 waveOutMessage((HWAVEOUT
)wod
, DRV_QUERYDSOUNDIFACE
, (DWORD_PTR
)&device
->driver
, 0);
723 /* Disable the direct sound driver to force emulation if requested. */
724 if (ds_hw_accel
== DS_HW_ACCEL_EMULATION
)
725 device
->driver
= NULL
;
727 /* Get driver description */
728 if (device
->driver
) {
729 hr
= IDsDriver_GetDriverDesc(device
->driver
,&(device
->drvdesc
));
731 WARN("IDsDriver_GetDriverDesc failed\n");
735 /* if no DirectSound interface available, use WINMM API instead */
736 device
->drvdesc
.dwFlags
= DSDDESC_DOMMSYSTEMOPEN
| DSDDESC_DOMMSYSTEMSETFORMAT
;
739 device
->drvdesc
.dnDevNode
= wod
;
741 /* If the driver requests being opened through MMSYSTEM
742 * (which is recommended by the DDK), it is supposed to happen
743 * before the DirectSound interface is opened */
744 if (device
->drvdesc
.dwFlags
& DSDDESC_DOMMSYSTEMOPEN
)
746 DWORD flags
= CALLBACK_FUNCTION
;
748 /* disable direct sound if requested */
749 if (ds_hw_accel
!= DS_HW_ACCEL_EMULATION
)
750 flags
|= WAVE_DIRECTSOUND
;
752 hr
= mmErr(waveOutOpen(&(device
->hwo
),
753 device
->drvdesc
.dnDevNode
, device
->pwfx
,
754 (DWORD_PTR
)DSOUND_callback
, (DWORD
)device
,
757 WARN("waveOutOpen failed\n");
762 if (device
->driver
) {
763 hr
= IDsDriver_Open(device
->driver
);
765 WARN("IDsDriver_Open failed\n");
769 /* the driver is now open, so it's now allowed to call GetCaps */
770 hr
= IDsDriver_GetCaps(device
->driver
,&(device
->drvcaps
));
772 WARN("IDsDriver_GetCaps failed\n");
777 hr
= mmErr(waveOutGetDevCapsA(device
->drvdesc
.dnDevNode
, &woc
, sizeof(woc
)));
779 WARN("waveOutGetDevCaps failed\n");
782 ZeroMemory(&device
->drvcaps
, sizeof(device
->drvcaps
));
783 if ((woc
.dwFormats
& WAVE_FORMAT_1M08
) ||
784 (woc
.dwFormats
& WAVE_FORMAT_2M08
) ||
785 (woc
.dwFormats
& WAVE_FORMAT_4M08
) ||
786 (woc
.dwFormats
& WAVE_FORMAT_48M08
) ||
787 (woc
.dwFormats
& WAVE_FORMAT_96M08
)) {
788 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARY8BIT
;
789 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARYMONO
;
791 if ((woc
.dwFormats
& WAVE_FORMAT_1M16
) ||
792 (woc
.dwFormats
& WAVE_FORMAT_2M16
) ||
793 (woc
.dwFormats
& WAVE_FORMAT_4M16
) ||
794 (woc
.dwFormats
& WAVE_FORMAT_48M16
) ||
795 (woc
.dwFormats
& WAVE_FORMAT_96M16
)) {
796 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARY16BIT
;
797 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARYMONO
;
799 if ((woc
.dwFormats
& WAVE_FORMAT_1S08
) ||
800 (woc
.dwFormats
& WAVE_FORMAT_2S08
) ||
801 (woc
.dwFormats
& WAVE_FORMAT_4S08
) ||
802 (woc
.dwFormats
& WAVE_FORMAT_48S08
) ||
803 (woc
.dwFormats
& WAVE_FORMAT_96S08
)) {
804 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARY8BIT
;
805 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARYSTEREO
;
807 if ((woc
.dwFormats
& WAVE_FORMAT_1S16
) ||
808 (woc
.dwFormats
& WAVE_FORMAT_2S16
) ||
809 (woc
.dwFormats
& WAVE_FORMAT_4S16
) ||
810 (woc
.dwFormats
& WAVE_FORMAT_48S16
) ||
811 (woc
.dwFormats
& WAVE_FORMAT_96S16
)) {
812 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARY16BIT
;
813 device
->drvcaps
.dwFlags
|= DSCAPS_PRIMARYSTEREO
;
816 device
->drvcaps
.dwFlags
|= DSCAPS_EMULDRIVER
;
817 device
->drvcaps
.dwMinSecondarySampleRate
= DSBFREQUENCY_MIN
;
818 device
->drvcaps
.dwMaxSecondarySampleRate
= DSBFREQUENCY_MAX
;
819 device
->drvcaps
.dwPrimaryBuffers
= 1;
822 hr
= DSOUND_PrimaryCreate(device
);
824 DSOUND_renderer
[device
->drvdesc
.dnDevNode
] = device
;
825 timeBeginPeriod(DS_TIME_RES
);
826 DSOUND_renderer
[device
->drvdesc
.dnDevNode
]->timerID
= timeSetEvent(DS_TIME_DEL
, DS_TIME_RES
, DSOUND_timer
,
827 (DWORD_PTR
)DSOUND_renderer
[device
->drvdesc
.dnDevNode
], TIME_PERIODIC
| TIME_CALLBACK_FUNCTION
);
829 WARN("DSOUND_PrimaryCreate failed\n");
835 static HRESULT WINAPI
IDirectSoundImpl_VerifyCertification(
836 LPDIRECTSOUND8 iface
,
837 LPDWORD pdwCertified
)
839 IDirectSoundImpl
*This
= (IDirectSoundImpl
*)iface
;
840 TRACE("(%p, %p)\n",This
,pdwCertified
);
842 if (This
->device
== NULL
) {
843 WARN("not initialized\n");
844 return DSERR_UNINITIALIZED
;
847 if (This
->device
->drvcaps
.dwFlags
& DSCAPS_CERTIFIED
)
848 *pdwCertified
= DS_CERTIFIED
;
850 *pdwCertified
= DS_UNCERTIFIED
;
854 static const IDirectSound8Vtbl IDirectSoundImpl_Vtbl
=
856 IDirectSoundImpl_QueryInterface
,
857 IDirectSoundImpl_AddRef
,
858 IDirectSoundImpl_Release
,
859 IDirectSoundImpl_CreateSoundBuffer
,
860 IDirectSoundImpl_GetCaps
,
861 IDirectSoundImpl_DuplicateSoundBuffer
,
862 IDirectSoundImpl_SetCooperativeLevel
,
863 IDirectSoundImpl_Compact
,
864 IDirectSoundImpl_GetSpeakerConfig
,
865 IDirectSoundImpl_SetSpeakerConfig
,
866 IDirectSoundImpl_Initialize
,
867 IDirectSoundImpl_VerifyCertification
870 static HRESULT
DirectSoundDevice_Create(DirectSoundDevice
** ppDevice
)
872 DirectSoundDevice
* device
;
873 TRACE("(%p)\n", ppDevice
);
875 /* Allocate memory */
876 device
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(DirectSoundDevice
));
877 if (device
== NULL
) {
878 WARN("out of memory\n");
879 return DSERR_OUTOFMEMORY
;
883 device
->driver
= NULL
;
884 device
->priolevel
= DSSCL_NORMAL
;
886 device
->hwbuf
= NULL
;
887 device
->buffer
= NULL
;
889 device
->writelead
= 0;
890 device
->state
= STATE_STOPPED
;
891 device
->nrofbuffers
= 0;
892 device
->buffers
= NULL
;
893 device
->primary
= NULL
;
894 device
->speaker_config
= DSSPEAKER_STEREO
| (DSSPEAKER_GEOMETRY_NARROW
<< 16);
895 device
->tmp_buffer
= NULL
;
896 device
->tmp_buffer_len
= 0;
898 /* 3D listener initial parameters */
899 device
->listener
= NULL
;
900 device
->ds3dl
.dwSize
= sizeof(DS3DLISTENER
);
901 device
->ds3dl
.vPosition
.x
= 0.0;
902 device
->ds3dl
.vPosition
.y
= 0.0;
903 device
->ds3dl
.vPosition
.z
= 0.0;
904 device
->ds3dl
.vVelocity
.x
= 0.0;
905 device
->ds3dl
.vVelocity
.y
= 0.0;
906 device
->ds3dl
.vVelocity
.z
= 0.0;
907 device
->ds3dl
.vOrientFront
.x
= 0.0;
908 device
->ds3dl
.vOrientFront
.y
= 0.0;
909 device
->ds3dl
.vOrientFront
.z
= 1.0;
910 device
->ds3dl
.vOrientTop
.x
= 0.0;
911 device
->ds3dl
.vOrientTop
.y
= 1.0;
912 device
->ds3dl
.vOrientTop
.z
= 0.0;
913 device
->ds3dl
.flDistanceFactor
= DS3D_DEFAULTDISTANCEFACTOR
;
914 device
->ds3dl
.flRolloffFactor
= DS3D_DEFAULTROLLOFFFACTOR
;
915 device
->ds3dl
.flDopplerFactor
= DS3D_DEFAULTDOPPLERFACTOR
;
917 device
->prebuf
= ds_snd_queue_max
;
918 device
->guid
= GUID_NULL
;
920 /* Set default wave format (may need it for waveOutOpen) */
921 device
->pwfx
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(WAVEFORMATEX
));
922 if (device
->pwfx
== NULL
) {
923 WARN("out of memory\n");
924 HeapFree(GetProcessHeap(),0,device
);
925 return DSERR_OUTOFMEMORY
;
928 /* We rely on the sound driver to return the actual sound format of
929 * the device if it does not support 22050x8x2 and is given the
930 * WAVE_DIRECTSOUND flag.
932 device
->pwfx
->wFormatTag
= WAVE_FORMAT_PCM
;
933 device
->pwfx
->nSamplesPerSec
= 22050;
934 device
->pwfx
->wBitsPerSample
= 8;
935 device
->pwfx
->nChannels
= 2;
936 device
->pwfx
->nBlockAlign
= device
->pwfx
->wBitsPerSample
* device
->pwfx
->nChannels
/ 8;
937 device
->pwfx
->nAvgBytesPerSec
= device
->pwfx
->nSamplesPerSec
* device
->pwfx
->nBlockAlign
;
938 device
->pwfx
->cbSize
= 0;
940 InitializeCriticalSection(&(device
->mixlock
));
941 device
->mixlock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)"DSOUND_mixlock";
943 RtlInitializeResource(&(device
->buffer_list_lock
));
950 static ULONG
DirectSoundDevice_AddRef(DirectSoundDevice
* device
)
952 ULONG ref
= InterlockedIncrement(&(device
->ref
));
953 TRACE("(%p) ref was %ld\n", device
, ref
- 1);
957 static ULONG
DirectSoundDevice_Release(DirectSoundDevice
* device
)
960 ULONG ref
= InterlockedDecrement(&(device
->ref
));
961 TRACE("(%p) ref was %lu\n", device
, ref
+ 1);
964 timeKillEvent(device
->timerID
);
965 timeEndPeriod(DS_TIME_RES
);
966 /* wait for timer to expire */
967 Sleep(DS_TIME_RES
+1);
969 /* The sleep above should have allowed the timer process to expire
970 * but try to grab the lock just in case. Can't hold lock because
971 * IDirectSoundBufferImpl_Destroy also grabs the lock */
972 RtlAcquireResourceShared(&(device
->buffer_list_lock
), TRUE
);
973 RtlReleaseResource(&(device
->buffer_list_lock
));
975 /* It is allowed to release this object even when buffers are playing */
976 if (device
->buffers
) {
977 WARN("%d secondary buffers not released\n", device
->nrofbuffers
);
978 for( i
=0;i
<device
->nrofbuffers
;i
++)
979 IDirectSoundBufferImpl_Destroy(device
->buffers
[i
]);
982 if (device
->primary
) {
983 WARN("primary buffer not released\n");
984 IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8
)device
->primary
);
987 hr
= DSOUND_PrimaryDestroy(device
);
989 WARN("DSOUND_PrimaryDestroy failed\n");
992 IDsDriver_Close(device
->driver
);
994 if (device
->drvdesc
.dwFlags
& DSDDESC_DOMMSYSTEMOPEN
)
995 waveOutClose(device
->hwo
);
998 IDsDriver_Release(device
->driver
);
1000 DSOUND_renderer
[device
->drvdesc
.dnDevNode
] = NULL
;
1002 HeapFree(GetProcessHeap(),0,device
->tmp_buffer
);
1003 HeapFree(GetProcessHeap(),0,device
->buffer
);
1004 RtlDeleteResource(&device
->buffer_list_lock
);
1005 device
->mixlock
.DebugInfo
->Spare
[0] = 0;
1006 DeleteCriticalSection(&device
->mixlock
);
1007 HeapFree(GetProcessHeap(),0,device
);
1008 TRACE("(%p) released\n", device
);
1013 HRESULT WINAPI
IDirectSoundImpl_Create(
1014 LPDIRECTSOUND8
* ppDS
)
1016 IDirectSoundImpl
* pDS
;
1017 TRACE("(%p)\n",ppDS
);
1019 /* Allocate memory */
1020 pDS
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectSoundImpl
));
1022 WARN("out of memory\n");
1024 return DSERR_OUTOFMEMORY
;
1027 pDS
->lpVtbl
= &IDirectSoundImpl_Vtbl
;
1031 *ppDS
= (LPDIRECTSOUND8
)pDS
;
1036 /*******************************************************************************
1037 * IDirectSound_IUnknown
1039 static HRESULT WINAPI
IDirectSound_IUnknown_QueryInterface(
1044 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1045 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
1046 return DSOUND_QueryInterface(This
->pds
, riid
, ppobj
);
1049 static ULONG WINAPI
IDirectSound_IUnknown_AddRef(
1052 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1053 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1054 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
1058 static ULONG WINAPI
IDirectSound_IUnknown_Release(
1061 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1062 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1063 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
1065 IDirectSoundImpl_Release(This
->pds
);
1066 HeapFree(GetProcessHeap(), 0, This
);
1067 TRACE("(%p) released\n", This
);
1072 static const IUnknownVtbl DirectSound_Unknown_Vtbl
=
1074 IDirectSound_IUnknown_QueryInterface
,
1075 IDirectSound_IUnknown_AddRef
,
1076 IDirectSound_IUnknown_Release
1079 HRESULT WINAPI
IDirectSound_IUnknown_Create(
1083 IDirectSound_IUnknown
* pdsunk
;
1084 TRACE("(%p,%p)\n",pds
,ppunk
);
1086 if (ppunk
== NULL
) {
1087 ERR("invalid parameter: ppunk == NULL\n");
1088 return DSERR_INVALIDPARAM
;
1092 ERR("invalid parameter: pds == NULL\n");
1094 return DSERR_INVALIDPARAM
;
1097 pdsunk
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk
));
1098 if (pdsunk
== NULL
) {
1099 WARN("out of memory\n");
1101 return DSERR_OUTOFMEMORY
;
1104 pdsunk
->lpVtbl
= &DirectSound_Unknown_Vtbl
;
1108 IDirectSoundImpl_AddRef(pds
);
1109 *ppunk
= (LPUNKNOWN
)pdsunk
;
1114 /*******************************************************************************
1115 * IDirectSound_IDirectSound
1117 static HRESULT WINAPI
IDirectSound_IDirectSound_QueryInterface(
1118 LPDIRECTSOUND iface
,
1122 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1123 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
1124 return DSOUND_QueryInterface(This
->pds
, riid
, ppobj
);
1127 static ULONG WINAPI
IDirectSound_IDirectSound_AddRef(
1128 LPDIRECTSOUND iface
)
1130 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1131 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1132 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
1136 static ULONG WINAPI
IDirectSound_IDirectSound_Release(
1137 LPDIRECTSOUND iface
)
1139 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1140 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1141 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
1143 IDirectSoundImpl_Release(This
->pds
);
1144 HeapFree(GetProcessHeap(), 0, This
);
1145 TRACE("(%p) released\n", This
);
1150 static HRESULT WINAPI
IDirectSound_IDirectSound_CreateSoundBuffer(
1151 LPDIRECTSOUND iface
,
1152 LPCDSBUFFERDESC dsbd
,
1153 LPLPDIRECTSOUNDBUFFER ppdsb
,
1156 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1157 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
1158 return DSOUND_CreateSoundBuffer(This
->pds
,dsbd
,ppdsb
,lpunk
,FALSE
);
1161 static HRESULT WINAPI
IDirectSound_IDirectSound_GetCaps(
1162 LPDIRECTSOUND iface
,
1165 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1166 TRACE("(%p,%p)\n",This
,lpDSCaps
);
1167 return IDirectSoundImpl_GetCaps(This
->pds
, lpDSCaps
);
1170 static HRESULT WINAPI
IDirectSound_IDirectSound_DuplicateSoundBuffer(
1171 LPDIRECTSOUND iface
,
1172 LPDIRECTSOUNDBUFFER psb
,
1173 LPLPDIRECTSOUNDBUFFER ppdsb
)
1175 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1176 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
1177 return IDirectSoundImpl_DuplicateSoundBuffer(This
->pds
,psb
,ppdsb
);
1180 static HRESULT WINAPI
IDirectSound_IDirectSound_SetCooperativeLevel(
1181 LPDIRECTSOUND iface
,
1185 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1186 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
1187 return IDirectSoundImpl_SetCooperativeLevel(This
->pds
,hwnd
,level
);
1190 static HRESULT WINAPI
IDirectSound_IDirectSound_Compact(
1191 LPDIRECTSOUND iface
)
1193 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1194 TRACE("(%p)\n", This
);
1195 return IDirectSoundImpl_Compact(This
->pds
);
1198 static HRESULT WINAPI
IDirectSound_IDirectSound_GetSpeakerConfig(
1199 LPDIRECTSOUND iface
,
1200 LPDWORD lpdwSpeakerConfig
)
1202 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1203 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
1204 return IDirectSoundImpl_GetSpeakerConfig(This
->pds
,lpdwSpeakerConfig
);
1207 static HRESULT WINAPI
IDirectSound_IDirectSound_SetSpeakerConfig(
1208 LPDIRECTSOUND iface
,
1211 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1212 TRACE("(%p,0x%08lx)\n",This
,config
);
1213 return IDirectSoundImpl_SetSpeakerConfig(This
->pds
,config
);
1216 static HRESULT WINAPI
IDirectSound_IDirectSound_Initialize(
1217 LPDIRECTSOUND iface
,
1220 IDirectSound_IDirectSound
*This
= (IDirectSound_IDirectSound
*)iface
;
1221 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
1222 return IDirectSoundImpl_Initialize(This
->pds
,lpcGuid
);
1225 static const IDirectSoundVtbl DirectSound_DirectSound_Vtbl
=
1227 IDirectSound_IDirectSound_QueryInterface
,
1228 IDirectSound_IDirectSound_AddRef
,
1229 IDirectSound_IDirectSound_Release
,
1230 IDirectSound_IDirectSound_CreateSoundBuffer
,
1231 IDirectSound_IDirectSound_GetCaps
,
1232 IDirectSound_IDirectSound_DuplicateSoundBuffer
,
1233 IDirectSound_IDirectSound_SetCooperativeLevel
,
1234 IDirectSound_IDirectSound_Compact
,
1235 IDirectSound_IDirectSound_GetSpeakerConfig
,
1236 IDirectSound_IDirectSound_SetSpeakerConfig
,
1237 IDirectSound_IDirectSound_Initialize
1240 HRESULT WINAPI
IDirectSound_IDirectSound_Create(
1242 LPDIRECTSOUND
* ppds
)
1244 IDirectSound_IDirectSound
* pdsds
;
1245 TRACE("(%p,%p)\n",pds
,ppds
);
1248 ERR("invalid parameter: ppds == NULL\n");
1249 return DSERR_INVALIDPARAM
;
1253 ERR("invalid parameter: pds == NULL\n");
1255 return DSERR_INVALIDPARAM
;
1258 pdsds
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds
));
1259 if (pdsds
== NULL
) {
1260 WARN("out of memory\n");
1262 return DSERR_OUTOFMEMORY
;
1265 pdsds
->lpVtbl
= &DirectSound_DirectSound_Vtbl
;
1269 IDirectSoundImpl_AddRef(pds
);
1270 *ppds
= (LPDIRECTSOUND
)pdsds
;
1275 /*******************************************************************************
1276 * IDirectSound8_IUnknown
1278 static HRESULT WINAPI
IDirectSound8_IUnknown_QueryInterface(
1283 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1284 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
1285 return DSOUND_QueryInterface8(This
->pds
, riid
, ppobj
);
1288 static ULONG WINAPI
IDirectSound8_IUnknown_AddRef(
1291 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1292 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1293 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
1297 static ULONG WINAPI
IDirectSound8_IUnknown_Release(
1300 IDirectSound_IUnknown
*This
= (IDirectSound_IUnknown
*)iface
;
1301 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1302 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
1304 IDirectSoundImpl_Release(This
->pds
);
1305 HeapFree(GetProcessHeap(), 0, This
);
1306 TRACE("(%p) released\n", This
);
1311 static const IUnknownVtbl DirectSound8_Unknown_Vtbl
=
1313 IDirectSound8_IUnknown_QueryInterface
,
1314 IDirectSound8_IUnknown_AddRef
,
1315 IDirectSound8_IUnknown_Release
1318 HRESULT WINAPI
IDirectSound8_IUnknown_Create(
1322 IDirectSound8_IUnknown
* pdsunk
;
1323 TRACE("(%p,%p)\n",pds
,ppunk
);
1325 if (ppunk
== NULL
) {
1326 ERR("invalid parameter: ppunk == NULL\n");
1327 return DSERR_INVALIDPARAM
;
1331 ERR("invalid parameter: pds == NULL\n");
1333 return DSERR_INVALIDPARAM
;
1336 pdsunk
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk
));
1337 if (pdsunk
== NULL
) {
1338 WARN("out of memory\n");
1340 return DSERR_OUTOFMEMORY
;
1343 pdsunk
->lpVtbl
= &DirectSound8_Unknown_Vtbl
;
1347 IDirectSoundImpl_AddRef(pds
);
1348 *ppunk
= (LPUNKNOWN
)pdsunk
;
1353 /*******************************************************************************
1354 * IDirectSound8_IDirectSound
1356 static HRESULT WINAPI
IDirectSound8_IDirectSound_QueryInterface(
1357 LPDIRECTSOUND iface
,
1361 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1362 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
1363 return DSOUND_QueryInterface8(This
->pds
, riid
, ppobj
);
1366 static ULONG WINAPI
IDirectSound8_IDirectSound_AddRef(
1367 LPDIRECTSOUND iface
)
1369 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1370 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1371 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
1375 static ULONG WINAPI
IDirectSound8_IDirectSound_Release(
1376 LPDIRECTSOUND iface
)
1378 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1379 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1380 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
1382 IDirectSoundImpl_Release(This
->pds
);
1383 HeapFree(GetProcessHeap(), 0, This
);
1384 TRACE("(%p) released\n", This
);
1389 static HRESULT WINAPI
IDirectSound8_IDirectSound_CreateSoundBuffer(
1390 LPDIRECTSOUND iface
,
1391 LPCDSBUFFERDESC dsbd
,
1392 LPLPDIRECTSOUNDBUFFER ppdsb
,
1395 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1396 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
1397 return DSOUND_CreateSoundBuffer(This
->pds
,dsbd
,ppdsb
,lpunk
,TRUE
);
1400 static HRESULT WINAPI
IDirectSound8_IDirectSound_GetCaps(
1401 LPDIRECTSOUND iface
,
1404 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1405 TRACE("(%p,%p)\n",This
,lpDSCaps
);
1406 return IDirectSoundImpl_GetCaps(This
->pds
, lpDSCaps
);
1409 static HRESULT WINAPI
IDirectSound8_IDirectSound_DuplicateSoundBuffer(
1410 LPDIRECTSOUND iface
,
1411 LPDIRECTSOUNDBUFFER psb
,
1412 LPLPDIRECTSOUNDBUFFER ppdsb
)
1414 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1415 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
1416 return IDirectSoundImpl_DuplicateSoundBuffer(This
->pds
,psb
,ppdsb
);
1419 static HRESULT WINAPI
IDirectSound8_IDirectSound_SetCooperativeLevel(
1420 LPDIRECTSOUND iface
,
1424 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1425 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
1426 return IDirectSoundImpl_SetCooperativeLevel(This
->pds
,hwnd
,level
);
1429 static HRESULT WINAPI
IDirectSound8_IDirectSound_Compact(
1430 LPDIRECTSOUND iface
)
1432 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1433 TRACE("(%p)\n", This
);
1434 return IDirectSoundImpl_Compact(This
->pds
);
1437 static HRESULT WINAPI
IDirectSound8_IDirectSound_GetSpeakerConfig(
1438 LPDIRECTSOUND iface
,
1439 LPDWORD lpdwSpeakerConfig
)
1441 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1442 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
1443 return IDirectSoundImpl_GetSpeakerConfig(This
->pds
,lpdwSpeakerConfig
);
1446 static HRESULT WINAPI
IDirectSound8_IDirectSound_SetSpeakerConfig(
1447 LPDIRECTSOUND iface
,
1450 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1451 TRACE("(%p,0x%08lx)\n",This
,config
);
1452 return IDirectSoundImpl_SetSpeakerConfig(This
->pds
,config
);
1455 static HRESULT WINAPI
IDirectSound8_IDirectSound_Initialize(
1456 LPDIRECTSOUND iface
,
1459 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1460 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
1461 return IDirectSoundImpl_Initialize(This
->pds
,lpcGuid
);
1464 static const IDirectSoundVtbl DirectSound8_DirectSound_Vtbl
=
1466 IDirectSound8_IDirectSound_QueryInterface
,
1467 IDirectSound8_IDirectSound_AddRef
,
1468 IDirectSound8_IDirectSound_Release
,
1469 IDirectSound8_IDirectSound_CreateSoundBuffer
,
1470 IDirectSound8_IDirectSound_GetCaps
,
1471 IDirectSound8_IDirectSound_DuplicateSoundBuffer
,
1472 IDirectSound8_IDirectSound_SetCooperativeLevel
,
1473 IDirectSound8_IDirectSound_Compact
,
1474 IDirectSound8_IDirectSound_GetSpeakerConfig
,
1475 IDirectSound8_IDirectSound_SetSpeakerConfig
,
1476 IDirectSound8_IDirectSound_Initialize
1479 HRESULT WINAPI
IDirectSound8_IDirectSound_Create(
1481 LPDIRECTSOUND
* ppds
)
1483 IDirectSound8_IDirectSound
* pdsds
;
1484 TRACE("(%p,%p)\n",pds
,ppds
);
1487 ERR("invalid parameter: ppds == NULL\n");
1488 return DSERR_INVALIDPARAM
;
1492 ERR("invalid parameter: pds == NULL\n");
1494 return DSERR_INVALIDPARAM
;
1497 pdsds
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds
));
1498 if (pdsds
== NULL
) {
1499 WARN("out of memory\n");
1501 return DSERR_OUTOFMEMORY
;
1504 pdsds
->lpVtbl
= &DirectSound8_DirectSound_Vtbl
;
1508 IDirectSoundImpl_AddRef(pds
);
1509 *ppds
= (LPDIRECTSOUND
)pdsds
;
1514 /*******************************************************************************
1515 * IDirectSound8_IDirectSound8
1517 static HRESULT WINAPI
IDirectSound8_IDirectSound8_QueryInterface(
1518 LPDIRECTSOUND8 iface
,
1522 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1523 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
1524 return DSOUND_QueryInterface8(This
->pds
, riid
, ppobj
);
1527 static ULONG WINAPI
IDirectSound8_IDirectSound8_AddRef(
1528 LPDIRECTSOUND8 iface
)
1530 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1531 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1532 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
1536 static ULONG WINAPI
IDirectSound8_IDirectSound8_Release(
1537 LPDIRECTSOUND8 iface
)
1539 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1540 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1541 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
1543 IDirectSoundImpl_Release(This
->pds
);
1544 HeapFree(GetProcessHeap(), 0, This
);
1545 TRACE("(%p) released\n", This
);
1550 static HRESULT WINAPI
IDirectSound8_IDirectSound8_CreateSoundBuffer(
1551 LPDIRECTSOUND8 iface
,
1552 LPCDSBUFFERDESC dsbd
,
1553 LPLPDIRECTSOUNDBUFFER ppdsb
,
1556 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1557 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
1558 return DSOUND_CreateSoundBuffer(This
->pds
,dsbd
,ppdsb
,lpunk
,TRUE
);
1561 static HRESULT WINAPI
IDirectSound8_IDirectSound8_GetCaps(
1562 LPDIRECTSOUND8 iface
,
1565 IDirectSound8_IDirectSound
*This
= (IDirectSound8_IDirectSound
*)iface
;
1566 TRACE("(%p,%p)\n",This
,lpDSCaps
);
1567 return IDirectSoundImpl_GetCaps(This
->pds
, lpDSCaps
);
1570 static HRESULT WINAPI
IDirectSound8_IDirectSound8_DuplicateSoundBuffer(
1571 LPDIRECTSOUND8 iface
,
1572 LPDIRECTSOUNDBUFFER psb
,
1573 LPLPDIRECTSOUNDBUFFER ppdsb
)
1575 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1576 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
1577 return IDirectSoundImpl_DuplicateSoundBuffer(This
->pds
,psb
,ppdsb
);
1580 static HRESULT WINAPI
IDirectSound8_IDirectSound8_SetCooperativeLevel(
1581 LPDIRECTSOUND8 iface
,
1585 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1586 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
1587 return IDirectSoundImpl_SetCooperativeLevel(This
->pds
,hwnd
,level
);
1590 static HRESULT WINAPI
IDirectSound8_IDirectSound8_Compact(
1591 LPDIRECTSOUND8 iface
)
1593 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1594 TRACE("(%p)\n", This
);
1595 return IDirectSoundImpl_Compact(This
->pds
);
1598 static HRESULT WINAPI
IDirectSound8_IDirectSound8_GetSpeakerConfig(
1599 LPDIRECTSOUND8 iface
,
1600 LPDWORD lpdwSpeakerConfig
)
1602 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1603 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
1604 return IDirectSoundImpl_GetSpeakerConfig(This
->pds
,lpdwSpeakerConfig
);
1607 static HRESULT WINAPI
IDirectSound8_IDirectSound8_SetSpeakerConfig(
1608 LPDIRECTSOUND8 iface
,
1611 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1612 TRACE("(%p,0x%08lx)\n",This
,config
);
1613 return IDirectSoundImpl_SetSpeakerConfig(This
->pds
,config
);
1616 static HRESULT WINAPI
IDirectSound8_IDirectSound8_Initialize(
1617 LPDIRECTSOUND8 iface
,
1620 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1621 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
1622 return IDirectSoundImpl_Initialize(This
->pds
,lpcGuid
);
1625 static HRESULT WINAPI
IDirectSound8_IDirectSound8_VerifyCertification(
1626 LPDIRECTSOUND8 iface
,
1627 LPDWORD pdwCertified
)
1629 IDirectSound8_IDirectSound8
*This
= (IDirectSound8_IDirectSound8
*)iface
;
1630 TRACE("(%p, %p)\n", This
, pdwCertified
);
1631 return IDirectSoundImpl_VerifyCertification(This
->pds
,pdwCertified
);
1634 static const IDirectSound8Vtbl DirectSound8_DirectSound8_Vtbl
=
1636 IDirectSound8_IDirectSound8_QueryInterface
,
1637 IDirectSound8_IDirectSound8_AddRef
,
1638 IDirectSound8_IDirectSound8_Release
,
1639 IDirectSound8_IDirectSound8_CreateSoundBuffer
,
1640 IDirectSound8_IDirectSound8_GetCaps
,
1641 IDirectSound8_IDirectSound8_DuplicateSoundBuffer
,
1642 IDirectSound8_IDirectSound8_SetCooperativeLevel
,
1643 IDirectSound8_IDirectSound8_Compact
,
1644 IDirectSound8_IDirectSound8_GetSpeakerConfig
,
1645 IDirectSound8_IDirectSound8_SetSpeakerConfig
,
1646 IDirectSound8_IDirectSound8_Initialize
,
1647 IDirectSound8_IDirectSound8_VerifyCertification
1650 HRESULT WINAPI
IDirectSound8_IDirectSound8_Create(
1652 LPDIRECTSOUND8
* ppds
)
1654 IDirectSound8_IDirectSound8
* pdsds
;
1655 TRACE("(%p,%p)\n",pds
,ppds
);
1658 ERR("invalid parameter: ppds == NULL\n");
1659 return DSERR_INVALIDPARAM
;
1663 ERR("invalid parameter: pds == NULL\n");
1665 return DSERR_INVALIDPARAM
;
1668 pdsds
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds
));
1669 if (pdsds
== NULL
) {
1670 WARN("out of memory\n");
1672 return DSERR_OUTOFMEMORY
;
1675 pdsds
->lpVtbl
= &DirectSound8_DirectSound8_Vtbl
;
1679 IDirectSoundImpl_AddRef(pds
);
1680 *ppds
= (LPDIRECTSOUND8
)pdsds
;
1685 HRESULT WINAPI
DSOUND_Create(
1686 LPDIRECTSOUND
*ppDS
,
1687 IUnknown
*pUnkOuter
)
1691 TRACE("(%p,%p)\n",ppDS
,pUnkOuter
);
1693 /* Get dsound configuration */
1694 setup_dsound_options();
1696 hr
= IDirectSoundImpl_Create(&pDS
);
1698 hr
= IDirectSound_IDirectSound_Create(pDS
, ppDS
);
1700 IDirectSound_IDirectSound_AddRef(*ppDS
);
1702 WARN("IDirectSound_IDirectSound_Create failed\n");
1703 IDirectSound8_Release(pDS
);
1706 WARN("IDirectSoundImpl_Create failed\n");
1713 /*******************************************************************************
1714 * DirectSoundCreate (DSOUND.1)
1716 * Creates and initializes a DirectSound interface.
1719 * lpcGUID [I] Address of the GUID that identifies the sound device.
1720 * ppDS [O] Address of a variable to receive the interface pointer.
1721 * pUnkOuter [I] Must be NULL.
1725 * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
1726 * DSERR_NODRIVER, DSERR_OUTOFMEMORY
1728 HRESULT WINAPI
DirectSoundCreate(
1730 LPDIRECTSOUND
*ppDS
,
1731 IUnknown
*pUnkOuter
)
1736 TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID
),ppDS
,pUnkOuter
);
1739 WARN("invalid parameter: ppDS == NULL\n");
1740 return DSERR_INVALIDPARAM
;
1743 if (pUnkOuter
!= NULL
) {
1744 WARN("invalid parameter: pUnkOuter != NULL\n");
1746 return DSERR_INVALIDPARAM
;
1749 hr
= DSOUND_Create(&pDS
, pUnkOuter
);
1751 hr
= IDirectSound_Initialize(pDS
, lpcGUID
);
1753 if (hr
!= DSERR_ALREADYINITIALIZED
) {
1754 IDirectSound_Release(pDS
);
1766 HRESULT WINAPI
DSOUND_Create8(
1767 LPDIRECTSOUND8
*ppDS
,
1768 IUnknown
*pUnkOuter
)
1772 TRACE("(%p,%p)\n",ppDS
,pUnkOuter
);
1774 /* Get dsound configuration */
1775 setup_dsound_options();
1777 hr
= IDirectSoundImpl_Create(&pDS
);
1779 hr
= IDirectSound8_IDirectSound8_Create(pDS
, ppDS
);
1781 IDirectSound8_IDirectSound8_AddRef(*ppDS
);
1783 WARN("IDirectSound8_IDirectSound8_Create failed\n");
1784 IDirectSound8_Release(pDS
);
1787 WARN("IDirectSoundImpl_Create failed\n");
1794 /*******************************************************************************
1795 * DirectSoundCreate8 (DSOUND.11)
1797 * Creates and initializes a DirectSound8 interface.
1800 * lpcGUID [I] Address of the GUID that identifies the sound device.
1801 * ppDS [O] Address of a variable to receive the interface pointer.
1802 * pUnkOuter [I] Must be NULL.
1806 * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
1807 * DSERR_NODRIVER, DSERR_OUTOFMEMORY
1809 HRESULT WINAPI
DirectSoundCreate8(
1811 LPDIRECTSOUND8
*ppDS
,
1812 IUnknown
*pUnkOuter
)
1817 TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID
),ppDS
,pUnkOuter
);
1820 WARN("invalid parameter: ppDS == NULL\n");
1821 return DSERR_INVALIDPARAM
;
1824 if (pUnkOuter
!= NULL
) {
1825 WARN("invalid parameter: pUnkOuter != NULL\n");
1827 return DSERR_INVALIDPARAM
;
1830 hr
= DSOUND_Create8(&pDS
, pUnkOuter
);
1832 hr
= IDirectSound8_Initialize(pDS
, lpcGUID
);
1834 if (hr
!= DSERR_ALREADYINITIALIZED
) {
1835 IDirectSound8_Release(pDS
);
1848 * Add secondary buffer to buffer list.
1849 * Gets exclusive access to buffer for writing.
1851 HRESULT
DSOUND_AddBuffer(
1852 IDirectSoundImpl
* pDS
,
1853 IDirectSoundBufferImpl
* pDSB
)
1855 IDirectSoundBufferImpl
**newbuffers
;
1858 TRACE("(%p, %p)\n", pDS
, pDSB
);
1860 RtlAcquireResourceExclusive(&(pDS
->device
->buffer_list_lock
), TRUE
);
1862 if (pDS
->device
->buffers
)
1863 newbuffers
= HeapReAlloc(GetProcessHeap(),0,pDS
->device
->buffers
,sizeof(IDirectSoundBufferImpl
*)*(pDS
->device
->nrofbuffers
+1));
1865 newbuffers
= HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl
*)*(pDS
->device
->nrofbuffers
+1));
1868 pDS
->device
->buffers
= newbuffers
;
1869 pDS
->device
->buffers
[pDS
->device
->nrofbuffers
] = pDSB
;
1870 pDS
->device
->nrofbuffers
++;
1871 TRACE("buffer count is now %d\n", pDS
->device
->nrofbuffers
);
1873 ERR("out of memory for buffer list! Current buffer count is %d\n", pDS
->device
->nrofbuffers
);
1874 hr
= DSERR_OUTOFMEMORY
;
1877 RtlReleaseResource(&(pDS
->device
->buffer_list_lock
));
1883 * Remove secondary buffer from buffer list.
1884 * Gets exclusive access to buffer for writing.
1886 HRESULT
DSOUND_RemoveBuffer(
1887 IDirectSoundImpl
* pDS
,
1888 IDirectSoundBufferImpl
* pDSB
)
1893 TRACE("(%p, %p)\n", pDS
, pDSB
);
1895 RtlAcquireResourceExclusive(&(pDS
->device
->buffer_list_lock
), TRUE
);
1897 for (i
= 0; i
< pDS
->device
->nrofbuffers
; i
++)
1898 if (pDS
->device
->buffers
[i
] == pDSB
)
1901 if (i
< pDS
->device
->nrofbuffers
) {
1902 /* Put the last buffer of the list in the (now empty) position */
1903 pDS
->device
->buffers
[i
] = pDS
->device
->buffers
[pDS
->device
->nrofbuffers
- 1];
1904 pDS
->device
->nrofbuffers
--;
1905 pDS
->device
->buffers
= HeapReAlloc(GetProcessHeap(),0,pDS
->device
->buffers
,sizeof(LPDIRECTSOUNDBUFFER8
)*pDS
->device
->nrofbuffers
);
1906 TRACE("buffer count is now %d\n", pDS
->device
->nrofbuffers
);
1909 if (pDS
->device
->nrofbuffers
== 0) {
1910 HeapFree(GetProcessHeap(),0,pDS
->device
->buffers
);
1911 pDS
->device
->buffers
= NULL
;
1914 RtlReleaseResource(&(pDS
->device
->buffer_list_lock
));