Fixed code to handle full duplex properly.

Added support for capture driver (disabled).
Fixed direct sound capture test to handle notifications properly.
This commit is contained in:
Robert Reif 2003-03-04 02:12:34 +00:00 committed by Alexandre Julliard
parent f851a860fc
commit 15cc17fbcf
6 changed files with 473 additions and 290 deletions

View File

@ -296,7 +296,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) {
ICOM_THIS(IDirectSoundBufferImpl,iface); ICOM_THIS(IDirectSoundBufferImpl,iface);
DWORD ref; DWORD ref;
TRACE("(%p) ref was %ld, thread is %lx\n",This, This->ref, GetCurrentThreadId()); TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
ref = InterlockedIncrement(&(This->ref)); ref = InterlockedIncrement(&(This->ref));
if (!ref) { if (!ref) {
@ -309,7 +309,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
int i; int i;
DWORD ref; DWORD ref;
TRACE("(%p) ref was %ld, thread is %lx\n",This, This->ref, GetCurrentThreadId()); TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
ref = InterlockedDecrement(&(This->ref)); ref = InterlockedDecrement(&(This->ref));
if (ref) return ref; if (ref) return ref;
@ -472,7 +472,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(
LPDIRECTSOUNDBUFFER8 iface,LPDWORD status LPDIRECTSOUNDBUFFER8 iface,LPDWORD status
) { ) {
ICOM_THIS(IDirectSoundBufferImpl,iface); ICOM_THIS(IDirectSoundBufferImpl,iface);
TRACE("(%p,%p), thread is %lx\n",This,status,GetCurrentThreadId()); TRACE("(%p,%p), thread is %04lx\n",This,status,GetCurrentThreadId());
if (status == NULL) if (status == NULL)
return DSERR_INVALIDPARAM; return DSERR_INVALIDPARAM;
@ -682,7 +682,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
ICOM_THIS(IDirectSoundBufferImpl,iface); ICOM_THIS(IDirectSoundBufferImpl,iface);
DWORD probably_valid_to; DWORD probably_valid_to;
TRACE("(%p,%p,%ld,%p,%ld):stub\n", This,p1,x1,p2,x2); TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
#if 0 #if 0
/* Preprocess 3D buffers... */ /* Preprocess 3D buffers... */
@ -853,6 +853,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
return E_FAIL; return E_FAIL;
} }
if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
IDirectSoundBuffer8_AddRef(iface);
*ppobj = This;
return NO_ERROR;
}
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) ); FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
*ppobj = NULL; *ppobj = NULL;

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,7 @@ HRESULT mmErr(UINT err)
return DS_OK; return DS_OK;
case MMSYSERR_ALLOCATED: case MMSYSERR_ALLOCATED:
return DSERR_ALLOCATED; return DSERR_ALLOCATED;
case MMSYSERR_ERROR:
case MMSYSERR_INVALHANDLE: case MMSYSERR_INVALHANDLE:
case WAVERR_STILLPLAYING: case WAVERR_STILLPLAYING:
return DSERR_GENERIC; /* FIXME */ return DSERR_GENERIC; /* FIXME */
@ -122,12 +123,13 @@ int ds_snd_queue_min = DS_SND_QUEUE_MIN;
inline static void enumerate_devices(LPDSENUMCALLBACKA lpDSEnumCallback, inline static void enumerate_devices(LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext) LPVOID lpContext)
{ {
if (lpDSEnumCallback != NULL) if (lpDSEnumCallback != NULL) {
if (lpDSEnumCallback(NULL, "Primary DirectSound Driver", TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"sound\",%p)\n",
"sound", lpContext)) debugstr_guid(&DSDEVID_DefaultPlayback),lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_WinePlayback,
"WINE DirectSound", "sound", lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback,
lpContext); "WINE DirectSound", "sound", lpContext);
}
} }
@ -147,7 +149,7 @@ inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
* Setup the dsound options. * Setup the dsound options.
*/ */
inline static void setup_dsound_options(void) void setup_dsound_options(void)
{ {
char buffer[MAX_PATH+1]; char buffer[MAX_PATH+1];
HKEY hkey, appkey = 0; HKEY hkey, appkey = 0;

View File

@ -39,6 +39,7 @@ typedef struct IDirectSoundImpl IDirectSoundImpl;
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl; typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl; typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl; typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl; typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl; typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl; typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
@ -137,32 +138,31 @@ struct IDirectSoundCaptureImpl
DWORD ref; DWORD ref;
/* IDirectSoundCaptureImpl fields */ /* IDirectSoundCaptureImpl fields */
GUID guid; GUID guid;
BOOL initialized; BOOL initialized;
/* DirectSound driver stuff */ /* DirectSound driver stuff */
PIDSCDRIVER driver; PIDSCDRIVER driver;
DSDRIVERDESC drvdesc; DSDRIVERDESC drvdesc;
DSDRIVERCAPS drvcaps; DSCDRIVERCAPS drvcaps;
PIDSDRIVERBUFFER hwbuf; PIDSCDRIVERBUFFER hwbuf;
/* wave driver info */ /* wave driver info */
HWAVEIN hwi; HWAVEIN hwi;
/* more stuff */ /* more stuff */
LPBYTE buffer; LPBYTE buffer;
DWORD buflen; DWORD buflen;
DWORD read_position; DWORD read_position;
/* FIXME: this should be a pointer because it can be bigger */ /* FIXME: this should be a pointer because it can be bigger */
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
DWORD formats; IDirectSoundCaptureBufferImpl* capture_buffer;
DWORD channels; DWORD state;
IDirectSoundCaptureBufferImpl* capture_buffer;
DWORD state;
LPWAVEHDR pwave; LPWAVEHDR pwave;
int index; int nrofpwaves;
int index;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
}; };
@ -171,18 +171,30 @@ struct IDirectSoundCaptureImpl
*/ */
struct IDirectSoundCaptureBufferImpl struct IDirectSoundCaptureBufferImpl
{ {
/* IUnknown fields */ /* IUnknown fields */
ICOM_VFIELD(IDirectSoundCaptureBuffer8); ICOM_VFIELD(IDirectSoundCaptureBuffer8);
DWORD ref; DWORD ref;
/* IDirectSoundCaptureBufferImpl fields */ /* IDirectSoundCaptureBufferImpl fields */
IDirectSoundCaptureImpl* dsound; IDirectSoundCaptureImpl* dsound;
CRITICAL_SECTION lock; /* FIXME: don't need this */
/* FIXME: don't need this */ LPDSCBUFFERDESC pdscbd;
LPDSCBUFFERDESC pdscbd; LPDSBPOSITIONNOTIFY notifies;
LPDSBPOSITIONNOTIFY notifies; int nrofnotifies;
int nrofnotifies; DWORD flags;
DWORD flags; };
/*****************************************************************************
* IDirectSoundFullDuplex implementation structure
*/
struct IDirectSoundFullDuplexImpl
{
/* IUnknown fields */
ICOM_VFIELD(IDirectSoundFullDuplex);
DWORD ref;
/* IDirectSoundFullDuplexImpl fields */
CRITICAL_SECTION lock;
}; };
/***************************************************************************** /*****************************************************************************
@ -195,7 +207,7 @@ struct IDirectSoundNotifyImpl
DWORD ref; DWORD ref;
/* IDirectSoundNotifyImpl fields */ /* IDirectSoundNotifyImpl fields */
IDirectSoundBufferImpl* dsb; IDirectSoundBufferImpl* dsb;
IDirectSoundCaptureBufferImpl* dscb; IDirectSoundCaptureBufferImpl* dscb;
}; };
/***************************************************************************** /*****************************************************************************
@ -288,6 +300,7 @@ void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, D
#define DSOUND_FREQSHIFT (14) #define DSOUND_FREQSHIFT (14)
extern IDirectSoundImpl* dsound; extern IDirectSoundImpl* dsound;
extern IDirectSoundCaptureImpl* dsound_capture;
struct PrimaryBuffer { struct PrimaryBuffer {
DWORD ref; DWORD ref;
@ -297,3 +310,4 @@ struct PrimaryBuffer {
extern ICOM_VTABLE(IDirectSoundNotify) dsnvt; extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
extern HRESULT mmErr(UINT err); extern HRESULT mmErr(UINT err);
extern void setup_dsound_options(void);

View File

@ -901,7 +901,11 @@ void DSOUND_PerformMix(void)
/* DSOUND_callback may need this lock */ /* DSOUND_callback may need this lock */
LeaveCriticalSection(&(dsound->mixlock)); LeaveCriticalSection(&(dsound->mixlock));
#endif #endif
DSOUND_PrimaryStop(dsound); /* FIXME: OSS doesn't allow independent stopping of input and output streams */
/* in full duplex mode so don't stop when capturing. This should be moved into */
/* the OSS driver someday. */
if ( (dsound_capture == NULL) || (dsound_capture->state != STATE_CAPTURING) )
DSOUND_PrimaryStop(dsound);
#ifdef SYNC_CALLBACK #ifdef SYNC_CALLBACK
EnterCriticalSection(&(dsound->mixlock)); EnterCriticalSection(&(dsound->mixlock));
#endif #endif

View File

@ -476,6 +476,7 @@ typedef struct {
DWORD buffer_size; DWORD buffer_size;
DWORD read; DWORD read;
DWORD offset; DWORD offset;
DWORD size;
DWORD last_pos; DWORD last_pos;
} capture_state_t; } capture_state_t;
@ -486,16 +487,13 @@ static int capture_buffer_service(capture_state_t* state)
LPVOID ptr1,ptr2; LPVOID ptr1,ptr2;
DWORD len1,len2; DWORD len1,len2;
DWORD capture_pos,read_pos; DWORD capture_pos,read_pos;
LONG size;
rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,&read_pos); rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,&read_pos);
ok(rc==DS_OK,"GetCurrentPosition failed: 0x%lx\n",rc); ok(rc==DS_OK,"GetCurrentPosition failed: 0x%lx\n",rc);
if (rc!=DS_OK) if (rc!=DS_OK)
return 0; return 0;
size = state->wfx->nAvgBytesPerSec/NOTIFICATIONS; rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,&ptr1,&len1,&ptr2,&len2,0);
rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,size,&ptr1,&len1,&ptr2,&len2,0);
ok(rc==DS_OK,"Lock failed: 0x%lx\n",rc); ok(rc==DS_OK,"Lock failed: 0x%lx\n",rc);
if (rc!=DS_OK) if (rc!=DS_OK)
return 0; return 0;
@ -505,7 +503,7 @@ static int capture_buffer_service(capture_state_t* state)
if (rc!=DS_OK) if (rc!=DS_OK)
return 0; return 0;
state->offset = (state->offset + size) % state->wfx->nAvgBytesPerSec; state->offset = (state->offset + state->size) % state->buffer_size;
return 1; return 1;
} }
@ -569,8 +567,9 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
ZeroMemory(&state, sizeof(state)); ZeroMemory(&state, sizeof(state));
state.dscbo=dscbo; state.dscbo=dscbo;
state.wfx=&wfx; state.wfx=&wfx;
state.buffer_size=dscbcaps.dwBufferBytes; state.buffer_size = dscbcaps.dwBufferBytes;
state.event = CreateEvent( NULL, FALSE, FALSE, NULL ); state.event = CreateEvent( NULL, FALSE, FALSE, NULL );
state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
rc=IDirectSoundCapture_QueryInterface(dscbo,&IID_IDirectSoundNotify,(void **)&(state.notify)); rc=IDirectSoundCapture_QueryInterface(dscbo,&IID_IDirectSoundNotify,(void **)&(state.notify));
ok(rc==DS_OK,"QueryInterface failed: 0x%lx\n",rc); ok(rc==DS_OK,"QueryInterface failed: 0x%lx\n",rc);
@ -578,7 +577,7 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
return; return;
for (i = 0; i < NOTIFICATIONS; i++) { for (i = 0; i < NOTIFICATIONS; i++) {
state.posnotify[i].dwOffset = (i * (dscbcaps.dwBufferBytes / NOTIFICATIONS)) + (dscbcaps.dwBufferBytes / NOTIFICATIONS) - 1; state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
state.posnotify[i].hEventNotify = state.event; state.posnotify[i].hEventNotify = state.event;
} }
@ -601,12 +600,10 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
/* wait for the notifications */ /* wait for the notifications */
for (i = 0; i < (NOTIFICATIONS * 2); i++) { for (i = 0; i < (NOTIFICATIONS * 2); i++) {
rc=MsgWaitForMultipleObjects( 1, &(state.event), FALSE, 100, QS_ALLEVENTS ); rc=MsgWaitForMultipleObjects( 1, &(state.event), FALSE, 1000, QS_ALLEVENTS );
#if 0
ok(rc==WAIT_OBJECT_0,"MsgWaitForMultipleObjects failed: 0x%lx\n",rc); ok(rc==WAIT_OBJECT_0,"MsgWaitForMultipleObjects failed: 0x%lx\n",rc);
if (rc!=WAIT_OBJECT_0) if (rc!=WAIT_OBJECT_0)
break; break;
#endif
if (!capture_buffer_service(&state)) if (!capture_buffer_service(&state))
break; break;
} }
@ -640,8 +637,8 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
IDirectSoundCapture_Release(dsco); IDirectSoundCapture_Release(dsco);
rc=DirectSoundCaptureCreate(lpGuid,&dsco,NULL); rc=DirectSoundCaptureCreate(lpGuid,&dsco,NULL);
ok(rc==DS_OK,"DirectSoundCaptureCreate failed: 0x%lx\n",rc); ok((rc==DS_OK)||(rc==DSERR_NODRIVER),"DirectSoundCaptureCreate failed: 0x%lx\n",rc);
if (rc!=DS_OK) if ((rc!=DS_OK)&&(rc!=DSERR_NODRIVER))
goto EXIT; goto EXIT;
/* Private dsound.dll: Error: Invalid caps buffer */ /* Private dsound.dll: Error: Invalid caps buffer */