From 3735ecac219ab0560e0b1141e0b6bf745e62fa13 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Tue, 27 Sep 2011 08:51:22 -0500 Subject: [PATCH] dsound: Reimplement capturing devices on mmdevapi. --- dlls/dsound/capture.c | 465 ++++++++++++++++++++++++------------------- dlls/dsound/dsound.c | 4 +- dlls/dsound/dsound_main.c | 62 +----- dlls/dsound/dsound_private.h | 23 ++- 4 files changed, 282 insertions(+), 272 deletions(-) diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index 4ce087b20c8..9a56e6576ab 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -27,6 +27,7 @@ #include +#define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION #include "windef.h" @@ -244,28 +245,30 @@ IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) if (!ref) { TRACE("deleting object\n"); - if (This->device->state == STATE_CAPTURING) - This->device->state = STATE_STOPPING; + if (This->device->state == STATE_CAPTURING) + This->device->state = STATE_STOPPING; HeapFree(GetProcessHeap(),0, This->pdscbd); - if (This->device->hwi) { - waveInReset(This->device->hwi); - waveInClose(This->device->hwi); - HeapFree(GetProcessHeap(),0, This->device->pwave); - This->device->pwave = 0; - This->device->hwi = 0; - } + if (This->device->client) { + IAudioClient_Release(This->device->client); + This->device->client = NULL; + } + + if (This->device->capture) { + IAudioCaptureClient_Release(This->device->capture); + This->device->capture = NULL; + } /* remove from DirectSoundCaptureDevice */ This->device->capture_buffer = NULL; if (This->notify) - IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify); + IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify); - HeapFree(GetProcessHeap(), 0, This->notifies); + HeapFree(GetProcessHeap(), 0, This->notifies); HeapFree( GetProcessHeap(), 0, This ); - TRACE("(%p) released\n", This); + TRACE("(%p) released\n", This); } return ref; } @@ -309,7 +312,6 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition( LPDWORD lpdwReadPosition ) { IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - HRESULT hres = DS_OK; TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition ); if (This->device == NULL) { @@ -317,25 +319,26 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition( return DSERR_INVALIDPARAM; } - if (This->device->hwi) { - DWORD pos; + EnterCriticalSection(&This->device->lock); - EnterCriticalSection(&This->device->lock); - pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer; - if (lpdwCapturePosition) - *lpdwCapturePosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen; - if (lpdwReadPosition) - *lpdwReadPosition = pos; + if (!This->device->client) { LeaveCriticalSection(&This->device->lock); - - } else { WARN("no driver\n"); - hres = DSERR_NODRIVER; + return DSERR_NODRIVER; } + if(lpdwCapturePosition) + *lpdwCapturePosition = This->device->write_pos_bytes; + + if(lpdwReadPosition) + *lpdwReadPosition = This->device->write_pos_bytes; + + LeaveCriticalSection(&This->device->lock); + TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition?*lpdwCapturePosition:-1), (lpdwReadPosition?*lpdwReadPosition:-1)); - TRACE("returning %08x\n", hres); - return hres; + TRACE("returning DS_OK\n"); + + return DS_OK; } static HRESULT WINAPI @@ -460,7 +463,7 @@ IDirectSoundCaptureBufferImpl_Lock( EnterCriticalSection(&(This->device->lock)); - if (This->device->hwi) { + if (This->device->client) { *lplpvAudioPtr1 = This->device->buffer + dwReadCusor; if ( (dwReadCusor + dwReadBytes) > This->device->buflen) { *lpdwAudioBytes1 = This->device->buflen - dwReadCusor; @@ -491,8 +494,9 @@ IDirectSoundCaptureBufferImpl_Start( LPDIRECTSOUNDCAPTUREBUFFER8 iface, DWORD dwFlags ) { - HRESULT hres = DS_OK; + HRESULT hres; IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; + TRACE( "(%p,0x%08x)\n", This, dwFlags ); if (This->device == NULL) { @@ -500,7 +504,7 @@ IDirectSoundCaptureBufferImpl_Start( return DSERR_INVALIDPARAM; } - if ( This->device->hwi == 0 ) { + if ( !This->device->client ) { WARN("no driver\n"); return DSERR_NODRIVER; } @@ -508,87 +512,33 @@ IDirectSoundCaptureBufferImpl_Start( EnterCriticalSection(&(This->device->lock)); This->flags = dwFlags; - TRACE("old This->state=%s\n",captureStateString[This->device->state]); + TRACE("old This->device->state=%s\n",captureStateString[This->device->state]); if (This->device->state == STATE_STOPPED) This->device->state = STATE_STARTING; else if (This->device->state == STATE_STOPPING) This->device->state = STATE_CAPTURING; TRACE("new This->device->state=%s\n",captureStateString[This->device->state]); - LeaveCriticalSection(&(This->device->lock)); + if (This->device->buffer) + FillMemory(This->device->buffer, This->device->buflen, (This->device->pwfx->wBitsPerSample == 8) ? 128 : 0); - if (This->device->hwi) { - DirectSoundCaptureDevice *device = This->device; - - if (device->buffer) { - int c; - DWORD blocksize = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign); - device->nrofpwaves = device->buflen / blocksize + !!(device->buflen % blocksize); - TRACE("nrofpwaves=%d\n", device->nrofpwaves); - - /* prepare headers */ - if (device->pwave) - device->pwave = HeapReAlloc(GetProcessHeap(), 0,device->pwave, device->nrofpwaves*sizeof(WAVEHDR)); - else - device->pwave = HeapAlloc(GetProcessHeap(), 0, device->nrofpwaves*sizeof(WAVEHDR)); - - for (c = 0; c < device->nrofpwaves; ++c) { - device->pwave[c].lpData = (char *)device->buffer + c * blocksize; - if (c + 1 == device->nrofpwaves) - device->pwave[c].dwBufferLength = device->buflen - c * blocksize; - else - device->pwave[c].dwBufferLength = blocksize; - device->pwave[c].dwBytesRecorded = 0; - device->pwave[c].dwUser = (DWORD_PTR)device; - device->pwave[c].dwFlags = 0; - device->pwave[c].dwLoops = 0; - hres = mmErr(waveInPrepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR))); - if (hres != DS_OK) { - WARN("waveInPrepareHeader failed\n"); - while (c--) - waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR)); - break; - } - - hres = mmErr(waveInAddBuffer(device->hwi, &(device->pwave[c]), sizeof(WAVEHDR))); - if (hres != DS_OK) { - WARN("waveInAddBuffer failed\n"); - while (c--) - waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR)); - break; - } - } - - FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0); - } - - device->index = 0; - - if (hres == DS_OK) { - /* start filling the first buffer */ - hres = mmErr(waveInStart(device->hwi)); - if (hres != DS_OK) - WARN("waveInStart failed\n"); - } - - if (hres != DS_OK) { - WARN("calling waveInClose because of error\n"); - waveInClose(device->hwi); - device->hwi = 0; - } - } else { - WARN("no driver\n"); - hres = DSERR_NODRIVER; + hres = IAudioClient_Start(This->device->client); + if(FAILED(hres)){ + WARN("Start failed: %08x\n", hres); + LeaveCriticalSection(&This->device->lock); + return hres; } - TRACE("returning %08x\n", hres); - return hres; + LeaveCriticalSection(&This->device->lock); + + TRACE("returning DS_OK\n"); + return DS_OK; } static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) { - HRESULT hres = DS_OK; + HRESULT hres; IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; TRACE( "(%p)\n", This ); @@ -606,19 +556,18 @@ IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) This->device->state = STATE_STOPPED; TRACE("new This->device->state=%s\n",captureStateString[This->device->state]); - LeaveCriticalSection(&(This->device->lock)); - - if (This->device->hwi) { - hres = mmErr(waveInReset(This->device->hwi)); - if (hres != DS_OK) - WARN("waveInReset() failed\n"); - } else { - WARN("no driver\n"); - hres = DSERR_NODRIVER; + if(This->device->client){ + hres = IAudioClient_Stop(This->device->client); + if(FAILED(hres)){ + LeaveCriticalSection(&This->device->lock); + return hres; + } } - TRACE("returning %08x\n", hres); - return hres; + LeaveCriticalSection(&(This->device->lock)); + + TRACE("returning DS_OK\n"); + return DS_OK; } static HRESULT WINAPI @@ -639,7 +588,7 @@ IDirectSoundCaptureBufferImpl_Unlock( return DSERR_INVALIDPARAM; } - if (!This->device->hwi) { + if (!This->device->client) { WARN("invalid call\n"); hres = DSERR_INVALIDCALL; } @@ -725,49 +674,6 @@ static void capture_CheckNotify(IDirectSoundCaptureBufferImpl *This, DWORD from, } } -static void CALLBACK -DSOUND_capture_callback(HWAVEIN hwi, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, - DWORD_PTR dw2) -{ - DirectSoundCaptureDevice * This = (DirectSoundCaptureDevice*)dwUser; - IDirectSoundCaptureBufferImpl * Moi = This->capture_buffer; - TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %d\n",hwi,msg, - msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" : - msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount()); - - if (msg == MM_WIM_DATA) { - EnterCriticalSection( &(This->lock) ); - TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n", - captureStateString[This->state],This->index); - if (This->state != STATE_STOPPED) { - int index = This->index; - if (This->state == STATE_STARTING) - This->state = STATE_CAPTURING; - capture_CheckNotify(Moi, (DWORD_PTR)This->pwave[index].lpData - (DWORD_PTR)This->buffer, This->pwave[index].dwBufferLength); - This->index = (This->index + 1) % This->nrofpwaves; - if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) { - TRACE("end of buffer\n"); - This->state = STATE_STOPPED; - capture_CheckNotify(Moi, 0, 0); - } else { - if (This->state == STATE_CAPTURING) { - waveInUnprepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR)); - waveInPrepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR)); - waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR)); - } else if (This->state == STATE_STOPPING) { - TRACE("stopping\n"); - This->state = STATE_STOPPED; - } - } - } - TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n", - captureStateString[This->state],This->index); - LeaveCriticalSection( &(This->lock) ); - } - - TRACE("completed\n"); -} - static HRESULT IDirectSoundCaptureBufferImpl_Create( DirectSoundCaptureDevice *device, IDirectSoundCaptureBufferImpl ** ppobj, @@ -849,12 +755,38 @@ static HRESULT IDirectSoundCaptureBufferImpl_Create( This->lpVtbl = &dscbvt; - err = mmErr(waveInOpen(&(device->hwi), - device->drvdesc.dnDevNode, device->pwfx, - (DWORD_PTR)DSOUND_capture_callback, (DWORD_PTR)device, - CALLBACK_FUNCTION | WAVE_MAPPED)); - if (err != DS_OK) { - WARN("waveInOpen failed\n"); + err = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient, + CLSCTX_INPROC_SERVER, NULL, (void**)&device->client); + if(FAILED(err)){ + WARN("Activate failed: %08x\n", err); + HeapFree(GetProcessHeap(), 0, This->pdscbd); + This->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return err; + } + + err = IAudioClient_Initialize(device->client, + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST, + 200 * 100000, 50000, device->pwfx, NULL); + if(FAILED(err)){ + WARN("Initialize failed: %08x\n", err); + IAudioClient_Release(device->client); + device->client = NULL; + HeapFree(GetProcessHeap(), 0, This->pdscbd); + This->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return err; + } + + err = IAudioClient_GetService(device->client, &IID_IAudioCaptureClient, + (void**)&device->capture); + if(FAILED(err)){ + WARN("GetService failed: %08x\n", err); + IAudioClient_Release(device->client); + device->client = NULL; + HeapFree(GetProcessHeap(), 0, This->pdscbd); This->device->capture_buffer = 0; HeapFree( GetProcessHeap(), 0, This ); *ppobj = NULL; @@ -868,13 +800,18 @@ static HRESULT IDirectSoundCaptureBufferImpl_Create( else newbuf = HeapAlloc(GetProcessHeap(),0,buflen); if (newbuf == NULL) { - WARN("failed to allocate capture buffer\n"); - err = DSERR_OUTOFMEMORY; - /* but the old buffer might still exist and must be re-prepared */ - } else { - device->buffer = newbuf; - device->buflen = buflen; + IAudioClient_Release(device->client); + device->client = NULL; + IAudioCaptureClient_Release(device->capture); + device->capture = NULL; + HeapFree(GetProcessHeap(), 0, This->pdscbd); + This->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return DSERR_OUTOFMEMORY; } + device->buffer = newbuf; + device->buflen = buflen; } TRACE("returning DS_OK\n"); @@ -920,94 +857,210 @@ static ULONG DirectSoundCaptureDevice_Release( if (!ref) { TRACE("deleting object\n"); + + timeKillEvent(device->timerID); + timeEndPeriod(DS_TIME_RES); + + EnterCriticalSection(&DSOUND_capturers_lock); + list_remove(&device->entry); + LeaveCriticalSection(&DSOUND_capturers_lock); + if (device->capture_buffer) IDirectSoundCaptureBufferImpl_Release( (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer); + if(device->mmdevice) + IMMDevice_Release(device->mmdevice); HeapFree(GetProcessHeap(), 0, device->pwfx); device->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &(device->lock) ); - DSOUND_capture[device->drvdesc.dnDevNode] = NULL; HeapFree(GetProcessHeap(), 0, device); TRACE("(%p) released\n", device); } return ref; } +void CALLBACK DSOUND_capture_timer(UINT timerID, UINT msg, DWORD_PTR user, + DWORD_PTR dw1, DWORD_PTR dw2) +{ + DirectSoundCaptureDevice *device = (DirectSoundCaptureDevice*)user; + UINT32 packet_frames, packet_bytes, avail_bytes; + DWORD flags; + BYTE *buf; + HRESULT hr; + + if(!device->ref) + return; + + EnterCriticalSection(&device->lock); + + if(!device->capture_buffer || device->state == STATE_STOPPED){ + LeaveCriticalSection(&device->lock); + return; + } + + if(device->state == STATE_STOPPING){ + device->state = STATE_STOPPED; + LeaveCriticalSection(&device->lock); + return; + } + + if(device->state == STATE_STARTING) + device->state = STATE_CAPTURING; + + hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames, + &flags, NULL, NULL); + if(FAILED(hr)){ + LeaveCriticalSection(&device->lock); + WARN("GetBuffer failed: %08x\n", hr); + return; + } + + packet_bytes = packet_frames * device->pwfx->nBlockAlign; + + avail_bytes = device->buflen - device->write_pos_bytes; + if(avail_bytes > packet_bytes) + avail_bytes = packet_bytes; + + memcpy(device->buffer + device->write_pos_bytes, buf, avail_bytes); + capture_CheckNotify(device->capture_buffer, device->write_pos_bytes, avail_bytes); + + packet_bytes -= avail_bytes; + if(packet_bytes > 0){ + if(device->capture_buffer->flags & DSCBSTART_LOOPING){ + memcpy(device->buffer, buf + avail_bytes, packet_bytes); + capture_CheckNotify(device->capture_buffer, 0, packet_bytes); + }else{ + device->state = STATE_STOPPED; + capture_CheckNotify(device->capture_buffer, 0, 0); + } + } + + device->write_pos_bytes += avail_bytes + packet_bytes; + device->write_pos_bytes %= device->buflen; + + hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames); + if(FAILED(hr)){ + LeaveCriticalSection(&device->lock); + WARN("ReleaseBuffer failed: %08x\n", hr); + return; + } + + LeaveCriticalSection(&device->lock); +} + +static struct _TestFormat { + DWORD flag; + DWORD rate; + DWORD depth; + WORD channels; +} formats_to_test[] = { + { WAVE_FORMAT_1M08, 11025, 8, 1 }, + { WAVE_FORMAT_1M16, 11025, 16, 1 }, + { WAVE_FORMAT_1S08, 11025, 8, 2 }, + { WAVE_FORMAT_1S16, 11025, 16, 2 }, + { WAVE_FORMAT_2M08, 22050, 8, 1 }, + { WAVE_FORMAT_2M16, 22050, 16, 1 }, + { WAVE_FORMAT_2S08, 22050, 8, 2 }, + { WAVE_FORMAT_2S16, 22050, 16, 2 }, + { WAVE_FORMAT_4M08, 44100, 8, 1 }, + { WAVE_FORMAT_4M16, 44100, 16, 1 }, + { WAVE_FORMAT_4S08, 44100, 8, 2 }, + { WAVE_FORMAT_4S16, 44100, 16, 2 }, + { WAVE_FORMAT_48M08, 48000, 8, 1 }, + { WAVE_FORMAT_48M16, 48000, 16, 1 }, + { WAVE_FORMAT_48S08, 48000, 8, 2 }, + { WAVE_FORMAT_48S16, 48000, 16, 2 }, + { WAVE_FORMAT_96M08, 96000, 8, 1 }, + { WAVE_FORMAT_96M16, 96000, 16, 1 }, + { WAVE_FORMAT_96S08, 96000, 8, 2 }, + { WAVE_FORMAT_96S16, 96000, 16, 2 }, + {0} +}; + static HRESULT DirectSoundCaptureDevice_Initialize( DirectSoundCaptureDevice ** ppDevice, LPCGUID lpcGUID) { - HRESULT err = DSERR_INVALIDPARAM; - unsigned wid, widn; - BOOLEAN found = FALSE; + HRESULT hr; GUID devGUID; - DirectSoundCaptureDevice *device = *ppDevice; - WAVEINCAPSA wic; + IMMDevice *mmdevice; + struct _TestFormat *fmt; + DirectSoundCaptureDevice *device; + IAudioClient *client; TRACE("(%p, %s)\n", ppDevice, debugstr_guid(lpcGUID)); /* Default device? */ if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) ) - lpcGUID = &DSDEVID_DefaultCapture; + lpcGUID = &DSDEVID_DefaultCapture; + + if(IsEqualGUID(lpcGUID, &DSDEVID_DefaultPlayback) || + IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoicePlayback)) + return DSERR_NODRIVER; if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) { WARN("invalid parameter: lpcGUID\n"); return DSERR_INVALIDPARAM; } - widn = waveInGetNumDevs(); - if (!widn) { - WARN("no audio devices found\n"); - return DSERR_NODRIVER; - } + hr = get_mmdevice(eCapture, &devGUID, &mmdevice); + if(FAILED(hr)) + return hr; - /* enumerate WINMM audio devices and find the one we want */ - for (wid=0; widguid, &devGUID)){ + IMMDevice_Release(mmdevice); + LeaveCriticalSection(&DSOUND_capturers_lock); + return DSERR_ALLOCATED; + } } - err = DirectSoundCaptureDevice_Create(&(device)); - if (err != DS_OK) { + hr = DirectSoundCaptureDevice_Create(&device); + if (hr != DS_OK) { WARN("DirectSoundCaptureDevice_Create failed\n"); - return err; + LeaveCriticalSection(&DSOUND_capturers_lock); + return hr; } - *ppDevice = device; device->guid = devGUID; + device->mmdevice = mmdevice; + device->drvdesc.dwFlags = 0; - device->drvdesc.dnDevNode = wid; + device->drvcaps.dwFlags = 0; - *ppDevice = device; + device->drvcaps.dwFormats = 0; + device->drvcaps.dwChannels = 0; + hr = IMMDevice_Activate(mmdevice, &IID_IAudioClient, + CLSCTX_INPROC_SERVER, NULL, (void**)&client); + if(FAILED(hr)){ + DeleteCriticalSection(&device->lock); + HeapFree(GetProcessHeap(), 0, device); + return DSERR_NODRIVER; + } - err = mmErr(waveInGetDevCapsA((UINT)device->drvdesc.dnDevNode, &wic, sizeof(wic))); + for(fmt = formats_to_test; fmt->flag; ++fmt){ + if(DSOUND_check_supported(client, fmt->rate, fmt->depth, fmt->channels)){ + device->drvcaps.dwFormats |= fmt->flag; + if(fmt->channels > device->drvcaps.dwChannels) + device->drvcaps.dwChannels = fmt->channels; + } + } + IAudioClient_Release(client); - if (err == DS_OK) { - device->drvcaps.dwFlags = 0; - lstrcpynA(device->drvdesc.szDrvname, wic.szPname, - sizeof(device->drvdesc.szDrvname)); + device->timerID = DSOUND_create_timer(&DSOUND_capture_timer, (DWORD_PTR)device); - device->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER; - device->drvcaps.dwFormats = wic.dwFormats; - device->drvcaps.dwChannels = wic.wChannels; - } + list_add_tail(&DSOUND_capturers, &device->entry); - return err; + *ppDevice = device; + + LeaveCriticalSection(&DSOUND_capturers_lock); + + return S_OK; } diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index 7616bc62148..49b39a108c4 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -1343,7 +1343,7 @@ HRESULT DirectSoundDevice_GetCaps( return DS_OK; } -static BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, +BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, DWORD depth, WORD channels) { WAVEFORMATEX fmt, *junk; @@ -1364,7 +1364,7 @@ static BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, return hr == S_OK; } -static UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) +UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) { UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id; TIMECAPS time; diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c index 681e3984b6f..1ed04e51a0f 100644 --- a/dlls/dsound/dsound_main.c +++ b/dlls/dsound/dsound_main.c @@ -68,6 +68,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); struct list DSOUND_renderers = LIST_INIT(DSOUND_renderers); CRITICAL_SECTION DSOUND_renderers_lock; +struct list DSOUND_capturers = LIST_INIT(DSOUND_capturers); +CRITICAL_SECTION DSOUND_capturers_lock; + GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; @@ -652,64 +655,17 @@ DirectSoundCaptureEnumerateW( LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext) { - unsigned devs, wid; - DSDRIVERDESC desc; - GUID guid; - int err; - WCHAR wDesc[MAXPNAMELEN]; - WCHAR wName[MAXPNAMELEN]; - TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext ); if (lpDSEnumCallback == NULL) { - WARN("invalid parameter: lpDSEnumCallback == NULL\n"); + WARN("invalid parameter: lpDSEnumCallback == NULL\n"); return DSERR_INVALIDPARAM; } setup_dsound_options(); - devs = waveInGetNumDevs(); - if (devs > 0) { - if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) { - for (wid = 0; wid < devs; ++wid) { - if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", - "Primary Sound Capture Driver",desc.szDrvname,lpContext); - MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1, - wDesc, sizeof(wDesc)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, - wName, sizeof(wName)/sizeof(WCHAR) ); - wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0'; - - if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) - return DS_OK; - } - } - } - } - } - - for (wid = 0; wid < devs; ++wid) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", - debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext); - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, - wDesc, sizeof(wDesc)/sizeof(WCHAR) ); - wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0'; - - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, - wName, sizeof(wName)/sizeof(WCHAR) ); - wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0'; - - if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE) - return DS_OK; - } - } - - return DS_OK; + return enumerate_mmdevices(eCapture, DSOUND_capture_guids, + lpDSEnumCallback, lpContext); } /******************************************************************************* @@ -877,21 +833,17 @@ HRESULT WINAPI DllCanUnloadNow(void) */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) { - int i; TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved); switch (fdwReason) { case DLL_PROCESS_ATTACH: TRACE("DLL_PROCESS_ATTACH\n"); - for (i = 0; i < MAXWAVEDRIVERS; i++) { - DSOUND_capture[i] = NULL; - INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i); - } instance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); /* Increase refcount on dsound by 1 */ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL); InitializeCriticalSection(&DSOUND_renderers_lock); + InitializeCriticalSection(&DSOUND_capturers_lock); InitializeCriticalSection(&g_devenum_lock); break; case DLL_PROCESS_DETACH: diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index c25c3557ebb..7f15e20e97c 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -280,21 +280,22 @@ struct DirectSoundCaptureDevice DSDRIVERDESC drvdesc; DSCDRIVERCAPS drvcaps; - /* wave driver info */ - HWAVEIN hwi; - /* more stuff */ LPBYTE buffer; - DWORD buflen; + DWORD buflen, write_pos_bytes; PWAVEFORMATEX pwfx; IDirectSoundCaptureBufferImpl* capture_buffer; DWORD state; - LPWAVEHDR pwave; - int nrofpwaves; - int index; + UINT timerID; CRITICAL_SECTION lock; + + IMMDevice *mmdevice; + IAudioClient *client; + IAudioCaptureClient *capture; + + struct list entry; }; /***************************************************************************** @@ -428,10 +429,10 @@ HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8) DECLSP #define DSOUND_FREQSHIFT (20) extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN; +extern CRITICAL_SECTION DSOUND_capturers_lock DECLSPEC_HIDDEN; +extern struct list DSOUND_capturers DECLSPEC_HIDDEN; extern struct list DSOUND_renderers DECLSPEC_HIDDEN; -extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS] DECLSPEC_HIDDEN; - extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN; extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN; @@ -440,3 +441,7 @@ void setup_dsound_options(void) DECLSPEC_HIDDEN; const char * dumpCooperativeLevel(DWORD level) DECLSPEC_HIDDEN; HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) DECLSPEC_HIDDEN; + +BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, + DWORD depth, WORD channels) DECLSPEC_HIDDEN; +UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) DECLSPEC_HIDDEN; -- 2.11.4.GIT