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
24 #include "wine/port.h"
28 #include <sys/types.h>
29 #include <sys/fcntl.h>
36 #define NONAMELESSSTRUCT
37 #define NONAMELESSUNION
48 #include "wine/windef16.h"
49 #include "wine/winbase16.h"
50 #include "wine/debug.h"
53 #include "dsound_private.h"
56 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
58 static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
59 static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
60 static ULONG WINAPI IDirectSound8_IUnknown_AddRef(LPUNKNOWN iface);
61 static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(LPDIRECTSOUND iface);
62 static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(LPDIRECTSOUND8 iface);
64 static const char * dumpCooperativeLevel(DWORD level)
66 static char unknown[32];
67 #define LE(x) case x: return #x
72 LE(DSSCL_WRITEPRIMARY);
75 sprintf(unknown, "Unknown(%08lx)", level);
79 static void _dump_DSBCAPS(DWORD xmask) {
84 #define FE(x) { x, #x },
85 FE(DSBCAPS_PRIMARYBUFFER)
87 FE(DSBCAPS_LOCHARDWARE)
88 FE(DSBCAPS_LOCSOFTWARE)
90 FE(DSBCAPS_CTRLFREQUENCY)
92 FE(DSBCAPS_CTRLVOLUME)
93 FE(DSBCAPS_CTRLPOSITIONNOTIFY)
94 FE(DSBCAPS_CTRLDEFAULT)
96 FE(DSBCAPS_STICKYFOCUS)
97 FE(DSBCAPS_GLOBALFOCUS)
98 FE(DSBCAPS_GETCURRENTPOSITION2)
99 FE(DSBCAPS_MUTE3DATMAXDISTANCE)
104 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
105 if ((flags[i].mask & xmask) == flags[i].mask)
106 DPRINTF("%s ",flags[i].name);
109 /*******************************************************************************
110 * IDirectSoundImpl_DirectSound
112 static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
113 LPDIRECTSOUND8 iface,
117 TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppobj);
118 FIXME("shouldn't be called directly\n");
119 return E_NOINTERFACE;
122 static HRESULT WINAPI DSOUND_QueryInterface(
123 LPDIRECTSOUND8 iface,
127 ICOM_THIS(IDirectSoundImpl,iface);
128 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
131 WARN("invalid parameter\n");
135 if (IsEqualIID(riid, &IID_IUnknown)) {
136 if (!This->pUnknown) {
137 IDirectSound_IUnknown_Create(iface, &This->pUnknown);
138 if (!This->pUnknown) {
139 WARN("IDirectSound_IUnknown_Create() failed\n");
141 return E_NOINTERFACE;
144 IDirectSound_IUnknown_AddRef(This->pUnknown);
145 *ppobj = This->pUnknown;
147 } else if (IsEqualIID(riid, &IID_IDirectSound)) {
149 IDirectSound_IDirectSound_Create(iface, &This->pDS);
151 WARN("IDirectSound_IDirectSound_Create() failed\n");
153 return E_NOINTERFACE;
156 IDirectSound_IDirectSound_AddRef(This->pDS);
162 WARN("Unknown IID %s\n",debugstr_guid(riid));
163 return E_NOINTERFACE;
166 static HRESULT WINAPI DSOUND_QueryInterface8(
167 LPDIRECTSOUND8 iface,
171 ICOM_THIS(IDirectSoundImpl,iface);
172 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
175 WARN("invalid parameter\n");
179 if (IsEqualIID(riid, &IID_IUnknown)) {
180 if (!This->pUnknown) {
181 IDirectSound8_IUnknown_Create(iface, &This->pUnknown);
182 if (!This->pUnknown) {
183 WARN("IDirectSound8_IUnknown_Create() failed\n");
185 return E_NOINTERFACE;
188 IDirectSound8_IUnknown_AddRef(This->pUnknown);
189 *ppobj = This->pUnknown;
191 } else if (IsEqualIID(riid, &IID_IDirectSound)) {
193 IDirectSound8_IDirectSound_Create(iface, &This->pDS);
195 WARN("IDirectSound8_IDirectSound_Create() failed\n");
197 return E_NOINTERFACE;
200 IDirectSound8_IDirectSound_AddRef(This->pDS);
203 } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
205 IDirectSound8_IDirectSound8_Create(iface, &This->pDS8);
207 WARN("IDirectSound8_IDirectSound8_Create() failed\n");
209 return E_NOINTERFACE;
212 IDirectSound8_IDirectSound8_AddRef(This->pDS8);
218 WARN("Unknown IID %s\n",debugstr_guid(riid));
219 return E_NOINTERFACE;
222 static ULONG WINAPI IDirectSoundImpl_AddRef(
223 LPDIRECTSOUND8 iface)
225 ICOM_THIS(IDirectSoundImpl,iface);
226 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
228 return InterlockedIncrement(&This->ref);
231 static ULONG WINAPI IDirectSoundImpl_Release(
232 LPDIRECTSOUND8 iface)
234 ICOM_THIS(IDirectSoundImpl,iface);
236 TRACE("(%p) ref was %ld, thread is %04lx\n",
237 This, This->ref, GetCurrentThreadId());
239 ref = InterlockedDecrement(&This->ref);
244 timeKillEvent(This->timerID);
245 timeEndPeriod(DS_TIME_RES);
246 /* wait for timer to expire */
247 Sleep(DS_TIME_RES+1);
249 /* The sleep above should have allowed the timer process to expire
250 * but try to grab the lock just in case. Can't hold lock because
251 * IDirectSoundBufferImpl_Destroy also grabs the lock */
252 RtlAcquireResourceShared(&(This->lock), TRUE);
253 RtlReleaseResource(&(This->lock));
255 /* It is allowed to release this object even when buffers are playing */
257 WARN("%d secondary buffers not released\n", This->nrofbuffers);
258 for( i=0;i<This->nrofbuffers;i++)
259 IDirectSoundBufferImpl_Destroy(This->buffers[i]);
263 WARN("primary buffer not released\n");
264 IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
267 hres = DSOUND_PrimaryDestroy(This);
269 WARN("DSOUND_PrimaryDestroy failed\n");
272 IDsDriver_Close(This->driver);
274 if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
275 waveOutClose(This->hwo);
278 IDsDriver_Release(This->driver);
280 RtlDeleteResource(&This->lock);
281 DeleteCriticalSection(&This->mixlock);
282 HeapFree(GetProcessHeap(),0,This);
284 TRACE("(%p) released\n",This);
290 static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
291 LPDIRECTSOUND8 iface,
292 LPCDSBUFFERDESC dsbd,
293 LPLPDIRECTSOUNDBUFFER ppdsb,
296 ICOM_THIS(IDirectSoundImpl,iface);
298 HRESULT hres = DS_OK;
299 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
302 WARN("invalid parameter: This == NULL\n");
303 return DSERR_INVALIDPARAM;
307 WARN("invalid parameter: dsbd == NULL\n");
308 return DSERR_INVALIDPARAM;
311 if (dsbd->dwSize != sizeof(DSBUFFERDESC) && dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
312 WARN("invalid parameter: dsbd\n");
313 return DSERR_INVALIDPARAM;
317 WARN("invalid parameter: ppdsb == NULL\n");
318 return DSERR_INVALIDPARAM;
321 if (TRACE_ON(dsound)) {
322 TRACE("(structsize=%ld)\n",dsbd->dwSize);
323 TRACE("(flags=0x%08lx:\n",dsbd->dwFlags);
324 _dump_DSBCAPS(dsbd->dwFlags);
326 TRACE("(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
327 TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
330 wfex = dsbd->lpwfxFormat;
333 TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
334 "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
335 wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
336 wfex->nAvgBytesPerSec, wfex->nBlockAlign,
337 wfex->wBitsPerSample, wfex->cbSize);
339 if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
341 WARN("Primary Buffer already created\n");
342 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
343 *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
346 hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
348 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
349 *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
351 WARN("PrimaryBufferImpl_Create failed\n");
354 IDirectSoundBufferImpl * dsb;
355 hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
357 hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
359 dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
360 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppdsb);
362 WARN("SecondaryBufferImpl_Create failed\n");
364 WARN("IDirectSoundBufferImpl_Create failed\n");
370 static HRESULT WINAPI IDirectSoundImpl_GetCaps(
371 LPDIRECTSOUND8 iface,
374 ICOM_THIS(IDirectSoundImpl,iface);
375 TRACE("(%p,%p)\n",This,lpDSCaps);
378 WARN("invalid parameter: This == NULL\n");
379 return DSERR_INVALIDPARAM;
382 if (lpDSCaps == NULL) {
383 WARN("invalid parameter: lpDSCaps = NULL\n");
384 return DSERR_INVALIDPARAM;
387 /* check if there is enough room */
388 if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
389 WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
390 lpDSCaps->dwSize, sizeof(*lpDSCaps));
391 return DSERR_INVALIDPARAM;
394 TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
395 lpDSCaps->dwFlags = This->drvcaps.dwFlags;
396 lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
397 lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
398 lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
399 lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
400 lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
401 lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
402 lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
403 lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
404 lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
405 lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
406 lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
407 lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
408 lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
409 lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
410 lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
411 lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
412 lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
413 lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
415 /* driver doesn't have these */
416 lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
417 lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
422 static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
423 LPDIRECTSOUND8 iface,
424 LPDIRECTSOUNDBUFFER psb,
425 LPLPDIRECTSOUNDBUFFER ppdsb)
427 IDirectSoundBufferImpl* pdsb;
428 IDirectSoundBufferImpl* dsb;
429 HRESULT hres = DS_OK;
430 ICOM_THIS(IDirectSoundImpl,iface);
432 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
435 WARN("invalid parameter: This == NULL\n");
436 return DSERR_INVALIDPARAM;
440 WARN("invalid parameter: psb == NULL\n");
441 return DSERR_INVALIDPARAM;
445 WARN("invalid parameter: ppdsb == NULL\n");
446 return DSERR_INVALIDPARAM;
449 /* FIXME: hack to make sure we have a secondary buffer */
450 if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
451 WARN("trying to duplicate primary buffer\n");
453 return DSERR_INVALIDCALL;
456 pdsb = ((SecondaryBufferImpl *)psb)->dsb;
458 dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
461 WARN("out of memory\n");
463 return DSERR_OUTOFMEMORY;
466 memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
469 TRACE("duplicating hardware buffer\n");
471 hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
473 TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
475 /* allocate buffer */
476 if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
477 dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
478 if (dsb->buffer == NULL) {
479 WARN("out of memory\n");
480 HeapFree(GetProcessHeap(),0,dsb);
482 return DSERR_OUTOFMEMORY;
485 dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
486 if (dsb->buffer->memory == NULL) {
487 WARN("out of memory\n");
488 HeapFree(GetProcessHeap(),0,dsb->buffer);
489 HeapFree(GetProcessHeap(),0,dsb);
491 return DSERR_OUTOFMEMORY;
493 dsb->buffer->ref = 1;
495 /* FIXME: copy buffer ? */
504 dsb->state = STATE_STOPPED;
509 dsb->iks = NULL; /* FIXME? */
511 memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
512 InitializeCriticalSection(&(dsb->lock));
513 /* register buffer */
514 RtlAcquireResourceExclusive(&(This->lock), TRUE);
516 IDirectSoundBufferImpl **newbuffers;
518 newbuffers = HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
520 newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
523 This->buffers = newbuffers;
524 This->buffers[This->nrofbuffers] = dsb;
526 TRACE("buffer count is now %d\n", This->nrofbuffers);
528 ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
529 IDirectSoundBuffer8_Release(psb);
530 DeleteCriticalSection(&(dsb->lock));
531 RtlReleaseResource(&(This->lock));
532 HeapFree(GetProcessHeap(),0,dsb);
534 return DSERR_OUTOFMEMORY;
537 RtlReleaseResource(&(This->lock));
538 hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
540 dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
541 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
543 WARN("SecondaryBufferImpl_Create failed\n");
548 static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
549 LPDIRECTSOUND8 iface,
553 ICOM_THIS(IDirectSoundImpl,iface);
554 TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
556 if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
557 FIXME("level=%s not fully supported\n",
558 level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
560 This->priolevel = level;
564 static HRESULT WINAPI IDirectSoundImpl_Compact(
565 LPDIRECTSOUND8 iface)
567 ICOM_THIS(IDirectSoundImpl,iface);
568 TRACE("(%p)\n",This);
573 static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
574 LPDIRECTSOUND8 iface,
575 LPDWORD lpdwSpeakerConfig)
577 ICOM_THIS(IDirectSoundImpl,iface);
578 TRACE("(%p, %p)\n",This,lpdwSpeakerConfig);
580 if (lpdwSpeakerConfig == NULL) {
581 WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
582 return DSERR_INVALIDPARAM;
585 WARN("not fully functional\n");
586 *lpdwSpeakerConfig = This->speaker_config;
590 static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
591 LPDIRECTSOUND8 iface,
594 ICOM_THIS(IDirectSoundImpl,iface);
595 TRACE("(%p,0x%08lx)\n",This,config);
597 This->speaker_config = config;
598 WARN("not fully functional\n");
602 static HRESULT WINAPI IDirectSoundImpl_Initialize(
603 LPDIRECTSOUND8 iface,
606 ICOM_THIS(IDirectSoundImpl,iface);
607 TRACE("(%p,%s)\n",This,debugstr_guid(lpcGuid));
612 static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
613 LPDIRECTSOUND8 iface,
614 LPDWORD pdwCertified)
616 ICOM_THIS(IDirectSoundImpl,iface);
617 TRACE("(%p, %p)\n",This,pdwCertified);
619 if (This->drvcaps.dwFlags & DSCAPS_CERTIFIED)
620 *pdwCertified = DS_CERTIFIED;
622 *pdwCertified = DS_UNCERTIFIED;
626 static ICOM_VTABLE(IDirectSound8) IDirectSoundImpl_Vtbl =
628 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
629 IDirectSoundImpl_QueryInterface,
630 IDirectSoundImpl_AddRef,
631 IDirectSoundImpl_Release,
632 IDirectSoundImpl_CreateSoundBuffer,
633 IDirectSoundImpl_GetCaps,
634 IDirectSoundImpl_DuplicateSoundBuffer,
635 IDirectSoundImpl_SetCooperativeLevel,
636 IDirectSoundImpl_Compact,
637 IDirectSoundImpl_GetSpeakerConfig,
638 IDirectSoundImpl_SetSpeakerConfig,
639 IDirectSoundImpl_Initialize,
640 IDirectSoundImpl_VerifyCertification
643 HRESULT WINAPI IDirectSoundImpl_Create(
645 LPDIRECTSOUND8 * ppDS)
647 HRESULT err = DSERR_INVALIDPARAM;
648 PIDSDRIVER drv = NULL;
649 IDirectSoundImpl* pDS;
651 BOOLEAN found = FALSE;
652 TRACE("(%s,%p)\n",debugstr_guid(lpcGUID),ppDS);
654 /* Enumerate WINMM audio devices and find the one we want */
655 wodn = waveOutGetNumDevs();
659 return DSERR_NODRIVER;
662 TRACE(" expecting GUID %s.\n", debugstr_guid(lpcGUID));
664 for (wod=0; wod<wodn; wod++) {
666 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
668 WARN("waveOutMessage failed; err=%lx\n",err);
672 TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
673 if (IsEqualGUID( lpcGUID, &guid)) {
681 WARN("invalid parameter\n");
683 return DSERR_INVALIDPARAM;
686 if (found == FALSE) {
687 WARN("No device found matching given ID - trying with default one !\n");
688 wod = ds_default_playback;
691 /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
692 waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
694 /* Disable the direct sound driver to force emulation if requested. */
695 if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
698 /* Allocate memory */
699 pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
701 WARN("out of memory\n");
703 return DSERR_OUTOFMEMORY;
706 pDS->lpVtbl = &IDirectSoundImpl_Vtbl;
710 pDS->priolevel = DSSCL_NORMAL;
716 pDS->state = STATE_STOPPED;
717 pDS->nrofbuffers = 0;
720 pDS->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
722 /* 3D listener initial parameters */
723 pDS->listener = NULL;
724 pDS->ds3dl.dwSize = sizeof(DS3DLISTENER);
725 pDS->ds3dl.vPosition.x = 0.0;
726 pDS->ds3dl.vPosition.y = 0.0;
727 pDS->ds3dl.vPosition.z = 0.0;
728 pDS->ds3dl.vVelocity.x = 0.0;
729 pDS->ds3dl.vVelocity.y = 0.0;
730 pDS->ds3dl.vVelocity.z = 0.0;
731 pDS->ds3dl.vOrientFront.x = 0.0;
732 pDS->ds3dl.vOrientFront.y = 0.0;
733 pDS->ds3dl.vOrientFront.z = 1.0;
734 pDS->ds3dl.vOrientTop.x = 0.0;
735 pDS->ds3dl.vOrientTop.y = 1.0;
736 pDS->ds3dl.vOrientTop.z = 0.0;
737 pDS->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
738 pDS->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
739 pDS->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
741 pDS->prebuf = ds_snd_queue_max;
742 pDS->guid = *lpcGUID;
744 /* Get driver description */
746 err = IDsDriver_GetDriverDesc(drv,&(pDS->drvdesc));
748 WARN("IDsDriver_GetDriverDesc failed\n");
749 HeapFree(GetProcessHeap(),0,pDS);
754 /* if no DirectSound interface available, use WINMM API instead */
755 pDS->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
758 pDS->drvdesc.dnDevNode = wod;
760 /* Set default wave format (may need it for waveOutOpen) */
761 pDS->wfx.wFormatTag = WAVE_FORMAT_PCM;
762 /* We rely on the sound driver to return the actual sound format of
763 * the device if it does not support 22050x8x2 and is given the
764 * WAVE_DIRECTSOUND flag.
766 pDS->wfx.nSamplesPerSec = 22050;
767 pDS->wfx.wBitsPerSample = 8;
768 pDS->wfx.nChannels = 2;
769 pDS->wfx.nBlockAlign = pDS->wfx.wBitsPerSample * pDS->wfx.nChannels / 8;
770 pDS->wfx.nAvgBytesPerSec = pDS->wfx.nSamplesPerSec * pDS->wfx.nBlockAlign;
773 /* If the driver requests being opened through MMSYSTEM
774 * (which is recommended by the DDK), it is supposed to happen
775 * before the DirectSound interface is opened */
776 if (pDS->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
778 DWORD flags = CALLBACK_FUNCTION;
780 /* disable direct sound if requested */
781 if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
782 flags |= WAVE_DIRECTSOUND;
784 err = mmErr(waveOutOpen(&(pDS->hwo),
785 pDS->drvdesc.dnDevNode, &(pDS->wfx),
786 (DWORD)DSOUND_callback, (DWORD)pDS,
789 WARN("waveOutOpen failed\n");
790 HeapFree(GetProcessHeap(),0,pDS);
797 err = IDsDriver_Open(drv);
799 WARN("IDsDriver_Open failed\n");
800 HeapFree(GetProcessHeap(),0,pDS);
805 /* the driver is now open, so it's now allowed to call GetCaps */
806 err = IDsDriver_GetCaps(drv,&(pDS->drvcaps));
808 WARN("IDsDriver_GetCaps failed\n");
809 HeapFree(GetProcessHeap(),0,pDS);
815 err = mmErr(waveOutGetDevCapsA(pDS->drvdesc.dnDevNode, &woc, sizeof(woc)));
817 WARN("waveOutGetDevCaps failed\n");
818 HeapFree(GetProcessHeap(),0,pDS);
822 ZeroMemory(&pDS->drvcaps, sizeof(pDS->drvcaps));
823 if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
824 (woc.dwFormats & WAVE_FORMAT_2M08) ||
825 (woc.dwFormats & WAVE_FORMAT_4M08) ||
826 (woc.dwFormats & WAVE_FORMAT_48M08) ||
827 (woc.dwFormats & WAVE_FORMAT_96M08)) {
828 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
829 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
831 if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
832 (woc.dwFormats & WAVE_FORMAT_2M16) ||
833 (woc.dwFormats & WAVE_FORMAT_4M16) ||
834 (woc.dwFormats & WAVE_FORMAT_48M16) ||
835 (woc.dwFormats & WAVE_FORMAT_96M16)) {
836 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
837 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
839 if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
840 (woc.dwFormats & WAVE_FORMAT_2S08) ||
841 (woc.dwFormats & WAVE_FORMAT_4S08) ||
842 (woc.dwFormats & WAVE_FORMAT_48S08) ||
843 (woc.dwFormats & WAVE_FORMAT_96S08)) {
844 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
845 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
847 if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
848 (woc.dwFormats & WAVE_FORMAT_2S16) ||
849 (woc.dwFormats & WAVE_FORMAT_4S16) ||
850 (woc.dwFormats & WAVE_FORMAT_48S16) ||
851 (woc.dwFormats & WAVE_FORMAT_96S16)) {
852 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
853 pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
856 pDS->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
857 pDS->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
858 pDS->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
859 pDS->drvcaps.dwPrimaryBuffers = 1;
862 pDS->volpan.lVolume = 0;
863 pDS->volpan.lPan = 0;
864 DSOUND_RecalcVolPan(&(pDS->volpan));
866 InitializeCriticalSection(&(pDS->mixlock));
867 RtlInitializeResource(&(pDS->lock));
869 *ppDS = (LPDIRECTSOUND8)pDS;
873 /*******************************************************************************
874 * IDirectSound_IUnknown
876 static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
881 ICOM_THIS(IDirectSound_IUnknown,iface);
882 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
883 return DSOUND_QueryInterface(This->pds, riid, ppobj);
886 static ULONG WINAPI IDirectSound_IUnknown_AddRef(
889 ICOM_THIS(IDirectSound_IUnknown,iface);
890 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
891 return InterlockedIncrement(&This->ref);
894 static ULONG WINAPI IDirectSound_IUnknown_Release(
897 ICOM_THIS(IDirectSound_IUnknown,iface);
899 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
900 ulReturn = InterlockedDecrement(&This->ref);
902 IDirectSoundImpl_Release(This->pds);
903 HeapFree(GetProcessHeap(),0,This);
904 TRACE("(%p) released\n",This);
909 static ICOM_VTABLE(IUnknown) DirectSound_Unknown_Vtbl =
911 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
912 IDirectSound_IUnknown_QueryInterface,
913 IDirectSound_IUnknown_AddRef,
914 IDirectSound_IUnknown_Release
917 HRESULT WINAPI IDirectSound_IUnknown_Create(
921 IDirectSound_IUnknown * pdsunk;
922 TRACE("(%p,%p)\n",pds,ppunk);
925 ERR("invalid parameter: ppunk == NULL\n");
926 return DSERR_INVALIDPARAM;
930 ERR("invalid parameter: pds == NULL\n");
932 return DSERR_INVALIDPARAM;
935 pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
936 if (pdsunk == NULL) {
937 WARN("out of memory\n");
939 return DSERR_OUTOFMEMORY;
942 pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
946 IDirectSoundImpl_AddRef(pds);
947 *ppunk = (LPUNKNOWN)pdsunk;
952 /*******************************************************************************
953 * IDirectSound_IDirectSound
955 static HRESULT WINAPI IDirectSound_IDirectSound_QueryInterface(
960 ICOM_THIS(IDirectSound_IDirectSound,iface);
961 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
962 return DSOUND_QueryInterface(This->pds, riid, ppobj);
965 static ULONG WINAPI IDirectSound_IDirectSound_AddRef(
968 ICOM_THIS(IDirectSound_IDirectSound,iface);
969 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
970 return InterlockedIncrement(&This->ref);
973 static ULONG WINAPI IDirectSound_IDirectSound_Release(
976 ICOM_THIS(IDirectSound_IDirectSound,iface);
978 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
979 ulReturn = InterlockedDecrement(&This->ref);
981 IDirectSoundImpl_Release(This->pds);
982 HeapFree(GetProcessHeap(),0,This);
983 TRACE("(%p) released\n",This);
988 static HRESULT WINAPI IDirectSound_IDirectSound_CreateSoundBuffer(
990 LPCDSBUFFERDESC dsbd,
991 LPLPDIRECTSOUNDBUFFER ppdsb,
994 ICOM_THIS(IDirectSound_IDirectSound,iface);
995 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
996 return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
999 static HRESULT WINAPI IDirectSound_IDirectSound_GetCaps(
1000 LPDIRECTSOUND iface,
1003 ICOM_THIS(IDirectSound_IDirectSound,iface);
1004 TRACE("(%p,%p)\n",This,lpDSCaps);
1005 return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
1008 static HRESULT WINAPI IDirectSound_IDirectSound_DuplicateSoundBuffer(
1009 LPDIRECTSOUND iface,
1010 LPDIRECTSOUNDBUFFER psb,
1011 LPLPDIRECTSOUNDBUFFER ppdsb)
1013 ICOM_THIS(IDirectSound_IDirectSound,iface);
1014 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
1015 return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
1018 static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel(
1019 LPDIRECTSOUND iface,
1023 ICOM_THIS(IDirectSound_IDirectSound,iface);
1024 TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
1025 return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
1028 static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
1029 LPDIRECTSOUND iface)
1031 ICOM_THIS(IDirectSound_IDirectSound,iface);
1032 TRACE("(%p)\n", This);
1033 return IDirectSoundImpl_Compact(This->pds);
1036 static HRESULT WINAPI IDirectSound_IDirectSound_GetSpeakerConfig(
1037 LPDIRECTSOUND iface,
1038 LPDWORD lpdwSpeakerConfig)
1040 ICOM_THIS(IDirectSound_IDirectSound,iface);
1041 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
1042 return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
1045 static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
1046 LPDIRECTSOUND iface,
1049 ICOM_THIS(IDirectSound_IDirectSound,iface);
1050 TRACE("(%p,0x%08lx)\n",This,config);
1051 return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
1054 static HRESULT WINAPI IDirectSound_IDirectSound_Initialize(
1055 LPDIRECTSOUND iface,
1058 ICOM_THIS(IDirectSound_IDirectSound,iface);
1059 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
1060 return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
1063 static ICOM_VTABLE(IDirectSound) DirectSound_DirectSound_Vtbl =
1065 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1066 IDirectSound_IDirectSound_QueryInterface,
1067 IDirectSound_IDirectSound_AddRef,
1068 IDirectSound_IDirectSound_Release,
1069 IDirectSound_IDirectSound_CreateSoundBuffer,
1070 IDirectSound_IDirectSound_GetCaps,
1071 IDirectSound_IDirectSound_DuplicateSoundBuffer,
1072 IDirectSound_IDirectSound_SetCooperativeLevel,
1073 IDirectSound_IDirectSound_Compact,
1074 IDirectSound_IDirectSound_GetSpeakerConfig,
1075 IDirectSound_IDirectSound_SetSpeakerConfig,
1076 IDirectSound_IDirectSound_Initialize
1079 HRESULT WINAPI IDirectSound_IDirectSound_Create(
1081 LPDIRECTSOUND * ppds)
1083 IDirectSound_IDirectSound * pdsds;
1084 TRACE("(%p,%p)\n",pds,ppds);
1087 ERR("invalid parameter: ppds == NULL\n");
1088 return DSERR_INVALIDPARAM;
1092 ERR("invalid parameter: pds == NULL\n");
1094 return DSERR_INVALIDPARAM;
1097 pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
1098 if (pdsds == NULL) {
1099 WARN("out of memory\n");
1101 return DSERR_OUTOFMEMORY;
1104 pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
1108 IDirectSoundImpl_AddRef(pds);
1109 *ppds = (LPDIRECTSOUND)pdsds;
1114 /*******************************************************************************
1115 * IDirectSound8_IUnknown
1117 static HRESULT WINAPI IDirectSound8_IUnknown_QueryInterface(
1122 ICOM_THIS(IDirectSound_IUnknown,iface);
1123 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
1124 return DSOUND_QueryInterface8(This->pds, riid, ppobj);
1127 static ULONG WINAPI IDirectSound8_IUnknown_AddRef(
1130 ICOM_THIS(IDirectSound_IUnknown,iface);
1131 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1132 return InterlockedIncrement(&This->ref);
1135 static ULONG WINAPI IDirectSound8_IUnknown_Release(
1138 ICOM_THIS(IDirectSound_IUnknown,iface);
1140 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1141 ulReturn = InterlockedDecrement(&This->ref);
1142 if (ulReturn == 0) {
1143 IDirectSoundImpl_Release(This->pds);
1144 HeapFree(GetProcessHeap(),0,This);
1145 TRACE("(%p) released\n",This);
1150 static ICOM_VTABLE(IUnknown) DirectSound8_Unknown_Vtbl =
1152 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1153 IDirectSound8_IUnknown_QueryInterface,
1154 IDirectSound8_IUnknown_AddRef,
1155 IDirectSound8_IUnknown_Release
1158 HRESULT WINAPI IDirectSound8_IUnknown_Create(
1162 IDirectSound8_IUnknown * pdsunk;
1163 TRACE("(%p,%p)\n",pds,ppunk);
1165 if (ppunk == NULL) {
1166 ERR("invalid parameter: ppunk == NULL\n");
1167 return DSERR_INVALIDPARAM;
1171 ERR("invalid parameter: pds == NULL\n");
1173 return DSERR_INVALIDPARAM;
1176 pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
1177 if (pdsunk == NULL) {
1178 WARN("out of memory\n");
1180 return DSERR_OUTOFMEMORY;
1183 pdsunk->lpVtbl = &DirectSound8_Unknown_Vtbl;
1187 IDirectSoundImpl_AddRef(pds);
1188 *ppunk = (LPUNKNOWN)pdsunk;
1193 /*******************************************************************************
1194 * IDirectSound8_IDirectSound
1196 static HRESULT WINAPI IDirectSound8_IDirectSound_QueryInterface(
1197 LPDIRECTSOUND iface,
1201 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1202 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
1203 return DSOUND_QueryInterface8(This->pds, riid, ppobj);
1206 static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(
1207 LPDIRECTSOUND iface)
1209 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1210 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1211 return InterlockedIncrement(&This->ref);
1214 static ULONG WINAPI IDirectSound8_IDirectSound_Release(
1215 LPDIRECTSOUND iface)
1217 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1219 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1220 ulReturn = InterlockedDecrement(&This->ref);
1221 if (ulReturn == 0) {
1222 IDirectSoundImpl_Release(This->pds);
1223 HeapFree(GetProcessHeap(),0,This);
1224 TRACE("(%p) released\n",This);
1229 static HRESULT WINAPI IDirectSound8_IDirectSound_CreateSoundBuffer(
1230 LPDIRECTSOUND iface,
1231 LPCDSBUFFERDESC dsbd,
1232 LPLPDIRECTSOUNDBUFFER ppdsb,
1235 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1236 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
1237 return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
1240 static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
1241 LPDIRECTSOUND iface,
1244 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1245 TRACE("(%p,%p)\n",This,lpDSCaps);
1246 return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
1249 static HRESULT WINAPI IDirectSound8_IDirectSound_DuplicateSoundBuffer(
1250 LPDIRECTSOUND iface,
1251 LPDIRECTSOUNDBUFFER psb,
1252 LPLPDIRECTSOUNDBUFFER ppdsb)
1254 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1255 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
1256 return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
1259 static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel(
1260 LPDIRECTSOUND iface,
1264 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1265 TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
1266 return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
1269 static HRESULT WINAPI IDirectSound8_IDirectSound_Compact(
1270 LPDIRECTSOUND iface)
1272 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1273 TRACE("(%p)\n", This);
1274 return IDirectSoundImpl_Compact(This->pds);
1277 static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
1278 LPDIRECTSOUND iface,
1279 LPDWORD lpdwSpeakerConfig)
1281 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1282 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
1283 return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
1286 static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
1287 LPDIRECTSOUND iface,
1290 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1291 TRACE("(%p,0x%08lx)\n",This,config);
1292 return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
1295 static HRESULT WINAPI IDirectSound8_IDirectSound_Initialize(
1296 LPDIRECTSOUND iface,
1299 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1300 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
1301 return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
1304 static ICOM_VTABLE(IDirectSound) DirectSound8_DirectSound_Vtbl =
1306 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1307 IDirectSound8_IDirectSound_QueryInterface,
1308 IDirectSound8_IDirectSound_AddRef,
1309 IDirectSound8_IDirectSound_Release,
1310 IDirectSound8_IDirectSound_CreateSoundBuffer,
1311 IDirectSound8_IDirectSound_GetCaps,
1312 IDirectSound8_IDirectSound_DuplicateSoundBuffer,
1313 IDirectSound8_IDirectSound_SetCooperativeLevel,
1314 IDirectSound8_IDirectSound_Compact,
1315 IDirectSound8_IDirectSound_GetSpeakerConfig,
1316 IDirectSound8_IDirectSound_SetSpeakerConfig,
1317 IDirectSound8_IDirectSound_Initialize
1320 HRESULT WINAPI IDirectSound8_IDirectSound_Create(
1322 LPDIRECTSOUND * ppds)
1324 IDirectSound8_IDirectSound * pdsds;
1325 TRACE("(%p,%p)\n",pds,ppds);
1328 ERR("invalid parameter: ppds == NULL\n");
1329 return DSERR_INVALIDPARAM;
1333 ERR("invalid parameter: pds == NULL\n");
1335 return DSERR_INVALIDPARAM;
1338 pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
1339 if (pdsds == NULL) {
1340 WARN("out of memory\n");
1342 return DSERR_OUTOFMEMORY;
1345 pdsds->lpVtbl = &DirectSound8_DirectSound_Vtbl;
1349 IDirectSoundImpl_AddRef(pds);
1350 *ppds = (LPDIRECTSOUND)pdsds;
1355 /*******************************************************************************
1356 * IDirectSound8_IDirectSound8
1358 static HRESULT WINAPI IDirectSound8_IDirectSound8_QueryInterface(
1359 LPDIRECTSOUND8 iface,
1363 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1364 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
1365 return DSOUND_QueryInterface8(This->pds, riid, ppobj);
1368 static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(
1369 LPDIRECTSOUND8 iface)
1371 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1372 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1373 return InterlockedIncrement(&This->ref);
1376 static ULONG WINAPI IDirectSound8_IDirectSound8_Release(
1377 LPDIRECTSOUND8 iface)
1379 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1381 TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
1382 ulReturn = InterlockedDecrement(&This->ref);
1383 if (ulReturn == 0) {
1384 IDirectSoundImpl_Release(This->pds);
1385 HeapFree(GetProcessHeap(),0,This);
1386 TRACE("(%p) released\n",This);
1391 static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
1392 LPDIRECTSOUND8 iface,
1393 LPCDSBUFFERDESC dsbd,
1394 LPLPDIRECTSOUNDBUFFER ppdsb,
1397 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1398 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
1399 return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
1402 static HRESULT WINAPI IDirectSound8_IDirectSound8_GetCaps(
1403 LPDIRECTSOUND8 iface,
1406 ICOM_THIS(IDirectSound8_IDirectSound,iface);
1407 TRACE("(%p,%p)\n",This,lpDSCaps);
1408 return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
1411 static HRESULT WINAPI IDirectSound8_IDirectSound8_DuplicateSoundBuffer(
1412 LPDIRECTSOUND8 iface,
1413 LPDIRECTSOUNDBUFFER psb,
1414 LPLPDIRECTSOUNDBUFFER ppdsb)
1416 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1417 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
1418 return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
1421 static HRESULT WINAPI IDirectSound8_IDirectSound8_SetCooperativeLevel(
1422 LPDIRECTSOUND8 iface,
1426 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1427 TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
1428 return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
1431 static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact(
1432 LPDIRECTSOUND8 iface)
1434 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1435 TRACE("(%p)\n", This);
1436 return IDirectSoundImpl_Compact(This->pds);
1439 static HRESULT WINAPI IDirectSound8_IDirectSound8_GetSpeakerConfig(
1440 LPDIRECTSOUND8 iface,
1441 LPDWORD lpdwSpeakerConfig)
1443 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1444 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
1445 return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
1448 static HRESULT WINAPI IDirectSound8_IDirectSound8_SetSpeakerConfig(
1449 LPDIRECTSOUND8 iface,
1452 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1453 TRACE("(%p,0x%08lx)\n",This,config);
1454 return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
1457 static HRESULT WINAPI IDirectSound8_IDirectSound8_Initialize(
1458 LPDIRECTSOUND8 iface,
1461 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1462 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
1463 return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
1466 static HRESULT WINAPI IDirectSound8_IDirectSound8_VerifyCertification(
1467 LPDIRECTSOUND8 iface,
1468 LPDWORD pdwCertified)
1470 ICOM_THIS(IDirectSound8_IDirectSound8,iface);
1471 TRACE("(%p, %p)\n", This, pdwCertified);
1472 return IDirectSoundImpl_VerifyCertification(This->pds,pdwCertified);
1475 static ICOM_VTABLE(IDirectSound8) DirectSound8_DirectSound8_Vtbl =
1477 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1478 IDirectSound8_IDirectSound8_QueryInterface,
1479 IDirectSound8_IDirectSound8_AddRef,
1480 IDirectSound8_IDirectSound8_Release,
1481 IDirectSound8_IDirectSound8_CreateSoundBuffer,
1482 IDirectSound8_IDirectSound8_GetCaps,
1483 IDirectSound8_IDirectSound8_DuplicateSoundBuffer,
1484 IDirectSound8_IDirectSound8_SetCooperativeLevel,
1485 IDirectSound8_IDirectSound8_Compact,
1486 IDirectSound8_IDirectSound8_GetSpeakerConfig,
1487 IDirectSound8_IDirectSound8_SetSpeakerConfig,
1488 IDirectSound8_IDirectSound8_Initialize,
1489 IDirectSound8_IDirectSound8_VerifyCertification
1492 HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
1494 LPDIRECTSOUND8 * ppds)
1496 IDirectSound8_IDirectSound8 * pdsds;
1497 TRACE("(%p,%p)\n",pds,ppds);
1500 ERR("invalid parameter: ppds == NULL\n");
1501 return DSERR_INVALIDPARAM;
1505 ERR("invalid parameter: pds == NULL\n");
1507 return DSERR_INVALIDPARAM;
1510 pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
1511 if (pdsds == NULL) {
1512 WARN("out of memory\n");
1514 return DSERR_OUTOFMEMORY;
1517 pdsds->lpVtbl = &DirectSound8_DirectSound8_Vtbl;
1521 IDirectSoundImpl_AddRef(pds);
1522 *ppds = (LPDIRECTSOUND8)pdsds;
1527 /*******************************************************************************
1528 * DirectSoundCreate (DSOUND.1)
1530 * Creates and initializes a DirectSound interface.
1533 * lpcGUID [I] Address of the GUID that identifies the sound device.
1534 * ppDS [O] Address of a variable to receive the interface pointer.
1535 * pUnkOuter [I] Must be NULL.
1539 * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
1540 * DSERR_NODRIVER, DSERR_OUTOFMEMORY
1542 HRESULT WINAPI DirectSoundCreate(
1544 LPDIRECTSOUND *ppDS,
1545 IUnknown *pUnkOuter)
1550 TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
1553 WARN("invalid parameter: ppDS == NULL\n");
1554 return DSERR_INVALIDPARAM;
1557 /* Get dsound configuration */
1558 setup_dsound_options();
1560 /* Default device? */
1561 if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
1562 lpcGUID = &DSDEVID_DefaultPlayback;
1564 if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
1565 WARN("invalid parameter: lpcGUID\n");
1567 return DSERR_INVALIDPARAM;
1571 if (IsEqualGUID(&devGuid, &dsound->guid)) {
1572 hr = IDirectSound_IDirectSound_Create((LPDIRECTSOUND8)dsound, ppDS);
1574 IDirectSound_IDirectSound_AddRef(*ppDS);
1576 WARN("IDirectSound_IDirectSound_Create failed\n");
1578 ERR("different dsound already opened (only support one sound card at a time now)\n");
1580 hr = DSERR_ALLOCATED;
1584 hr = IDirectSoundImpl_Create(&devGuid, &pDS);
1586 hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS);
1588 hr = IDirectSound_IDirectSound_Create(pDS, ppDS);
1590 IDirectSound_IDirectSound_AddRef(*ppDS);
1592 dsound = (IDirectSoundImpl*)pDS;
1593 timeBeginPeriod(DS_TIME_RES);
1594 dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
1595 (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
1597 WARN("IDirectSound_IDirectSound_Create failed\n");
1598 IDirectSound8_Release(pDS);
1601 WARN("DSOUND_PrimaryCreate failed\n");
1602 IDirectSound8_Release(pDS);
1605 WARN("IDirectSoundImpl_Create failed\n");
1611 /*******************************************************************************
1612 * DirectSoundCreate8 (DSOUND.11)
1614 * Creates and initializes a DirectSound8 interface.
1617 * lpcGUID [I] Address of the GUID that identifies the sound device.
1618 * ppDS [O] Address of a variable to receive the interface pointer.
1619 * pUnkOuter [I] Must be NULL.
1623 * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
1624 * DSERR_NODRIVER, DSERR_OUTOFMEMORY
1626 HRESULT WINAPI DirectSoundCreate8(
1628 LPDIRECTSOUND8 *ppDS,
1629 IUnknown *pUnkOuter)
1634 TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
1637 WARN("invalid parameter: ppDS == NULL\n");
1638 return DSERR_INVALIDPARAM;
1641 /* Get dsound configuration */
1642 setup_dsound_options();
1644 /* Default device? */
1645 if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
1646 lpcGUID = &DSDEVID_DefaultPlayback;
1648 if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
1649 WARN("invalid parameter: lpcGUID\n");
1651 return DSERR_INVALIDPARAM;
1655 if (IsEqualGUID(&devGuid, &dsound->guid)) {
1656 hr = IDirectSound8_IDirectSound8_Create((LPDIRECTSOUND8)dsound, ppDS);
1658 IDirectSound8_IDirectSound8_AddRef(*ppDS);
1660 WARN("IDirectSound8_IDirectSound8_Create failed\n");
1662 ERR("different dsound already opened (only support one sound card at a time now)\n");
1664 hr = DSERR_ALLOCATED;
1668 hr = IDirectSoundImpl_Create(&devGuid, &pDS);
1670 hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS);
1672 hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS);
1674 IDirectSound8_IDirectSound8_AddRef(*ppDS);
1676 dsound = (IDirectSoundImpl*)pDS;
1677 timeBeginPeriod(DS_TIME_RES);
1678 dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
1679 (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
1681 WARN("IDirectSound8_IDirectSound8_Create failed\n");
1682 IDirectSound8_Release(pDS);
1685 WARN("DSOUND_PrimaryCreate failed\n");
1686 IDirectSound8_Release(pDS);
1689 WARN("IDirectSoundImpl_Create failed\n");