mirror of
https://github.com/reactos/wine.git
synced 2024-12-01 15:40:43 +00:00
935e3df35c
separate files. Split primary buffer and secondary buffer interfaces into separate implementations. Made the primary buffer state part of the dsound object, so primary buffer objects can be created and refcounted independently. Made the interfaces follow COM aggregation rules more closely. Converted the dsound critical section to a R/W lock to improve potential remixing concurrency. Fixed various bugs and refcounting issues.
538 lines
13 KiB
C
538 lines
13 KiB
C
/* DirectSoundCapture
|
|
*
|
|
* Copyright 1998 Marcus Meissner
|
|
* Copyright 1998 Rob Riggs
|
|
* Copyright 2000-2001 TransGaming Technologies, Inc.
|
|
*
|
|
* 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
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
/*
|
|
* TODO:
|
|
* Implement DirectSoundCapture API
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
#include "winerror.h"
|
|
#include "mmsystem.h"
|
|
#include "wine/debug.h"
|
|
#include "dsound.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
|
|
|
/*****************************************************************************
|
|
* Predeclare the interface implementation structures
|
|
*/
|
|
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
|
|
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
|
|
|
|
|
|
/*****************************************************************************
|
|
* IDirectSoundCapture implementation structure
|
|
*/
|
|
struct IDirectSoundCaptureImpl
|
|
{
|
|
/* IUnknown fields */
|
|
ICOM_VFIELD(IDirectSoundCapture);
|
|
DWORD ref;
|
|
|
|
/* IDirectSoundCaptureImpl fields */
|
|
CRITICAL_SECTION lock;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
* IDirectSoundCapture implementation structure
|
|
*/
|
|
struct IDirectSoundCaptureBufferImpl
|
|
{
|
|
/* IUnknown fields */
|
|
ICOM_VFIELD(IDirectSoundCaptureBuffer8);
|
|
DWORD ref;
|
|
|
|
/* IDirectSoundCaptureBufferImpl fields */
|
|
CRITICAL_SECTION lock;
|
|
};
|
|
|
|
|
|
static HRESULT DSOUND_CreateDirectSoundCapture( LPVOID* ppobj );
|
|
static HRESULT DSOUND_CreateDirectSoundCaptureBuffer( LPCDSCBUFFERDESC lpcDSCBufferDesc, LPVOID* ppobj );
|
|
|
|
static ICOM_VTABLE(IDirectSoundCapture) dscvt;
|
|
static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt;
|
|
|
|
|
|
/***************************************************************************
|
|
* DirectSoundCaptureCreate [DSOUND.6]
|
|
*
|
|
* Create and initialize a DirectSoundCapture interface
|
|
*
|
|
* RETURNS
|
|
* Success: DS_OK
|
|
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
|
|
* DSERR_OUTOFMEMORY
|
|
*/
|
|
HRESULT WINAPI DirectSoundCaptureCreate8(
|
|
LPCGUID lpcGUID,
|
|
LPDIRECTSOUNDCAPTURE* lplpDSC,
|
|
LPUNKNOWN pUnkOuter )
|
|
{
|
|
TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), lplpDSC, pUnkOuter);
|
|
|
|
if( pUnkOuter ) {
|
|
return DSERR_NOAGGREGATION;
|
|
}
|
|
|
|
/* Default device? */
|
|
if ( !lpcGUID ||
|
|
IsEqualGUID(lpcGUID, &DSDEVID_DefaultCapture) ||
|
|
IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoiceCapture) ) {
|
|
return DSOUND_CreateDirectSoundCapture( (LPVOID*)lplpDSC );
|
|
}
|
|
|
|
FIXME( "Unknown GUID %s\n", debugstr_guid(lpcGUID) );
|
|
*lplpDSC = NULL;
|
|
|
|
return DSERR_OUTOFMEMORY;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* DirectSoundCaptureEnumerateA [DSOUND.7]
|
|
*
|
|
* Enumerate all DirectSound drivers installed in the system
|
|
*
|
|
* RETURNS
|
|
* Success: DS_OK
|
|
* Failure: DSERR_INVALIDPARAM
|
|
*/
|
|
HRESULT WINAPI DirectSoundCaptureEnumerateA(
|
|
LPDSENUMCALLBACKA lpDSEnumCallback,
|
|
LPVOID lpContext)
|
|
{
|
|
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
|
|
|
|
if ( lpDSEnumCallback )
|
|
lpDSEnumCallback(NULL,"WINE Primary Sound Capture Driver",
|
|
"SoundCap",lpContext);
|
|
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* DirectSoundCaptureEnumerateW [DSOUND.8]
|
|
*
|
|
* Enumerate all DirectSound drivers installed in the system
|
|
*
|
|
* RETURNS
|
|
* Success: DS_OK
|
|
* Failure: DSERR_INVALIDPARAM
|
|
*/
|
|
HRESULT WINAPI DirectSoundCaptureEnumerateW(
|
|
LPDSENUMCALLBACKW lpDSEnumCallback,
|
|
LPVOID lpContext)
|
|
{
|
|
FIXME("(%p,%p):stub\n", lpDSEnumCallback, lpContext );
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT
|
|
DSOUND_CreateDirectSoundCapture( LPVOID* ppobj )
|
|
{
|
|
*ppobj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( IDirectSoundCaptureImpl ) );
|
|
|
|
if ( *ppobj == NULL ) {
|
|
return DSERR_OUTOFMEMORY;
|
|
}
|
|
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureImpl,*ppobj);
|
|
|
|
This->ref = 1;
|
|
ICOM_VTBL(This) = &dscvt;
|
|
|
|
InitializeCriticalSection( &This->lock );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureImpl_QueryInterface(
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
REFIID riid,
|
|
LPVOID* ppobj )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
FIXME( "(%p)->(%s,%p): stub\n", This, debugstr_guid(riid), ppobj );
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface )
|
|
{
|
|
ULONG uRef;
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
EnterCriticalSection( &This->lock );
|
|
|
|
TRACE( "(%p) was 0x%08lx\n", This, This->ref );
|
|
uRef = ++(This->ref);
|
|
|
|
LeaveCriticalSection( &This->lock );
|
|
|
|
return uRef;
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface )
|
|
{
|
|
ULONG uRef;
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
EnterCriticalSection( &This->lock );
|
|
|
|
TRACE( "(%p) was 0x%08lx\n", This, This->ref );
|
|
uRef = --(This->ref);
|
|
|
|
LeaveCriticalSection( &This->lock );
|
|
|
|
if ( uRef == 0 ) {
|
|
DeleteCriticalSection( &This->lock );
|
|
HeapFree( GetProcessHeap(), 0, This );
|
|
}
|
|
|
|
return uRef;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureImpl_CreateCaptureBuffer(
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
LPCDSCBUFFERDESC lpcDSCBufferDesc,
|
|
LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
|
|
LPUNKNOWN pUnk )
|
|
{
|
|
HRESULT hr;
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
TRACE( "(%p)->(%p,%p,%p)\n", This, lpcDSCBufferDesc, lplpDSCaptureBuffer, pUnk );
|
|
|
|
if ( pUnk ) {
|
|
return DSERR_INVALIDPARAM;
|
|
}
|
|
|
|
hr = DSOUND_CreateDirectSoundCaptureBuffer( lpcDSCBufferDesc, (LPVOID*)lplpDSCaptureBuffer );
|
|
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureImpl_GetCaps(
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
LPDSCCAPS lpDSCCaps )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p): stub\n", This, lpDSCCaps );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureImpl_Initialize(
|
|
LPDIRECTSOUNDCAPTURE iface,
|
|
LPCGUID lpcGUID )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p): stub\n", This, lpcGUID );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
|
|
static ICOM_VTABLE(IDirectSoundCapture) dscvt =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
/* IUnknown methods */
|
|
IDirectSoundCaptureImpl_QueryInterface,
|
|
IDirectSoundCaptureImpl_AddRef,
|
|
IDirectSoundCaptureImpl_Release,
|
|
|
|
/* IDirectSoundCapture methods */
|
|
IDirectSoundCaptureImpl_CreateCaptureBuffer,
|
|
IDirectSoundCaptureImpl_GetCaps,
|
|
IDirectSoundCaptureImpl_Initialize
|
|
};
|
|
|
|
static HRESULT
|
|
DSOUND_CreateDirectSoundCaptureBuffer( LPCDSCBUFFERDESC lpcDSCBufferDesc, LPVOID* ppobj )
|
|
{
|
|
|
|
FIXME( "(%p,%p): ignoring lpcDSCBufferDesc\n", lpcDSCBufferDesc, ppobj );
|
|
|
|
*ppobj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( IDirectSoundCaptureBufferImpl ) );
|
|
|
|
if ( *ppobj == NULL ) {
|
|
return DSERR_OUTOFMEMORY;
|
|
}
|
|
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,*ppobj);
|
|
|
|
This->ref = 1;
|
|
ICOM_VTBL(This) = &dscbvt;
|
|
|
|
InitializeCriticalSection( &This->lock );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_QueryInterface(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
REFIID riid,
|
|
LPVOID* ppobj )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%s,%p): stub\n", This, debugstr_guid(riid), ppobj );
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
|
|
{
|
|
ULONG uRef;
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
EnterCriticalSection( &This->lock );
|
|
|
|
TRACE( "(%p) was 0x%08lx\n", This, This->ref );
|
|
uRef = ++(This->ref);
|
|
|
|
LeaveCriticalSection( &This->lock );
|
|
|
|
return uRef;
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
|
|
{
|
|
ULONG uRef;
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
EnterCriticalSection( &This->lock );
|
|
|
|
TRACE( "(%p) was 0x%08lx\n", This, This->ref );
|
|
uRef = --(This->ref);
|
|
|
|
LeaveCriticalSection( &This->lock );
|
|
|
|
if ( uRef == 0 ) {
|
|
DeleteCriticalSection( &This->lock );
|
|
HeapFree( GetProcessHeap(), 0, This );
|
|
}
|
|
|
|
return uRef;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetCaps(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPDSCBCAPS lpDSCBCaps )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p): stub\n", This, lpDSCBCaps );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetCurrentPosition(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPDWORD lpdwCapturePosition,
|
|
LPDWORD lpdwReadPosition )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p,%p): stub\n", This, lpdwCapturePosition, lpdwReadPosition );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetFormat(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPWAVEFORMATEX lpwfxFormat,
|
|
DWORD dwSizeAllocated,
|
|
LPDWORD lpdwSizeWritten )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p,0x%08lx,%p): stub\n", This, lpwfxFormat, dwSizeAllocated, lpdwSizeWritten );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetStatus(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPDWORD lpdwStatus )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p): stub\n", This, lpdwStatus );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_Initialize(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPDIRECTSOUNDCAPTURE lpDSC,
|
|
LPCDSCBUFFERDESC lpcDSCBDesc )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p,%p): stub\n", This, lpDSC, lpcDSCBDesc );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_Lock(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
DWORD dwReadCusor,
|
|
DWORD dwReadBytes,
|
|
LPVOID* lplpvAudioPtr1,
|
|
LPDWORD lpdwAudioBytes1,
|
|
LPVOID* lplpvAudioPtr2,
|
|
LPDWORD lpdwAudioBytes2,
|
|
DWORD dwFlags )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%08lu,%08lu,%p,%p,%p,%p,0x%08lx): stub\n", This, dwReadCusor, dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2, lpdwAudioBytes2, dwFlags );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_Start(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
DWORD dwFlags )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(0x%08lx): stub\n", This, dwFlags );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p): stub\n", This );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_Unlock(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
LPVOID lpvAudioPtr1,
|
|
DWORD dwAudioBytes1,
|
|
LPVOID lpvAudioPtr2,
|
|
DWORD dwAudioBytes2 )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%p,%08lu,%p,%08lu): stub\n", This, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2 );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetObjectInPath(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
REFGUID rguidObject,
|
|
DWORD dwIndex,
|
|
REFGUID rguidInterface,
|
|
LPVOID* ppObject )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%s,%lu,%s,%p): stub\n", This, debugstr_guid(rguidObject), dwIndex, debugstr_guid(rguidInterface), ppObject );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IDirectSoundCaptureBufferImpl_GetFXStatus(
|
|
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
|
DWORD dwFXCount,
|
|
LPDWORD pdwFXStatus )
|
|
{
|
|
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
|
|
|
|
FIXME( "(%p)->(%lu,%p): stub\n", This, dwFXCount, pdwFXStatus );
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
|
|
static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
/* IUnknown methods */
|
|
IDirectSoundCaptureBufferImpl_QueryInterface,
|
|
IDirectSoundCaptureBufferImpl_AddRef,
|
|
IDirectSoundCaptureBufferImpl_Release,
|
|
|
|
/* IDirectSoundCaptureBuffer methods */
|
|
IDirectSoundCaptureBufferImpl_GetCaps,
|
|
IDirectSoundCaptureBufferImpl_GetCurrentPosition,
|
|
IDirectSoundCaptureBufferImpl_GetFormat,
|
|
IDirectSoundCaptureBufferImpl_GetStatus,
|
|
IDirectSoundCaptureBufferImpl_Initialize,
|
|
IDirectSoundCaptureBufferImpl_Lock,
|
|
IDirectSoundCaptureBufferImpl_Start,
|
|
IDirectSoundCaptureBufferImpl_Stop,
|
|
IDirectSoundCaptureBufferImpl_Unlock,
|
|
|
|
/* IDirectSoundCaptureBuffer methods */
|
|
IDirectSoundCaptureBufferImpl_GetObjectInPath,
|
|
IDirectSoundCaptureBufferImpl_GetFXStatus
|
|
};
|