dsound: Reimplement capturing devices on mmdevapi.

This commit is contained in:
Andrew Eikum 2011-09-27 08:51:22 -05:00 committed by Alexandre Julliard
parent e786998daf
commit 3735ecac21
4 changed files with 285 additions and 275 deletions

View File

@ -27,6 +27,7 @@
#include <stdarg.h>
#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;
EnterCriticalSection(&DSOUND_capturers_lock);
LIST_FOR_EACH_ENTRY(device, &DSOUND_capturers, DirectSoundCaptureDevice, entry){
if(IsEqualGUID(&device->guid, &devGUID)){
IMMDevice_Release(mmdevice);
LeaveCriticalSection(&DSOUND_capturers_lock);
return DSERR_ALLOCATED;
}
}
/* enumerate WINMM audio devices and find the one we want */
for (wid=0; wid<widn; wid++) {
if (IsEqualGUID( &devGUID, &DSOUND_capture_guids[wid]) ) {
found = TRUE;
break;
}
}
if (found == FALSE) {
WARN("No device found matching given ID!\n");
return DSERR_NODRIVER;
}
if (DSOUND_capture[wid]) {
WARN("already in use\n");
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;
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;
}
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);
device->timerID = DSOUND_create_timer(&DSOUND_capture_timer, (DWORD_PTR)device);
list_add_tail(&DSOUND_capturers, &device->entry);
*ppDevice = device;
err = mmErr(waveInGetDevCapsA((UINT)device->drvdesc.dnDevNode, &wic, sizeof(wic)));
LeaveCriticalSection(&DSOUND_capturers_lock);
if (err == DS_OK) {
device->drvcaps.dwFlags = 0;
lstrcpynA(device->drvdesc.szDrvname, wic.szPname,
sizeof(device->drvdesc.szDrvname));
device->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
device->drvcaps.dwFormats = wic.dwFormats;
device->drvcaps.dwChannels = wic.wChannels;
}
return err;
return S_OK;
}

View File

@ -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;

View File

@ -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:

View File

@ -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;