Commit 15cc17fb authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Fixed code to handle full duplex properly.

Added support for capture driver (disabled). Fixed direct sound capture test to handle notifications properly.
parent f851a860
...@@ -296,7 +296,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) { ...@@ -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) { ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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;
......
...@@ -90,6 +90,7 @@ HRESULT mmErr(UINT err) ...@@ -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; ...@@ -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, ...@@ -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;
......
...@@ -39,6 +39,7 @@ typedef struct IDirectSoundImpl IDirectSoundImpl; ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 { ...@@ -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);
...@@ -901,7 +901,11 @@ void DSOUND_PerformMix(void) ...@@ -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
......
...@@ -476,6 +476,7 @@ typedef struct { ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment