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:
parent
f851a860fc
commit
15cc17fbcf
@ -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
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
|||||||
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user