static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps( LPDIRECTSOUNDCAPTURE iface, LPDSCCAPS lpDSCCaps) { IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface; TRACE("(%p,%p)\n",This,lpDSCCaps); return IDirectSoundCapture_GetCaps(This->pdsfd->capture_device, lpDSCCaps); }
/************************************************************************************ ** Extract capabilities info from each device. */ static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext ) { HRESULT hr; LPDIRECTSOUND lpDirectSound; #if SUPPORT_AUDIO_CAPTURE LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; #endif /* SUPPORT_AUDIO_CAPTURE */ int isInput = (int) lpContext; /* Passed from Pa_CountDevices() */ internalPortAudioDevice *pad; if( sDeviceIndex >= sNumDevices ) { sEnumerationError = paInternalError; return FALSE; } pad = &sDevices[sDeviceIndex]; /* Copy GUID to static array. Set pointer. */ if( lpGUID == NULL ) { pad->pad_lpGUID = NULL; } else { memcpy( &pad->pad_GUID, lpGUID, sizeof(GUID) ); pad->pad_lpGUID = &pad->pad_GUID; } pad->pad_Info.sampleRates = pad->pad_SampleRates; /* Point to array. */ /* Allocate room for descriptive name. */ if( lpszDesc != NULL ) { int len = strlen(lpszDesc); pad->pad_Info.name = (char *)malloc( len+1 ); if( pad->pad_Info.name == NULL ) { sEnumerationError = paInsufficientMemory; return FALSE; } memcpy( (void *) pad->pad_Info.name, lpszDesc, len+1 ); } #if SUPPORT_AUDIO_CAPTURE if( isInput ) { /********** Input ******************************/ DSCCAPS caps; if( lpGUID == NULL ) sDefaultInputDeviceID = sDeviceIndex; hr = DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); if( hr != DS_OK ) { pad->pad_Info.maxInputChannels = 0; DBUG(("Cannot create Capture for %s. Result = 0x%x\n", lpszDesc, hr )); } else { /* Query device characteristics. */ caps.dwSize = sizeof(caps); IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); /* printf("caps.dwFormats = 0x%x\n", caps.dwFormats ); */ pad->pad_Info.maxInputChannels = caps.dwChannels; /* Determine sample rates from flags. */ if( caps.dwChannels == 2 ) { int index = 0; if( caps.dwFormats & WAVE_FORMAT_1S16) pad->pad_SampleRates[index++] = 11025.0; if( caps.dwFormats & WAVE_FORMAT_2S16) pad->pad_SampleRates[index++] = 22050.0; if( caps.dwFormats & WAVE_FORMAT_4S16) pad->pad_SampleRates[index++] = 44100.0; pad->pad_Info.numSampleRates = index; } else if( caps.dwChannels == 1 ) { int index = 0; if( caps.dwFormats & WAVE_FORMAT_1M16) pad->pad_SampleRates[index++] = 11025.0; if( caps.dwFormats & WAVE_FORMAT_2M16) pad->pad_SampleRates[index++] = 22050.0; if( caps.dwFormats & WAVE_FORMAT_4M16) pad->pad_SampleRates[index++] = 44100.0; pad->pad_Info.numSampleRates = index; } else pad->pad_Info.numSampleRates = 0; IDirectSoundCapture_Release( lpDirectSoundCapture ); } } else #endif /* SUPPORT_AUDIO_CAPTURE */ { /********** Output ******************************/ DSCAPS caps; if( lpGUID == NULL ) sDefaultOutputDeviceID = sDeviceIndex; /* Create interfaces for each object. */ hr = DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); if( hr != DS_OK ) { pad->pad_Info.maxOutputChannels = 0; DBUG(("Cannot create dsound for %s. Result = 0x%x\n", lpszDesc, hr )); } else { /* Query device characteristics. */ caps.dwSize = sizeof(caps); IDirectSound_GetCaps( lpDirectSound, &caps ); pad->pad_Info.maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; /* Get sample rates. */ pad->pad_SampleRates[0] = (double) caps.dwMinSecondarySampleRate; pad->pad_SampleRates[1] = (double) caps.dwMaxSecondarySampleRate; if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) pad->pad_Info.numSampleRates = -1; else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate ) { if( caps.dwMinSecondarySampleRate == 0 ) { /* ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !! ** But it supports continuous sampling. ** So fake range of rates, and hope it really supports it. */ pad->pad_SampleRates[0] = 11025.0f; pad->pad_SampleRates[1] = 48000.0f; pad->pad_Info.numSampleRates = -1; /* continuous range */ DBUG(("PA - Reported rates both zero. Setting to fake values for device #%d\n", sDeviceIndex )); } else { pad->pad_Info.numSampleRates = 1; } } else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) ) { /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000. ** But we know that they really support a range of rates! ** So when we see a ridiculous set of rates, assume it is a range. */ pad->pad_Info.numSampleRates = -1; DBUG(("PA - Sample rate range used instead of two odd values for device #%d\n", sDeviceIndex )); } else pad->pad_Info.numSampleRates = 2; IDirectSound_Release( lpDirectSound ); } } pad->pad_Info.nativeSampleFormats = paInt16; sDeviceIndex++; return( TRUE ); }
static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) { HRESULT rc; LPDIRECTSOUNDCAPTURE dsco=NULL; LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL; DSCBUFFERDESC bufdesc; WAVEFORMATEX wfx; DSCCAPS dsccaps; DWORD f; int ref; /* Private dsound.dll: Error: Invalid interface buffer */ trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule); rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL); ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have " "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL); ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED), "DirectSoundCaptureCreate() failed: %08x\n",rc); if (rc!=DS_OK) { if (rc==DSERR_NODRIVER) trace(" No Driver\n"); else if (rc==E_FAIL) trace(" No Device\n"); else if (rc==DSERR_ALLOCATED) trace(" Already In Use\n"); goto EXIT; } /* Private dsound.dll: Error: Invalid caps buffer */ rc=IDirectSoundCapture_GetCaps(dsco,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have " "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); /* Private dsound.dll: Error: Invalid caps buffer */ dsccaps.dwSize=0; rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have " "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); dsccaps.dwSize=sizeof(dsccaps); rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps); ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %08x\n", rc); if (rc==DS_OK && winetest_debug > 1) { trace(" Caps: size=%d flags=0x%08x formats=%05x channels=%d\n", dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats, dsccaps.dwChannels); } /* Private dsound.dll: Error: Invalid size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=0; bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=NULL; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=NULL; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() " "should have returned DSERR_INVALIDPARAM, returned %08x\n", rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); ZeroMemory(&wfx, sizeof(wfx)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } for (f=0;f<NB_FORMATS;f++) { dscbo=NULL; init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1], formats[f][2]); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(((rc==DS_OK)&&(dscbo!=NULL)) || rc==DSERR_BADFORMAT || rc==DSERR_INVALIDCALL || rc==DSERR_NODRIVER || rc==DSERR_ALLOCATED || rc==E_INVALIDARG || rc==E_FAIL, "IDirectSoundCapture_CreateCaptureBuffer() failed to create a " "%s capture buffer: %08x\n",format_string(&wfx),rc); if (rc==DS_OK) { test_capture_buffer(dsco, dscbo, winetest_interactive); ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } else if (rc==DSERR_BADFORMAT) { ok(!(dsccaps.dwFormats & formats[f][3]), "IDirectSoundCapture_CreateCaptureBuffer() failed to create a " "capture buffer: format listed as supported but using it failed\n"); if (!(dsccaps.dwFormats & formats[f][3])) trace(" Format not supported: %s\n", format_string(&wfx)); } else if (rc==DSERR_NODRIVER) { trace(" No Driver\n"); } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); } else if (rc==E_INVALIDARG) { /* try the old version struct */ DSCBUFFERDESC1 bufdesc1; ZeroMemory(&bufdesc1, sizeof(bufdesc1)); bufdesc1.dwSize=sizeof(bufdesc1); bufdesc1.dwFlags=0; bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc1.dwReserved=0; bufdesc1.lpwfxFormat=&wfx; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco, (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL); ok(rc==DS_OK || broken(rc==DSERR_INVALIDPARAM), "IDirectSoundCapture_CreateCaptureBuffer() failed to create a " "%s capture buffer: %08x\n",format_string(&wfx), rc); if (rc==DSERR_INVALIDPARAM) { skip("broken driver\n"); goto EXIT; } if (rc==DS_OK) { test_capture_buffer(dsco, dscbo, winetest_interactive); ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d " "references, should have 0\n",ref); } } else if (rc==E_FAIL) { /* WAVE_FORMAT_PCM only allows 8 and 16 bits per sample, so only * report a failure if the bits per sample is 8 or 16 */ if (wfx.wBitsPerSample == 8 || wfx.wBitsPerSample == 16) ok(FALSE,"Should not fail for 8 or 16 bits per sample\n"); } } /* try a non PCM format */ if (0) { /* FIXME: Why is this commented out? */ init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() " "failed to create a capture buffer: %08x\n",rc); if ((rc==DS_OK)&&(dscbo!=NULL)) { test_capture_buffer(dsco, dscbo, winetest_interactive); ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, " "should have 0\n",ref); } } /* Try an invalid format to test error handling */ if (0) { /* FIXME: Remove this test altogether? */ init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed " "at 2 MHz %08x\n",rc); } EXIT: if (dsco!=NULL) { ref=IDirectSoundCapture_Release(dsco); ok(ref==0,"IDirectSoundCapture_Release() has %d references, should " "have 0\n",ref); } return TRUE; }
static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco, BOOL initialized, LPCGUID lpGuid) { HRESULT rc; DSCCAPS dsccaps; int ref; IUnknown * unknown; IDirectSoundCapture * dsc; /* Try to Query for objects */ rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown, (LPVOID*)&unknown); ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) " "failed: %08x\n", rc); if (rc==DS_OK) IDirectSoundCapture_Release(unknown); rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture, (LPVOID*)&dsc); ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) " "failed: %08x\n", rc); if (rc==DS_OK) IDirectSoundCapture_Release(dsc); if (initialized == FALSE) { /* try uninitialized object */ rc=IDirectSoundCapture_GetCaps(dsco,0); ok(rc==DSERR_UNINITIALIZED||rc==E_INVALIDARG, "IDirectSoundCapture_GetCaps(NULL) should have returned " "DSERR_UNINITIALIZED or E_INVALIDARG, returned: %08x\n", rc); rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps); ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSoundCapture_Initialize(dsco, lpGuid); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED|| rc==E_FAIL||rc==E_INVALIDARG, "IDirectSoundCapture_Initialize() failed: %08x\n", rc); if (rc==DSERR_NODRIVER||rc==E_INVALIDARG) { trace(" No Driver\n"); goto EXIT; } else if (rc==E_FAIL) { trace(" No Device\n"); goto EXIT; } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); goto EXIT; } } rc=IDirectSoundCapture_Initialize(dsco, lpGuid); ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() " "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSoundCapture_GetCaps(dsco, 0); ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); ZeroMemory(&dsccaps, sizeof(dsccaps)); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound_GetCaps(dsco, &dsccaps); ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); dsccaps.dwSize=sizeof(dsccaps); /* DSOUND: Running on a certified driver */ rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps); ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %08x\n", rc); EXIT: ref=IDirectSoundCapture_Release(dsco); ok(ref==0, "IDirectSoundCapture_Release() has %d references, " "should have 0\n", ref); }