📄 pa_win_ds.c
字号:
{ PaError result = paNoError; if( guidVector->items != NULL ) { if( LocalFree( guidVector->items ) != NULL ) result = paInsufficientMemory; /** @todo this isn't the correct error to return from a deallocation failure */ guidVector->items = NULL; } return result;}/************************************************************************************** Collect preliminary device information during DirectSound enumeration */static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext ){ DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext; PaError error; (void) lpszDrvName; /* unused variable */ if( namesAndGUIDs->free == 0 ) { error = ExpandDSDeviceNameAndGUIDVector( namesAndGUIDs ); if( error != paNoError ) { namesAndGUIDs->enumerationError = error; return FALSE; } } /* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */ if( lpGUID == NULL ) { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = NULL; } else { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = &namesAndGUIDs->items[namesAndGUIDs->count].guid; memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) ); } namesAndGUIDs->items[namesAndGUIDs->count].name = DuplicateDeviceNameString( namesAndGUIDs->allocations, lpszDesc ); if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL ) { namesAndGUIDs->enumerationError = paInsufficientMemory; return FALSE; } ++namesAndGUIDs->count; --namesAndGUIDs->free; return TRUE;}/* GUIDs for emulated devices which we blacklist below. are there more than two of them??*/GUID IID_IRolandVSCEmulated1 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x01};GUID IID_IRolandVSCEmulated2 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x02};#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };/************************************************************************************** Extract capabilities from an output device, and add it to the device info list** if successful. This function assumes that there is enough room in the** device info list to accomodate all entries.**** The device will not be added to the device list if any errors are encountered.*/static PaError AddOutputDeviceInfoFromDirectSound( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID ){ PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaDeviceInfo *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount]; PaWinDsDeviceInfo *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount]; HRESULT hr; LPDIRECTSOUND lpDirectSound; DSCAPS caps; int deviceOK = TRUE; PaError result = paNoError; int i; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; } if( lpGUID ) { if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) || IsEqualGUID (&IID_IRolandVSCEmulated2,lpGUID) ) { PA_DEBUG(("BLACKLISTED: %s \n",name)); return paNoError; } } /* Create a DirectSound object for the specified GUID Note that using CoCreateInstance doesn't work on windows CE. */ hr = paWinDsDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&lpDirectSound ); if( hr == S_OK ) { hr = IDirectSound_Initialize( lpDirectSound, lpGUID ); } */ if( hr != DS_OK ) { if (hr == DSERR_ALLOCATED) PA_DEBUG(("AddOutputDeviceInfoFromDirectSound %s DSERR_ALLOCATED\n",name)); DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr )); if (lpGUID) DBUG(("%s's GUID: {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x, 0x%x} \n", name, lpGUID->Data1, lpGUID->Data2, lpGUID->Data3, lpGUID->Data4[0], lpGUID->Data4[1], lpGUID->Data4[2], lpGUID->Data4[3], lpGUID->Data4[4], lpGUID->Data4[5], lpGUID->Data4[6], lpGUID->Data4[7])); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSound_GetCaps( lpDirectSound, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else {#ifndef PA_NO_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; }#endif if( deviceOK ) { deviceInfo->maxInputChannels = 0; /* Mono or stereo device? */ deviceInfo->maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; deviceInfo->defaultLowInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultLowOutputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighOutputLatency = 0.; /** @todo IMPLEMENT ME */ /* initialize defaultSampleRate */ if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) { /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */ deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ){ deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i]; break; } } } 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. */ deviceInfo->defaultSampleRate = 44100.0f; DBUG(("PA - Reported rates both zero. Setting to fake values for device #%s\n", name )); } else { deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; } } 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. */ deviceInfo->defaultSampleRate = 44100.0f; DBUG(("PA - Sample rate range used instead of two odd values for device #%s\n", name )); } else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate ); // dwFlags | DSCAPS_CONTINUOUSRATE } } IDirectSound_Release( lpDirectSound ); } if( deviceOK ) { deviceInfo->name = name; if( lpGUID == NULL ) hostApi->info.defaultOutputDevice = hostApi->info.deviceCount; hostApi->info.deviceCount++; } return result;}/************************************************************************************** Extract capabilities from an input device, and add it to the device info list** if successful. This function assumes that there is enough room in the** device info list to accomodate all entries.**** The device will not be added to the device list if any errors are encountered.*/static PaError AddInputDeviceInfoFromDirectSoundCapture( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID ){ PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaDeviceInfo *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount]; PaWinDsDeviceInfo *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount]; HRESULT hr; LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; DSCCAPS caps; int deviceOK = TRUE; PaError result = paNoError; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); } hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture ); */ if( hr != DS_OK ) { DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else {#ifndef PA_NO_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; }#endif if( deviceOK ) { deviceInfo->maxInputChannels = caps.dwChannels; deviceInfo->maxOutputChannels = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -