reactos/dll/directx/dsound_new/capture.c

339 lines
8.7 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Configuration of network devices
* FILE: dll/directx/dsound_new/capture.c
* PURPOSE: Implement IDirectSoundCapture
*
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "precomp.h"
typedef struct
{
IDirectSoundCaptureVtbl *lpVtbl;
LONG ref;
GUID DeviceGUID;
BOOL bInitialized;
LPFILTERINFO Filter;
}CDirectSoundCaptureImpl, *LPCDirectSoundCaptureImpl;
HRESULT
WINAPI
CDirectSoundCapture_fnQueryInterface(
LPDIRECTSOUNDCAPTURE8 iface,
REFIID riid,
LPVOID * ppobj)
{
LPOLESTR pStr;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
/* check if the interface is supported */
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDirectSoundCapture))
{
*ppobj = (LPVOID)&This->lpVtbl;
InterlockedIncrement(&This->ref);
return S_OK;
}
/* unsupported interface */
if (SUCCEEDED(StringFromIID(riid, &pStr)))
{
DPRINT("No Interface for class %s\n", pStr);
CoTaskMemFree(pStr);
}
return E_NOINTERFACE;
}
ULONG
WINAPI
CDirectSoundCapture_fnAddRef(
LPDIRECTSOUNDCAPTURE8 iface)
{
ULONG ref;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
/* increment reference count */
ref = InterlockedIncrement(&This->ref);
return ref;
}
ULONG
WINAPI
CDirectSoundCapture_fnRelease(
LPDIRECTSOUNDCAPTURE8 iface)
{
ULONG ref;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
/* release reference count */
ref = InterlockedDecrement(&(This->ref));
if (!ref)
{
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
HRESULT
WINAPI
CDirectSoundCapture_fnCreateCaptureBuffer(
LPDIRECTSOUNDCAPTURE8 iface,
LPCDSCBUFFERDESC lpcDSBufferDesc,
LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer,
LPUNKNOWN pUnkOuter)
{
HRESULT hResult;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
if (!This->bInitialized)
{
/* object not yet initialized */
return DSERR_UNINITIALIZED;
}
if (!lpcDSBufferDesc || !ppDSCBuffer || pUnkOuter != NULL)
{
/* invalid param */
return DSERR_INVALIDPARAM;
}
/* check buffer description */
if ((lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC1)) ||
lpcDSBufferDesc->dwReserved != 0 || lpcDSBufferDesc->dwBufferBytes == 0 || lpcDSBufferDesc->lpwfxFormat == NULL)
{
/* invalid buffer description */
return DSERR_INVALIDPARAM;
}
DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize);
hResult = NewDirectSoundCaptureBuffer((LPDIRECTSOUNDCAPTUREBUFFER8*)ppDSCBuffer, This->Filter, lpcDSBufferDesc);
return hResult;
}
HRESULT
WINAPI
CDirectSoundCapture_fnGetCaps(
LPDIRECTSOUNDCAPTURE8 iface,
LPDSCCAPS pDSCCaps)
{
WAVEINCAPSW Caps;
MMRESULT Result;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
if (!This->bInitialized)
{
/* object not yet initialized */
return DSERR_UNINITIALIZED;
}
if (!pDSCCaps)
{
/* invalid param */
return DSERR_INVALIDPARAM;
}
if (pDSCCaps->dwSize != sizeof(DSCCAPS))
{
/* invalid param */
return DSERR_INVALIDPARAM;
}
/* We are certified ;) */
pDSCCaps->dwFlags = DSCCAPS_CERTIFIED;
ASSERT(This->Filter);
Result = waveInGetDevCapsW(This->Filter->MappedId[0], &Caps, sizeof(WAVEINCAPSW));
if (Result != MMSYSERR_NOERROR)
{
/* failed */
DPRINT("waveInGetDevCapsW for device %u failed with %x\n", This->Filter->MappedId[0], Result);
return DSERR_UNSUPPORTED;
}
pDSCCaps->dwFormats = Caps.dwFormats;
pDSCCaps->dwChannels = Caps.wChannels;
return DS_OK;
}
HRESULT
WINAPI
CDirectSoundCapture_fnInitialize(
LPDIRECTSOUNDCAPTURE8 iface,
LPCGUID pcGuidDevice)
{
GUID DeviceGuid;
LPOLESTR pGuidStr;
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
/* sanity check */
ASSERT(RootInfo);
if (This->bInitialized)
{
/* object has already been initialized */
return DSERR_ALREADYINITIALIZED;
}
/* fixme mutual exclusion */
if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
{
/* use default playback device id */
pcGuidDevice = &DSDEVID_DefaultCapture;
}
if (IsEqualIID(pcGuidDevice, &DSDEVID_DefaultVoicePlayback) || IsEqualIID(pcGuidDevice, &DSDEVID_DefaultPlayback))
{
/* this has to be a winetest */
return DSERR_NODRIVER;
}
/* now verify the guid */
if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
{
if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
{
DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
CoTaskMemFree(pGuidStr);
}
return DSERR_INVALIDPARAM;
}
if (FindDeviceByGuid(&DeviceGuid, &This->Filter))
{
This->bInitialized = TRUE;
return DS_OK;
}
DPRINT("Failed to find device\n");
return DSERR_INVALIDPARAM;
}
static IDirectSoundCaptureVtbl vt_DirectSoundCapture =
{
/* IUnknown methods */
CDirectSoundCapture_fnQueryInterface,
CDirectSoundCapture_fnAddRef,
CDirectSoundCapture_fnRelease,
CDirectSoundCapture_fnCreateCaptureBuffer,
CDirectSoundCapture_fnGetCaps,
CDirectSoundCapture_fnInitialize
};
HRESULT
InternalDirectSoundCaptureCreate(
LPCGUID lpcGUID,
LPDIRECTSOUNDCAPTURE8 *ppDS,
IUnknown *pUnkOuter)
{
LPCDirectSoundCaptureImpl This;
HRESULT hr;
if (!ppDS || pUnkOuter != NULL)
{
/* invalid parameter passed */
return DSERR_INVALIDPARAM;
}
/* allocate CDirectSoundCaptureImpl struct */
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl));
if (!This)
{
/* not enough memory */
return DSERR_OUTOFMEMORY;
}
/* initialize IDirectSoundCapture object */
This->ref = 1;
This->lpVtbl = &vt_DirectSoundCapture;
/* initialize direct sound interface */
hr = IDirectSoundCapture_Initialize((LPDIRECTSOUNDCAPTURE8)&This->lpVtbl, lpcGUID);
/* check for success */
if (!SUCCEEDED(hr))
{
/* failed */
DPRINT("Failed to initialize DirectSoundCapture object with %x\n", hr);
IDirectSoundCapture_Release((LPDIRECTSOUND8)&This->lpVtbl);
return hr;
}
/* store result */
*ppDS = (LPDIRECTSOUNDCAPTURE8)&This->lpVtbl;
DPRINT("DirectSoundCapture object %p\n", *ppDS);
return DS_OK;
}
HRESULT
CALLBACK
NewDirectSoundCapture(
IUnknown* pUnkOuter,
REFIID riid,
LPVOID* ppvObject)
{
LPOLESTR pStr;
LPCDirectSoundCaptureImpl This;
/* check requested interface */
if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSoundCapture) && !IsEqualIID(riid, &IID_IDirectSoundCapture8))
{
*ppvObject = 0;
StringFromIID(riid, &pStr);
DPRINT("NewDirectSoundCapture does not support Interface %ws\n", pStr);
CoTaskMemFree(pStr);
return E_NOINTERFACE;
}
/* allocate CDirectSoundCaptureImpl struct */
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl));
if (!This)
{
/* not enough memory */
return DSERR_OUTOFMEMORY;
}
/* initialize object */
This->ref = 1;
This->lpVtbl = &vt_DirectSoundCapture;
This->bInitialized = FALSE;
*ppvObject = (LPVOID)&This->lpVtbl;
return S_OK;
}
HRESULT
WINAPI
DirectSoundCaptureCreate(
LPCGUID lpcGUID,
LPDIRECTSOUNDCAPTURE *ppDSC,
LPUNKNOWN pUnkOuter)
{
return InternalDirectSoundCaptureCreate(lpcGUID, (LPDIRECTSOUNDCAPTURE8*)ppDSC, pUnkOuter);
}
HRESULT
WINAPI
DirectSoundCaptureCreate8(
LPCGUID lpcGUID,
LPDIRECTSOUNDCAPTURE8 *ppDSC8,
LPUNKNOWN pUnkOuter)
{
return InternalDirectSoundCaptureCreate(lpcGUID, ppDSC8, pUnkOuter);
}