2005-06-02 12:28:34 +02:00
|
|
|
/* DirectSoundFullDuplex
|
|
|
|
*
|
|
|
|
* Copyright 1998 Marcus Meissner
|
|
|
|
* Copyright 1998 Rob Riggs
|
|
|
|
* Copyright 2000-2001 TransGaming Technologies, Inc.
|
|
|
|
* Copyright 2005 Robert Reif
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-05-18 14:49:52 +02:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-06-02 12:28:34 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#define NONAMELESSSTRUCT
|
|
|
|
#define NONAMELESSUNION
|
2009-11-24 14:22:29 +01:00
|
|
|
#define COBJMACROS
|
2005-06-02 12:28:34 +02:00
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
2005-10-17 11:24:50 +02:00
|
|
|
#include "winuser.h"
|
2005-06-02 12:28:34 +02:00
|
|
|
#include "mmsystem.h"
|
|
|
|
#include "mmddk.h"
|
|
|
|
#include "winternl.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "dsound.h"
|
|
|
|
#include "dsound_private.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
|
|
|
|
2009-11-14 14:55:58 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* IDirectSoundFullDuplex implementation structure
|
|
|
|
*/
|
|
|
|
typedef struct IDirectSoundFullDuplexImpl
|
|
|
|
{
|
2012-08-16 01:31:52 +02:00
|
|
|
IDirectSoundFullDuplex IDirectSoundFullDuplex_iface;
|
2009-11-14 14:55:58 +01:00
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
/* IDirectSoundFullDuplexImpl fields */
|
2009-11-24 14:32:23 +01:00
|
|
|
IDirectSound8 *renderer_device;
|
2009-11-24 14:22:29 +01:00
|
|
|
IDirectSoundCapture *capture_device;
|
2009-11-14 14:55:58 +01:00
|
|
|
|
|
|
|
LPUNKNOWN pUnknown;
|
|
|
|
LPDIRECTSOUND8 pDS8;
|
|
|
|
LPDIRECTSOUNDCAPTURE pDSC;
|
|
|
|
} IDirectSoundFullDuplexImpl;
|
|
|
|
|
|
|
|
typedef struct IDirectSoundFullDuplex_IUnknown {
|
|
|
|
const IUnknownVtbl *lpVtbl;
|
|
|
|
LONG ref;
|
|
|
|
IDirectSoundFullDuplexImpl *pdsfd;
|
|
|
|
} IDirectSoundFullDuplex_IUnknown;
|
|
|
|
|
|
|
|
typedef struct IDirectSoundFullDuplex_IDirectSound8 {
|
|
|
|
const IDirectSound8Vtbl *lpVtbl;
|
|
|
|
LONG ref;
|
|
|
|
IDirectSoundFullDuplexImpl *pdsfd;
|
|
|
|
} IDirectSoundFullDuplex_IDirectSound8;
|
|
|
|
|
|
|
|
typedef struct IDirectSoundFullDuplex_IDirectSoundCapture {
|
|
|
|
const IDirectSoundCaptureVtbl *lpVtbl;
|
|
|
|
LONG ref;
|
|
|
|
IDirectSoundFullDuplexImpl *pdsfd;
|
|
|
|
} IDirectSoundFullDuplex_IDirectSoundCapture;
|
|
|
|
|
2006-01-17 16:13:58 +01:00
|
|
|
/*******************************************************************************
|
|
|
|
* IUnknown
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
|
|
|
|
LPUNKNOWN iface,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID * ppobj)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
|
|
|
|
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
|
|
|
return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
|
|
|
|
LPUNKNOWN iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
|
|
|
|
ULONG ref = InterlockedIncrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
|
|
|
|
LPUNKNOWN iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
|
|
|
|
ULONG ref = InterlockedDecrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref + 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (!ref) {
|
2009-11-24 14:12:58 +01:00
|
|
|
This->pdsfd->pUnknown = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
TRACE("(%p) released\n", This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IUnknown_QueryInterface,
|
|
|
|
IDirectSoundFullDuplex_IUnknown_AddRef,
|
|
|
|
IDirectSoundFullDuplex_IUnknown_Release
|
|
|
|
};
|
|
|
|
|
2006-06-10 11:57:48 +02:00
|
|
|
static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
|
2006-01-17 16:13:58 +01:00
|
|
|
LPDIRECTSOUNDFULLDUPLEX pdsfd,
|
|
|
|
LPUNKNOWN * ppunk)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IUnknown * pdsfdunk;
|
|
|
|
TRACE("(%p,%p)\n",pdsfd,ppunk);
|
|
|
|
|
|
|
|
if (pdsfd == NULL) {
|
|
|
|
ERR("invalid parameter: pdsfd == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ppunk == NULL) {
|
|
|
|
ERR("invalid parameter: ppunk == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
|
|
|
|
if (pdsfdunk == NULL) {
|
|
|
|
WARN("out of memory\n");
|
|
|
|
*ppunk = NULL;
|
|
|
|
return DSERR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
|
|
|
|
pdsfdunk->ref = 0;
|
|
|
|
pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
|
|
|
|
|
|
|
|
*ppunk = (LPUNKNOWN)pdsfdunk;
|
|
|
|
|
|
|
|
return DS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* IDirectSoundFullDuplex_IDirectSound8
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID * ppobj)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
2012-08-16 01:31:52 +02:00
|
|
|
return IDirectSoundFullDuplex_QueryInterface(&This->pdsfd->IDirectSoundFullDuplex_iface, riid, ppobj);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
|
|
|
|
LPDIRECTSOUND8 iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
ULONG ref = InterlockedIncrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
|
|
|
|
LPDIRECTSOUND8 iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
ULONG ref = InterlockedDecrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref + 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (!ref) {
|
2009-11-24 14:12:58 +01:00
|
|
|
This->pdsfd->pDS8 = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
TRACE("(%p) released\n", This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
LPCDSBUFFERDESC dsbd,
|
|
|
|
LPLPDIRECTSOUNDBUFFER ppdsb,
|
|
|
|
LPUNKNOWN lpunk)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
LPDSCAPS lpDSCaps)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p,%p)\n",This,lpDSCaps);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
LPDIRECTSOUNDBUFFER psb,
|
|
|
|
LPLPDIRECTSOUNDBUFFER ppdsb)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
HWND hwnd,
|
|
|
|
DWORD level)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
|
|
|
|
LPDIRECTSOUND8 iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p)\n", This);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_Compact(This->pdsfd->renderer_device);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
LPDWORD lpdwSpeakerConfig)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
DWORD config)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p,0x%08x)\n",This,config);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_SetSpeakerConfig(This->pdsfd->renderer_device,config);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
LPCGUID lpcGuid)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_Initialize(This->pdsfd->renderer_device,lpcGuid);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
2009-11-24 14:10:52 +01:00
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
|
|
|
|
LPDIRECTSOUND8 iface,
|
|
|
|
DWORD *cert)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
|
|
|
|
TRACE("(%p, %p)\n", This, cert);
|
2009-11-24 14:32:23 +01:00
|
|
|
return IDirectSound8_VerifyCertification(This->pdsfd->renderer_device,cert);
|
2009-11-24 14:10:52 +01:00
|
|
|
}
|
|
|
|
|
2006-01-17 16:13:58 +01:00
|
|
|
static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_AddRef,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_Release,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_GetCaps,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_Compact,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
|
2009-11-24 14:10:52 +01:00
|
|
|
IDirectSoundFullDuplex_IDirectSound8_Initialize,
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
|
2006-01-17 16:13:58 +01:00
|
|
|
};
|
|
|
|
|
2006-06-10 11:57:48 +02:00
|
|
|
static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
|
2006-01-17 16:13:58 +01:00
|
|
|
LPDIRECTSOUNDFULLDUPLEX pdsfd,
|
|
|
|
LPDIRECTSOUND8 * ppds8)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
|
|
|
|
TRACE("(%p,%p)\n",pdsfd,ppds8);
|
|
|
|
|
|
|
|
if (pdsfd == NULL) {
|
|
|
|
ERR("invalid parameter: pdsfd == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ppds8 == NULL) {
|
|
|
|
ERR("invalid parameter: ppds8 == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
2006-02-27 13:34:01 +01:00
|
|
|
if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
|
|
|
|
WARN("not initialized\n");
|
|
|
|
*ppds8 = NULL;
|
|
|
|
return DSERR_UNINITIALIZED;
|
|
|
|
}
|
|
|
|
|
2006-01-17 16:13:58 +01:00
|
|
|
pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
|
|
|
|
if (pdsfdds8 == NULL) {
|
|
|
|
WARN("out of memory\n");
|
|
|
|
*ppds8 = NULL;
|
|
|
|
return DSERR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
|
|
|
|
pdsfdds8->ref = 0;
|
|
|
|
pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
|
|
|
|
|
|
|
|
*ppds8 = (LPDIRECTSOUND8)pdsfdds8;
|
|
|
|
|
|
|
|
return DS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* IDirectSoundFullDuplex_IDirectSoundCapture
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID * ppobj)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
2012-08-16 01:31:52 +02:00
|
|
|
return IDirectSoundFullDuplex_QueryInterface(&This->pdsfd->IDirectSoundFullDuplex_iface, riid, ppobj);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
ULONG ref = InterlockedIncrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
ULONG ref = InterlockedDecrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref + 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (!ref) {
|
2009-11-24 14:12:58 +01:00
|
|
|
This->pdsfd->pDSC = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
TRACE("(%p) released\n", This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
|
|
LPCDSCBUFFERDESC lpcDSCBufferDesc,
|
|
|
|
LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
|
|
|
|
LPUNKNOWN pUnk)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
|
2009-11-24 14:22:29 +01:00
|
|
|
return IDirectSoundCapture_CreateCaptureBuffer(This->pdsfd->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
|
|
LPDSCCAPS lpDSCCaps)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
TRACE("(%p,%p)\n",This,lpDSCCaps);
|
2009-11-24 14:22:29 +01:00
|
|
|
return IDirectSoundCapture_GetCaps(This->pdsfd->capture_device, lpDSCCaps);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
|
|
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
|
|
LPCGUID lpcGUID)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
|
|
|
|
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
|
2009-11-24 14:22:29 +01:00
|
|
|
return IDirectSoundCapture_Initialize(This->pdsfd->capture_device,lpcGUID);
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_Release,
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
|
|
|
|
};
|
|
|
|
|
2006-06-10 11:57:48 +02:00
|
|
|
static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
|
2006-01-17 16:13:58 +01:00
|
|
|
LPDIRECTSOUNDFULLDUPLEX pdsfd,
|
|
|
|
LPDIRECTSOUNDCAPTURE8 * ppdsc8)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
|
|
|
|
TRACE("(%p,%p)\n",pdsfd,ppdsc8);
|
|
|
|
|
|
|
|
if (pdsfd == NULL) {
|
|
|
|
ERR("invalid parameter: pdsfd == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ppdsc8 == NULL) {
|
|
|
|
ERR("invalid parameter: ppdsc8 == NULL\n");
|
|
|
|
return DSERR_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
|
2006-02-27 13:34:01 +01:00
|
|
|
if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
|
|
|
|
WARN("not initialized\n");
|
|
|
|
*ppdsc8 = NULL;
|
|
|
|
return DSERR_UNINITIALIZED;
|
|
|
|
}
|
|
|
|
|
2006-01-17 16:13:58 +01:00
|
|
|
pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
|
|
|
|
if (pdsfddsc == NULL) {
|
|
|
|
WARN("out of memory\n");
|
|
|
|
*ppdsc8 = NULL;
|
|
|
|
return DSERR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
|
|
|
|
pdsfddsc->ref = 0;
|
|
|
|
pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
|
|
|
|
|
|
|
|
*ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
|
|
|
|
|
|
|
|
return DS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
2012-08-16 01:31:52 +02:00
|
|
|
* IDirectSoundFullDuplex implementation
|
2006-01-17 16:13:58 +01:00
|
|
|
*/
|
2012-08-16 01:31:52 +02:00
|
|
|
static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface)
|
2006-01-17 16:13:58 +01:00
|
|
|
{
|
2012-08-16 01:31:52 +02:00
|
|
|
return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
|
|
|
|
{
|
|
|
|
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
|
2006-01-17 16:13:58 +01:00
|
|
|
ULONG ref = InterlockedIncrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1);
|
2006-01-17 16:13:58 +01:00
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(IDirectSoundFullDuplex *iface,
|
|
|
|
REFIID riid, void **ppv)
|
2005-10-27 12:18:51 +02:00
|
|
|
{
|
2012-08-16 01:31:52 +02:00
|
|
|
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
|
|
|
|
TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
|
2005-10-27 12:18:51 +02:00
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
if (ppv == NULL) {
|
2005-10-27 12:18:51 +02:00
|
|
|
WARN("invalid parameter\n");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = NULL;
|
2005-10-27 12:18:51 +02:00
|
|
|
|
2006-01-17 16:13:58 +01:00
|
|
|
if (IsEqualIID(riid, &IID_IUnknown)) {
|
|
|
|
if (!This->pUnknown) {
|
|
|
|
IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
|
|
|
|
if (!This->pUnknown) {
|
|
|
|
WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = This->pUnknown;
|
2006-01-17 16:13:58 +01:00
|
|
|
return S_OK;
|
|
|
|
} else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
|
|
|
|
IDirectSoundFullDuplexImpl_AddRef(iface);
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = &This->IDirectSoundFullDuplex_iface;
|
2006-01-17 16:13:58 +01:00
|
|
|
return S_OK;
|
2009-11-24 14:10:52 +01:00
|
|
|
} else if (IsEqualIID(riid, &IID_IDirectSound)
|
|
|
|
|| IsEqualIID(riid, &IID_IDirectSound8)) {
|
2006-01-17 16:13:58 +01:00
|
|
|
if (!This->pDS8) {
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
|
|
|
|
if (!This->pDS8) {
|
|
|
|
WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = This->pDS8;
|
2006-01-17 16:13:58 +01:00
|
|
|
return S_OK;
|
|
|
|
} else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
|
|
|
|
if (!This->pDSC) {
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
|
|
|
|
if (!This->pDSC) {
|
|
|
|
WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
|
2012-08-16 01:31:52 +02:00
|
|
|
*ppv = This->pDSC;
|
2006-01-17 16:13:58 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return E_NOINTERFACE;
|
2005-10-27 12:18:51 +02:00
|
|
|
}
|
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface)
|
2005-10-27 12:18:51 +02:00
|
|
|
{
|
2012-08-16 01:31:52 +02:00
|
|
|
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
|
2005-10-27 12:18:51 +02:00
|
|
|
ULONG ref = InterlockedDecrement(&(This->ref));
|
2006-11-12 14:40:35 +01:00
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1);
|
2005-10-27 12:18:51 +02:00
|
|
|
|
|
|
|
if (!ref) {
|
2006-01-17 16:13:58 +01:00
|
|
|
if (This->capture_device)
|
2009-11-24 14:22:29 +01:00
|
|
|
IDirectSoundCapture_Release(This->capture_device);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (This->renderer_device)
|
2009-11-24 14:32:23 +01:00
|
|
|
IDirectSound_Release(This->renderer_device);
|
2005-10-27 12:18:51 +02:00
|
|
|
HeapFree( GetProcessHeap(), 0, This );
|
|
|
|
TRACE("(%p) released\n", This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(IDirectSoundFullDuplex *iface,
|
|
|
|
const GUID *capture_dev, const GUID *render_dev, const DSCBUFFERDESC *cbufdesc,
|
|
|
|
const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level, IDirectSoundCaptureBuffer8 **dscb8,
|
|
|
|
IDirectSoundBuffer8 **dsb8)
|
2005-10-27 12:18:51 +02:00
|
|
|
{
|
2012-08-16 01:31:52 +02:00
|
|
|
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
|
2006-01-17 16:13:58 +01:00
|
|
|
HRESULT hr;
|
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This, debugstr_guid(capture_dev),
|
|
|
|
debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dscb8, dsb8);
|
|
|
|
|
|
|
|
if (!dscb8 || !dsb8)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*dscb8 = NULL;
|
|
|
|
*dsb8 = NULL;
|
2006-01-17 16:13:58 +01:00
|
|
|
|
|
|
|
if (This->renderer_device != NULL || This->capture_device != NULL) {
|
|
|
|
WARN("already initialized\n");
|
|
|
|
return DSERR_ALREADYINITIALIZED;
|
|
|
|
}
|
|
|
|
|
2012-07-19 02:00:27 +02:00
|
|
|
hr = DSOUND_Create8(&IID_IDirectSound8, (void **)&This->renderer_device);
|
2009-11-24 14:32:23 +01:00
|
|
|
if (SUCCEEDED(hr))
|
2012-08-16 01:30:16 +02:00
|
|
|
hr = IDirectSound_Initialize(This->renderer_device, render_dev);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (hr != DS_OK) {
|
|
|
|
WARN("DirectSoundDevice_Initialize() failed\n");
|
2012-08-16 01:30:16 +02:00
|
|
|
goto error;
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
2005-06-02 12:28:34 +02:00
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
IDirectSound8_SetCooperativeLevel(This->renderer_device, hwnd, level);
|
2006-01-17 16:13:58 +01:00
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, bufdesc,
|
|
|
|
(IDirectSoundBuffer**)dsb8, NULL);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (hr != DS_OK) {
|
|
|
|
WARN("IDirectSoundBufferImpl_Create() failed\n");
|
2012-08-16 01:30:16 +02:00
|
|
|
goto error;
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
2005-10-27 12:18:51 +02:00
|
|
|
|
2012-08-16 01:20:01 +02:00
|
|
|
hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, (void**)&This->capture_device);
|
2009-11-24 14:22:29 +01:00
|
|
|
if (SUCCEEDED(hr))
|
2012-08-16 01:30:16 +02:00
|
|
|
hr = IDirectSoundCapture_Initialize(This->capture_device, capture_dev);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (hr != DS_OK) {
|
|
|
|
WARN("DirectSoundCaptureDevice_Initialize() failed\n");
|
2012-08-16 01:30:16 +02:00
|
|
|
goto error;
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device, cbufdesc,
|
|
|
|
(IDirectSoundCaptureBuffer**)dscb8, NULL);
|
2006-01-17 16:13:58 +01:00
|
|
|
if (hr != DS_OK) {
|
|
|
|
WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
|
2012-08-16 01:30:16 +02:00
|
|
|
goto error;
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
2012-08-16 01:30:16 +02:00
|
|
|
return DS_OK;
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (*dsb8) {
|
|
|
|
IDirectSoundBuffer8_Release(*dsb8);
|
|
|
|
*dsb8 = NULL;
|
|
|
|
}
|
|
|
|
if (This->renderer_device) {
|
|
|
|
IDirectSound8_Release(This->renderer_device);
|
|
|
|
This->renderer_device = NULL;
|
|
|
|
}
|
|
|
|
if (*dscb8) {
|
|
|
|
IDirectSoundCaptureBuffer8_Release(*dscb8);
|
|
|
|
*dscb8 = NULL;
|
|
|
|
}
|
|
|
|
if (This->capture_device) {
|
|
|
|
IDirectSoundCapture_Release(This->capture_device);
|
|
|
|
This->capture_device = NULL;
|
|
|
|
}
|
2006-01-17 16:13:58 +01:00
|
|
|
return hr;
|
2005-10-27 12:18:51 +02:00
|
|
|
}
|
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
static const IDirectSoundFullDuplexVtbl dsfd_vtbl =
|
2005-10-27 12:18:51 +02:00
|
|
|
{
|
|
|
|
/* IUnknown methods */
|
|
|
|
IDirectSoundFullDuplexImpl_QueryInterface,
|
|
|
|
IDirectSoundFullDuplexImpl_AddRef,
|
|
|
|
IDirectSoundFullDuplexImpl_Release,
|
|
|
|
|
|
|
|
/* IDirectSoundFullDuplex methods */
|
|
|
|
IDirectSoundFullDuplexImpl_Initialize
|
|
|
|
};
|
2005-06-02 12:28:34 +02:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv)
|
2006-01-17 16:13:58 +01:00
|
|
|
{
|
2012-08-16 01:27:12 +02:00
|
|
|
IDirectSoundFullDuplexImpl *obj;
|
|
|
|
HRESULT hr;
|
2006-01-17 16:13:58 +01:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
2006-01-17 16:13:58 +01:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
*ppv = NULL;
|
|
|
|
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
|
|
|
|
if (!obj) {
|
2006-01-17 16:13:58 +01:00
|
|
|
WARN("out of memory\n");
|
|
|
|
return DSERR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
setup_dsound_options();
|
|
|
|
|
2012-08-16 01:31:52 +02:00
|
|
|
obj->IDirectSoundFullDuplex_iface.lpVtbl = &dsfd_vtbl;
|
2012-08-16 01:27:12 +02:00
|
|
|
obj->ref = 1;
|
2006-01-17 16:13:58 +01:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
hr = IUnknown_QueryInterface((IUnknown*)obj, riid, ppv);
|
|
|
|
IUnknown_Release((IUnknown*)obj);
|
2006-02-27 13:34:01 +01:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
return hr;
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
2005-06-02 12:28:34 +02:00
|
|
|
/***************************************************************************
|
|
|
|
* DirectSoundFullDuplexCreate [DSOUND.10]
|
|
|
|
*
|
|
|
|
* Create and initialize a DirectSoundFullDuplex interface.
|
|
|
|
*
|
|
|
|
* PARAMS
|
2012-08-16 01:27:12 +02:00
|
|
|
* capture_dev [I] Address of sound capture device GUID.
|
|
|
|
* render_dev [I] Address of sound render device GUID.
|
|
|
|
* cbufdesc [I] Address of capture buffer description.
|
|
|
|
* bufdesc [I] Address of render buffer description.
|
|
|
|
* hwnd [I] Handle to application window.
|
|
|
|
* level [I] Cooperative level.
|
|
|
|
* dsfd [O] Address where full duplex interface returned.
|
|
|
|
* dscb8 [0] Address where capture buffer interface returned.
|
|
|
|
* dsb8 [0] Address where render buffer interface returned.
|
|
|
|
* outer_unk [I] Must be NULL.
|
2005-06-02 12:28:34 +02:00
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: DS_OK
|
|
|
|
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
|
|
|
|
* DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
|
|
|
|
*/
|
2012-08-16 01:27:12 +02:00
|
|
|
HRESULT WINAPI DirectSoundFullDuplexCreate(const GUID *capture_dev, const GUID *render_dev,
|
|
|
|
const DSCBUFFERDESC *cbufdesc, const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level,
|
|
|
|
IDirectSoundFullDuplex **dsfd, IDirectSoundCaptureBuffer8 **dscb8,
|
|
|
|
IDirectSoundBuffer8 **dsb8, IUnknown *outer_unk)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
2005-06-02 12:28:34 +02:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n", debugstr_guid(capture_dev),
|
|
|
|
debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dsfd, dscb8, dsb8,
|
|
|
|
outer_unk);
|
2005-06-02 12:28:34 +02:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
if (!dsfd)
|
2006-01-17 16:13:58 +01:00
|
|
|
return DSERR_INVALIDPARAM;
|
2012-08-16 01:27:12 +02:00
|
|
|
if (outer_unk) {
|
|
|
|
*dsfd = NULL;
|
|
|
|
return DSERR_NOAGGREGATION;
|
2005-06-02 12:28:34 +02:00
|
|
|
}
|
2006-01-17 16:13:58 +01:00
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
hr = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (void**)dsfd);
|
|
|
|
if (hr == DS_OK) {
|
|
|
|
hr = IDirectSoundFullDuplex_Initialize(*dsfd, capture_dev, render_dev, cbufdesc, bufdesc,
|
|
|
|
hwnd, level, dscb8, dsb8);
|
|
|
|
if (hr != DS_OK) {
|
|
|
|
IDirectSoundFullDuplex_Release(*dsfd);
|
|
|
|
*dsfd = NULL;
|
|
|
|
WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
|
|
|
|
}
|
2006-01-17 16:13:58 +01:00
|
|
|
}
|
|
|
|
|
2012-08-16 01:27:12 +02:00
|
|
|
return hr;
|
2005-06-02 12:28:34 +02:00
|
|
|
}
|