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) {
ICOM_THIS(IDirectSoundBufferImpl,iface);
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));
if (!ref) {
......@@ -309,7 +309,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
int i;
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));
if (ref) return ref;
......@@ -472,7 +472,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(
LPDIRECTSOUNDBUFFER8 iface,LPDWORD status
) {
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)
return DSERR_INVALIDPARAM;
......@@ -682,7 +682,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
ICOM_THIS(IDirectSoundBufferImpl,iface);
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
/* Preprocess 3D buffers... */
......@@ -853,6 +853,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
return E_FAIL;
}
if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
IDirectSoundBuffer8_AddRef(iface);
*ppobj = This;
return NO_ERROR;
}
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
*ppobj = NULL;
......
......@@ -90,6 +90,7 @@ HRESULT mmErr(UINT err)
return DS_OK;
case MMSYSERR_ALLOCATED:
return DSERR_ALLOCATED;
case MMSYSERR_ERROR:
case MMSYSERR_INVALHANDLE:
case WAVERR_STILLPLAYING:
return DSERR_GENERIC; /* FIXME */
......@@ -122,12 +123,13 @@ int ds_snd_queue_min = DS_SND_QUEUE_MIN;
inline static void enumerate_devices(LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
if (lpDSEnumCallback != NULL)
if (lpDSEnumCallback(NULL, "Primary DirectSound Driver",
"sound", lpContext))
lpDSEnumCallback((LPGUID)&DSDEVID_WinePlayback,
"WINE DirectSound", "sound",
lpContext);
if (lpDSEnumCallback != NULL) {
TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"sound\",%p)\n",
debugstr_guid(&DSDEVID_DefaultPlayback),lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback,
"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.
*/
inline static void setup_dsound_options(void)
void setup_dsound_options(void)
{
char buffer[MAX_PATH+1];
HKEY hkey, appkey = 0;
......
......@@ -39,6 +39,7 @@ typedef struct IDirectSoundImpl IDirectSoundImpl;
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
......@@ -137,32 +138,31 @@ struct IDirectSoundCaptureImpl
DWORD ref;
/* IDirectSoundCaptureImpl fields */
GUID guid;
BOOL initialized;
GUID guid;
BOOL initialized;
/* DirectSound driver stuff */
PIDSCDRIVER driver;
DSDRIVERDESC drvdesc;
DSDRIVERCAPS drvcaps;
PIDSDRIVERBUFFER hwbuf;
/* DirectSound driver stuff */
PIDSCDRIVER driver;
DSDRIVERDESC drvdesc;
DSCDRIVERCAPS drvcaps;
PIDSCDRIVERBUFFER hwbuf;
/* wave driver info */
HWAVEIN hwi;
/* wave driver info */
HWAVEIN hwi;
/* more stuff */
/* more stuff */
LPBYTE buffer;
DWORD buflen;
DWORD read_position;
DWORD read_position;
/* FIXME: this should be a pointer because it can be bigger */
WAVEFORMATEX wfx;
/* FIXME: this should be a pointer because it can be bigger */
WAVEFORMATEX wfx;
DWORD formats;
DWORD channels;
IDirectSoundCaptureBufferImpl* capture_buffer;
DWORD state;
IDirectSoundCaptureBufferImpl* capture_buffer;
DWORD state;
LPWAVEHDR pwave;
int index;
int nrofpwaves;
int index;
CRITICAL_SECTION lock;
};
......@@ -171,18 +171,30 @@ struct IDirectSoundCaptureImpl
*/
struct IDirectSoundCaptureBufferImpl
{
/* IUnknown fields */
ICOM_VFIELD(IDirectSoundCaptureBuffer8);
DWORD ref;
/* IDirectSoundCaptureBufferImpl fields */
IDirectSoundCaptureImpl* dsound;
CRITICAL_SECTION lock;
/* FIXME: don't need this */
LPDSCBUFFERDESC pdscbd;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
DWORD flags;
/* IUnknown fields */
ICOM_VFIELD(IDirectSoundCaptureBuffer8);
DWORD ref;
/* IDirectSoundCaptureBufferImpl fields */
IDirectSoundCaptureImpl* dsound;
/* FIXME: don't need this */
LPDSCBUFFERDESC pdscbd;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
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;
/* IDirectSoundNotifyImpl fields */
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)
extern IDirectSoundImpl* dsound;
extern IDirectSoundCaptureImpl* dsound_capture;
struct PrimaryBuffer {
DWORD ref;
......@@ -297,3 +310,4 @@ struct PrimaryBuffer {
extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
extern HRESULT mmErr(UINT err);
extern void setup_dsound_options(void);
......@@ -901,7 +901,11 @@ void DSOUND_PerformMix(void)
/* DSOUND_callback may need this lock */
LeaveCriticalSection(&(dsound->mixlock));
#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
EnterCriticalSection(&(dsound->mixlock));
#endif
......
......@@ -476,6 +476,7 @@ typedef struct {
DWORD buffer_size;
DWORD read;
DWORD offset;
DWORD size;
DWORD last_pos;
} capture_state_t;
......@@ -486,16 +487,13 @@ static int capture_buffer_service(capture_state_t* state)
LPVOID ptr1,ptr2;
DWORD len1,len2;
DWORD capture_pos,read_pos;
LONG size;
rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,&read_pos);
ok(rc==DS_OK,"GetCurrentPosition failed: 0x%lx\n",rc);
if (rc!=DS_OK)
return 0;
size = state->wfx->nAvgBytesPerSec/NOTIFICATIONS;
rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,size,&ptr1,&len1,&ptr2,&len2,0);
rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,&ptr1,&len1,&ptr2,&len2,0);
ok(rc==DS_OK,"Lock failed: 0x%lx\n",rc);
if (rc!=DS_OK)
return 0;
......@@ -505,7 +503,7 @@ static int capture_buffer_service(capture_state_t* state)
if (rc!=DS_OK)
return 0;
state->offset = (state->offset + size) % state->wfx->nAvgBytesPerSec;
state->offset = (state->offset + state->size) % state->buffer_size;
return 1;
}
......@@ -569,8 +567,9 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
ZeroMemory(&state, sizeof(state));
state.dscbo=dscbo;
state.wfx=&wfx;
state.buffer_size=dscbcaps.dwBufferBytes;
state.buffer_size = dscbcaps.dwBufferBytes;
state.event = CreateEvent( NULL, FALSE, FALSE, NULL );
state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
rc=IDirectSoundCapture_QueryInterface(dscbo,&IID_IDirectSoundNotify,(void **)&(state.notify));
ok(rc==DS_OK,"QueryInterface failed: 0x%lx\n",rc);
......@@ -578,7 +577,7 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
return;
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;
}
......@@ -601,12 +600,10 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
/* wait for the notifications */
for (i = 0; i < (NOTIFICATIONS * 2); i++) {
rc=MsgWaitForMultipleObjects( 1, &(state.event), FALSE, 100, QS_ALLEVENTS );
#if 0
rc=MsgWaitForMultipleObjects( 1, &(state.event), FALSE, 1000, QS_ALLEVENTS );
ok(rc==WAIT_OBJECT_0,"MsgWaitForMultipleObjects failed: 0x%lx\n",rc);
if (rc!=WAIT_OBJECT_0)
break;
#endif
if (!capture_buffer_service(&state))
break;
}
......@@ -640,8 +637,8 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
IDirectSoundCapture_Release(dsco);
rc=DirectSoundCaptureCreate(lpGuid,&dsco,NULL);
ok(rc==DS_OK,"DirectSoundCaptureCreate failed: 0x%lx\n",rc);
if (rc!=DS_OK)
ok((rc==DS_OK)||(rc==DSERR_NODRIVER),"DirectSoundCaptureCreate failed: 0x%lx\n",rc);
if ((rc!=DS_OK)&&(rc!=DSERR_NODRIVER))
goto EXIT;
/* 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