hotplug wmme: Factor out new Query{Input, Output} DeviceInterfaceName() functions to wrap DRV_QUERYDEVICEINTERFACE. Store the device interface name in PaWinMmeDeviceInfo::deviceInterfaceName, free the associated allocation in FreeDeviceInfos() (required adding deviceCount parameter). Rework WDM/KS-based numChannels query to use the stored deviceInterfaceName. Free name memory on error in InitializeInputDeviceInfo, InitializeOutputDeviceInfo. Implement device connectionId correlation by matching deviceInterfaceName using new functions: FindDeviceByConnectionId(), FindDeviceInfoByInterfaceName(), AssignDeviceConnectionId().
This commit is contained in:
parent
9745b2a590
commit
def5763094
1 changed files with 206 additions and 78 deletions
|
|
@ -445,6 +445,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
PaDeviceInfo inheritedDeviceInfo;
|
PaDeviceInfo inheritedDeviceInfo;
|
||||||
UINT winWmmeDeviceId; /*<< Windows MME device id for this device */
|
UINT winWmmeDeviceId; /*<< Windows MME device id for this device */
|
||||||
|
LPWSTR deviceInterfaceName; /*<< A null-terminated Unicode string containing the device-interface name returned by DRV_QUERYDEVICEINTERFACE.
|
||||||
|
see: https://msdn.microsoft.com/en-us/library/windows/hardware/ff536363(v=vs.85).aspx
|
||||||
|
We use this for connectionId impl because it works on Windows XP (DRV_QUERYFUNCTIONINSTANCEID is supported only on Vista and later) */
|
||||||
DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */
|
DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */
|
||||||
char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/
|
char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/
|
||||||
char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/
|
char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/
|
||||||
|
|
@ -678,45 +681,45 @@ static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
/* On error, *resultInterfaceName will be NULL */
|
||||||
static char QueryWaveInKSFilterMaxChannels( int waveInDeviceId, int *maxChannels )
|
static PaError QueryInputDeviceInterfaceName( PaUtilAllocationGroup *allocations, UINT waveInDeviceId, LPWSTR *resultInterfaceName )
|
||||||
{
|
{
|
||||||
void *devicePath;
|
LPWSTR resultString = NULL;
|
||||||
DWORD devicePathSize;
|
DWORD stringSize = 0;
|
||||||
char result = 0;
|
|
||||||
|
|
||||||
if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACESIZE,
|
*resultInterfaceName = NULL;
|
||||||
(DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
devicePath = PaUtil_AllocateMemory( devicePathSize );
|
if( waveInMessage( (HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACESIZE,
|
||||||
if( !devicePath )
|
(DWORD_PTR)&stringSize, 0 ) != MMSYSERR_NOERROR )
|
||||||
return 0;
|
return paUnanticipatedHostError;
|
||||||
|
|
||||||
/* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */
|
if( stringSize == 0 )
|
||||||
if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACE,
|
return paNoError;
|
||||||
(DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR )
|
|
||||||
|
resultString = (LPWSTR)PaUtil_GroupAllocateMemory( allocations, stringSize );
|
||||||
|
if( !resultString )
|
||||||
|
return paInsufficientMemory;
|
||||||
|
|
||||||
|
if( waveInMessage( (HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACE,
|
||||||
|
(DWORD_PTR)resultString, stringSize ) == MMSYSERR_NOERROR )
|
||||||
{
|
{
|
||||||
int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 1 );
|
*resultInterfaceName = resultString;
|
||||||
if( count > 0 )
|
return paNoError;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*maxChannels = count;
|
PaUtil_GroupFreeMemory( allocations, resultString );
|
||||||
result = 1;
|
return paUnanticipatedHostError;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PaUtil_FreeMemory( devicePath );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
|
||||||
|
|
||||||
|
|
||||||
static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
|
static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
|
||||||
PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success )
|
PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success )
|
||||||
{
|
{
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
char *deviceName; /* non-const ptr */
|
char *deviceName = NULL; /* non-const ptr */
|
||||||
|
LPWSTR deviceInterfaceName = NULL;
|
||||||
MMRESULT mmresult;
|
MMRESULT mmresult;
|
||||||
WAVEINCAPS wic;
|
WAVEINCAPS wic;
|
||||||
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
||||||
|
|
@ -772,6 +775,10 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
||||||
}
|
}
|
||||||
deviceInfo->name = deviceName;
|
deviceInfo->name = deviceName;
|
||||||
|
|
||||||
|
QueryInputDeviceInterfaceName( winMmeHostApi->allocations,
|
||||||
|
winMmeInputDeviceId, &deviceInterfaceName );
|
||||||
|
winMmeDeviceInfo->deviceInterfaceName = deviceInterfaceName;
|
||||||
|
|
||||||
if( wic.wChannels == 0xFFFF || wic.wChannels < 1 || wic.wChannels > 255 ){
|
if( wic.wChannels == 0xFFFF || wic.wChannels < 1 || wic.wChannels > 255 ){
|
||||||
/* For Windows versions using WDM (possibly Windows 98 ME and later)
|
/* For Windows versions using WDM (possibly Windows 98 ME and later)
|
||||||
* the kernel mixer sits between the application and the driver. As a result,
|
* the kernel mixer sits between the application and the driver. As a result,
|
||||||
|
|
@ -792,8 +799,17 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
||||||
winMmeDeviceInfo->deviceInputChannelCountIsKnown =
|
if( deviceInterfaceName != NULL )
|
||||||
QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels );
|
{
|
||||||
|
/* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path
|
||||||
|
that we can use with WDM/KS, although this seems to be undocumented */
|
||||||
|
int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( deviceInterfaceName, /* isInput= */ 1 );
|
||||||
|
if( count > 0 )
|
||||||
|
{
|
||||||
|
deviceInfo->maxInputChannels = count;
|
||||||
|
winMmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
||||||
|
|
||||||
winMmeDeviceInfo->dwFormats = wic.dwFormats;
|
winMmeDeviceInfo->dwFormats = wic.dwFormats;
|
||||||
|
|
@ -803,61 +819,59 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
||||||
|
|
||||||
winMmeDeviceInfo->winWmmeDeviceId = winMmeInputDeviceId;
|
winMmeDeviceInfo->winWmmeDeviceId = winMmeInputDeviceId;
|
||||||
|
|
||||||
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
|
|
||||||
|
|
||||||
*success = 1;
|
*success = 1;
|
||||||
|
return result;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, deviceName );
|
||||||
|
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, deviceInterfaceName );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
/* resultInterfaceName will be NULL if there's an error */
|
||||||
static int QueryWaveOutKSFilterMaxChannels( int waveOutDeviceId, int *maxChannels )
|
static PaError QueryOutputDeviceInterfaceName( PaUtilAllocationGroup *allocations, UINT waveOutDeviceId, LPWSTR *resultInterfaceName )
|
||||||
{
|
{
|
||||||
void *devicePath;
|
LPWSTR resultString = NULL;
|
||||||
DWORD devicePathSize;
|
DWORD stringSize = 0;
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACESIZE,
|
*resultInterfaceName = NULL;
|
||||||
(DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
devicePath = PaUtil_AllocateMemory( devicePathSize );
|
if( waveOutMessage( (HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACESIZE,
|
||||||
if( !devicePath )
|
(DWORD_PTR)&stringSize, 0 ) != MMSYSERR_NOERROR )
|
||||||
return 0;
|
return paInternalError;
|
||||||
|
|
||||||
/* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */
|
if( stringSize == 0 )
|
||||||
if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACE,
|
return paNoError;
|
||||||
(DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR )
|
|
||||||
|
resultString = (LPWSTR)PaUtil_GroupAllocateMemory( allocations, stringSize );
|
||||||
|
if( !resultString )
|
||||||
|
return paInsufficientMemory;
|
||||||
|
|
||||||
|
if( waveOutMessage( (HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACE,
|
||||||
|
(DWORD_PTR)resultString, stringSize ) == MMSYSERR_NOERROR )
|
||||||
{
|
{
|
||||||
int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 0 );
|
*resultInterfaceName = resultString;
|
||||||
if( count > 0 )
|
return paNoError;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*maxChannels = count;
|
PaUtil_GroupFreeMemory( allocations, resultString );
|
||||||
result = 1;
|
return paInternalError;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PaUtil_FreeMemory( devicePath );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
|
||||||
|
|
||||||
|
|
||||||
static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
|
static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
|
||||||
PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success )
|
PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success )
|
||||||
{
|
{
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
char *deviceName; /* non-const ptr */
|
char *deviceName = NULL; /* non-const ptr */
|
||||||
|
LPWSTR deviceInterfaceName = NULL;
|
||||||
MMRESULT mmresult;
|
MMRESULT mmresult;
|
||||||
WAVEOUTCAPS woc;
|
WAVEOUTCAPS woc;
|
||||||
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
||||||
size_t len;
|
size_t len;
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
|
||||||
int wdmksDeviceOutputChannelCountIsKnown;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*success = 0;
|
*success = 0;
|
||||||
|
|
||||||
|
|
@ -909,6 +923,10 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
||||||
}
|
}
|
||||||
deviceInfo->name = deviceName;
|
deviceInfo->name = deviceName;
|
||||||
|
|
||||||
|
QueryOutputDeviceInterfaceName( winMmeHostApi->allocations,
|
||||||
|
winMmeOutputDeviceId, &deviceInterfaceName );
|
||||||
|
winMmeDeviceInfo->deviceInterfaceName = deviceInterfaceName;
|
||||||
|
|
||||||
if( woc.wChannels == 0xFFFF || woc.wChannels < 1 || woc.wChannels > 255 ){
|
if( woc.wChannels == 0xFFFF || woc.wChannels < 1 || woc.wChannels > 255 ){
|
||||||
/* For Windows versions using WDM (possibly Windows 98 ME and later)
|
/* For Windows versions using WDM (possibly Windows 98 ME and later)
|
||||||
* the kernel mixer sits between the application and the driver. As a result,
|
* the kernel mixer sits between the application and the driver. As a result,
|
||||||
|
|
@ -929,10 +947,17 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
||||||
wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels(
|
if( deviceInterfaceName != NULL )
|
||||||
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
|
{
|
||||||
if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown )
|
/* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path
|
||||||
|
that we can use with WDM/KS, although this seems to be undocumented */
|
||||||
|
int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( deviceInterfaceName, /* isInput= */ 0 );
|
||||||
|
if( count > 0 )
|
||||||
|
{
|
||||||
|
deviceInfo->maxOutputChannels = count;
|
||||||
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
|
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
||||||
|
|
||||||
winMmeDeviceInfo->dwFormats = woc.dwFormats;
|
winMmeDeviceInfo->dwFormats = woc.dwFormats;
|
||||||
|
|
@ -942,11 +967,12 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
||||||
|
|
||||||
winMmeDeviceInfo->winWmmeDeviceId = winMmeOutputDeviceId;
|
winMmeDeviceInfo->winWmmeDeviceId = winMmeOutputDeviceId;
|
||||||
|
|
||||||
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
|
|
||||||
|
|
||||||
*success = 1;
|
*success = 1;
|
||||||
|
return result;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, deviceName );
|
||||||
|
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, deviceInterfaceName );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1274,14 +1300,101 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
return paFormatIsSupported;
|
return paFormatIsSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************************************************************/
|
/***********************************************************************************/
|
||||||
|
|
||||||
static void FreeDeviceInfos( PaUtilAllocationGroup *allocations, PaDeviceInfo **deviceInfos )
|
static const PaDeviceInfo* FindDeviceByConnectionId(
|
||||||
|
const PaDeviceInfo **deviceInfos, int deviceCount, PaDeviceConnectionId connectionId )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if( deviceCount )
|
||||||
|
{
|
||||||
|
assert( deviceInfos != NULL );
|
||||||
|
assert( deviceInfos[0] != NULL );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( i = 0; i < deviceCount; ++i )
|
||||||
|
{
|
||||||
|
const PaDeviceInfo *deviceInfo = deviceInfos[i];
|
||||||
|
if( deviceInfo->connectionId == connectionId )
|
||||||
|
return deviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* used for looking up existing devices to reuse their connectionId */
|
||||||
|
static const PaDeviceInfo* FindDeviceInfoByInterfaceName(
|
||||||
|
const PaDeviceInfo **deviceInfos, int deviceCount,
|
||||||
|
LPCWSTR deviceInterfaceName, int isInput )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if( deviceCount )
|
||||||
|
{
|
||||||
|
assert( deviceInfos != NULL );
|
||||||
|
assert( deviceInfos[0] != NULL );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( i = 0; i < deviceCount; ++i )
|
||||||
|
{
|
||||||
|
const PaDeviceInfo *deviceInfo = deviceInfos[i];
|
||||||
|
const PaWinMmeDeviceInfo *wmmeDeviceInfo = (const PaWinMmeDeviceInfo*)deviceInfo;
|
||||||
|
if( ((isInput && deviceInfo->maxInputChannels > 0)
|
||||||
|
|| (!isInput && deviceInfo->maxOutputChannels > 0))
|
||||||
|
&&
|
||||||
|
/* require both interface names to be non-NULL, because they can be NULL due to errors. */
|
||||||
|
(deviceInterfaceName != NULL && wmmeDeviceInfo->deviceInterfaceName != NULL
|
||||||
|
&& (wcscmp(deviceInterfaceName, wmmeDeviceInfo->deviceInterfaceName) == 0)) )
|
||||||
|
{
|
||||||
|
return deviceInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* correlate or allocate device connection id */
|
||||||
|
static PaDeviceConnectionId AssignDeviceConnectionId(
|
||||||
|
const PaDeviceInfo **activeDeviceInfos, int activeDeviceCount,
|
||||||
|
const PaDeviceInfo **newDeviceInfos, int newDeviceCount,
|
||||||
|
LPCWSTR deviceInterfaceName, int isInput )
|
||||||
|
{
|
||||||
|
const PaDeviceInfo *currentDeviceInfo;
|
||||||
|
|
||||||
|
currentDeviceInfo = FindDeviceInfoByInterfaceName(
|
||||||
|
activeDeviceInfos, activeDeviceCount, /* search active device list for deviceInterfaceName */
|
||||||
|
deviceInterfaceName, isInput );
|
||||||
|
|
||||||
|
if( currentDeviceInfo && FindDeviceByConnectionId(
|
||||||
|
newDeviceInfos, newDeviceCount, /* search new device list connectionId */
|
||||||
|
currentDeviceInfo->connectionId ) == NULL )
|
||||||
|
{
|
||||||
|
/* deviceInterfaceName matches, and its connectionId hasn't already been reused */
|
||||||
|
return currentDeviceInfo->connectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PaUtil_MakeDeviceConnectionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void FreeDeviceInfos( PaUtilAllocationGroup *allocations, PaDeviceInfo **deviceInfos, int deviceCount )
|
||||||
{
|
{
|
||||||
if( deviceInfos )
|
if( deviceInfos )
|
||||||
{
|
{
|
||||||
if( deviceInfos[0] )
|
if( deviceInfos[0] )
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
for( i = 0; i < deviceCount; ++i )
|
||||||
|
{
|
||||||
|
PaWinMmeDeviceInfo *wmmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfos[ i ];
|
||||||
|
PaUtil_GroupFreeMemory( allocations, wmmeDeviceInfo->deviceInterfaceName );
|
||||||
|
}
|
||||||
|
|
||||||
/* all device info structs are allocated in a block so we can destroy them like this */
|
/* all device info structs are allocated in a block so we can destroy them like this */
|
||||||
PaUtil_GroupFreeMemory( allocations, deviceInfos[0] );
|
PaUtil_GroupFreeMemory( allocations, deviceInfos[0] );
|
||||||
}
|
}
|
||||||
|
|
@ -1416,6 +1529,8 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
|
||||||
/* N.B. Prior WMME versions failed scanning with an error here. */
|
/* N.B. Prior WMME versions failed scanning with an error here. */
|
||||||
|
|
||||||
if( deviceInfoInitializationSucceeded ){
|
if( deviceInfoInitializationSucceeded ){
|
||||||
|
/* NOTE: wmmeDeviceInfo->deviceInterfaceName is now allocated and would need to be freed on error. */
|
||||||
|
|
||||||
if( outArgument->defaultInputDevice == paNoDevice )
|
if( outArgument->defaultInputDevice == paNoDevice )
|
||||||
{
|
{
|
||||||
/* if there is currently no default device, use the first one available */
|
/* if there is currently no default device, use the first one available */
|
||||||
|
|
@ -1427,6 +1542,11 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
|
||||||
outArgument->defaultInputDevice = *newDeviceCount;
|
outArgument->defaultInputDevice = *newDeviceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceInfo->connectionId = AssignDeviceConnectionId(
|
||||||
|
hostApi->deviceInfos, hostApi->info.deviceCount,
|
||||||
|
outArgument->deviceInfos, *newDeviceCount,
|
||||||
|
wmmeDeviceInfo->deviceInterfaceName, /* isInput= */ 1 );
|
||||||
|
|
||||||
outArgument->deviceInfos[ *newDeviceCount ] = deviceInfo;
|
outArgument->deviceInfos[ *newDeviceCount ] = deviceInfo;
|
||||||
outArgument->inputDeviceCount++;
|
outArgument->inputDeviceCount++;
|
||||||
(*newDeviceCount)++;
|
(*newDeviceCount)++;
|
||||||
|
|
@ -1465,6 +1585,8 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
|
||||||
/* N.B. Prior WMME versions failed scanning with an error here. */
|
/* N.B. Prior WMME versions failed scanning with an error here. */
|
||||||
|
|
||||||
if( deviceInfoInitializationSucceeded ){
|
if( deviceInfoInitializationSucceeded ){
|
||||||
|
/* NOTE: wmmeDeviceInfo->deviceInterfaceName is now allocated and would need to be freed on error. */
|
||||||
|
|
||||||
if( outArgument->defaultOutputDevice == paNoDevice )
|
if( outArgument->defaultOutputDevice == paNoDevice )
|
||||||
{
|
{
|
||||||
/* if there is currently no default device, use the first one available */
|
/* if there is currently no default device, use the first one available */
|
||||||
|
|
@ -1477,6 +1599,11 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
|
||||||
outArgument->defaultOutputDevice = *newDeviceCount;
|
outArgument->defaultOutputDevice = *newDeviceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceInfo->connectionId = AssignDeviceConnectionId(
|
||||||
|
hostApi->deviceInfos, hostApi->info.deviceCount,
|
||||||
|
outArgument->deviceInfos, *newDeviceCount,
|
||||||
|
wmmeDeviceInfo->deviceInterfaceName, /* isInput= */ 0 );
|
||||||
|
|
||||||
outArgument->deviceInfos[ *newDeviceCount ] = deviceInfo;
|
outArgument->deviceInfos[ *newDeviceCount ] = deviceInfo;
|
||||||
outArgument->outputDeviceCount++;
|
outArgument->outputDeviceCount++;
|
||||||
(*newDeviceCount)++;
|
(*newDeviceCount)++;
|
||||||
|
|
@ -1493,8 +1620,10 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
|
||||||
error:
|
error:
|
||||||
if( outArgument )
|
if( outArgument )
|
||||||
{
|
{
|
||||||
FreeDeviceInfos( winMmeHostApi->allocations, outArgument->deviceInfos );
|
FreeDeviceInfos( winMmeHostApi->allocations, outArgument->deviceInfos, *newDeviceCount );
|
||||||
}
|
}
|
||||||
|
*newDeviceCount = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1505,16 +1634,15 @@ static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, P
|
||||||
|
|
||||||
(void)index; /* unused parameter */
|
(void)index; /* unused parameter */
|
||||||
|
|
||||||
hostApi->info.deviceCount = 0;
|
|
||||||
hostApi->info.defaultInputDevice = paNoDevice;
|
|
||||||
hostApi->info.defaultOutputDevice = paNoDevice;
|
|
||||||
|
|
||||||
/* Free any old memory which might be in the device info */
|
/* Free any old memory which might be in the device info */
|
||||||
if( hostApi->deviceInfos )
|
if( hostApi->deviceInfos )
|
||||||
{
|
{
|
||||||
FreeDeviceInfos( winMmeHostApi->allocations, hostApi->deviceInfos );
|
FreeDeviceInfos( winMmeHostApi->allocations, hostApi->deviceInfos, hostApi->info.deviceCount );
|
||||||
hostApi->deviceInfos = NULL;
|
hostApi->deviceInfos = NULL;
|
||||||
}
|
}
|
||||||
|
hostApi->info.deviceCount = 0;
|
||||||
|
hostApi->info.defaultInputDevice = paNoDevice;
|
||||||
|
hostApi->info.defaultOutputDevice = paNoDevice;
|
||||||
|
|
||||||
if( scanResults != NULL )
|
if( scanResults != NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -1550,7 +1678,7 @@ static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
if( scanDeviceInfosResults->deviceInfos )
|
if( scanDeviceInfosResults->deviceInfos )
|
||||||
{
|
{
|
||||||
FreeDeviceInfos( winMmeHostApi->allocations, hostApi->deviceInfos );
|
FreeDeviceInfos( winMmeHostApi->allocations, hostApi->deviceInfos, deviceCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
|
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
|
||||||
|
|
@ -1559,7 +1687,7 @@ static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
return paNoError;
|
return paNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************************************************************/
|
/***********************************************************************************/
|
||||||
|
|
||||||
static unsigned long ComputeHostBufferCountForFixedBufferSizeFrames(
|
static unsigned long ComputeHostBufferCountForFixedBufferSizeFrames(
|
||||||
unsigned long suggestedLatencyFrames,
|
unsigned long suggestedLatencyFrames,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue