Adds hotplug to portaudio wmme host api, also fixes a NPE that can prevent

device change updates.
damencho committed on Nov 6, 2012
5ca6fed from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
This commit is contained in:
Ross Bencina 2016-09-03 22:44:31 +10:00
commit 15d77417bf

View file

@ -245,6 +245,9 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters, const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters, const PaStreamParameters *outputParameters,
double sampleRate ); double sampleRate );
static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void **newDeviceInfos, int *newDeviceCount );
static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *deviceInfos, int deviceCount );
static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *deviceInfos, int deviceCount );
static PaError CloseStream( PaStream* stream ); static PaError CloseStream( PaStream* stream );
static PaError StartStream( PaStream *stream ); static PaError StartStream( PaStream *stream );
static PaError StopStream( PaStream *stream ); static PaError StopStream( PaStream *stream );
@ -399,6 +402,8 @@ typedef struct
device ids. device ids.
*/ */
UINT *winMmeDeviceIds; UINT *winMmeDeviceIds;
//char comWasInitialized;
} }
PaWinMmeHostApiRepresentation; PaWinMmeHostApiRepresentation;
@ -412,6 +417,14 @@ typedef struct
} }
PaWinMmeDeviceInfo; PaWinMmeDeviceInfo;
typedef struct PaWinMmeScanDeviceInfosResults{ /* used for tranferring device infos during scanning / rescanning */
PaDeviceInfo **deviceInfos;
PaDeviceIndex defaultInputDevice;
PaDeviceIndex defaultOutputDevice;
int inputDeviceCount, outputDeviceCount;
} PaWinMmeScanDeviceInfosResults;
/************************************************************************* /*************************************************************************
* Returns recommended device ID. * Returns recommended device ID.
@ -993,14 +1006,10 @@ static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighL
PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{ {
PaError result = paNoError; PaError result = paNoError;
int i; int deviceCount;
PaWinMmeHostApiRepresentation *winMmeHostApi; PaWinMmeHostApiRepresentation *winMmeHostApi;
int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount; //char comWasInitialized = 1;
PaWinMmeDeviceInfo *deviceInfoArray; void *scanResults = 0;
int deviceInfoInitializationSucceeded;
PaTime defaultLowLatency, defaultHighLatency;
DWORD waveInPreferredDevice, waveOutPreferredDevice;
DWORD preferredDeviceStatusFlags;
winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) ); winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) );
if( !winMmeHostApi ) if( !winMmeHostApi )
@ -1009,6 +1018,8 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
goto error; goto error;
} }
//winMmeHostApi->comWasInitialized = comWasInitialized;
winMmeHostApi->allocations = PaUtil_CreateAllocationGroup(); winMmeHostApi->allocations = PaUtil_CreateAllocationGroup();
if( !winMmeHostApi->allocations ) if( !winMmeHostApi->allocations )
{ {
@ -1025,162 +1036,28 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
there are no devices. These values are incremented below if and when there are no devices. These values are incremented below if and when
devices are successfully initialized. devices are successfully initialized.
*/ */
/* these are all updated by CommitDeviceInfos() */
(*hostApi)->info.deviceCount = 0; (*hostApi)->info.deviceCount = 0;
(*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice;
winMmeHostApi->inputDeviceCount = 0; winMmeHostApi->inputDeviceCount = 0;
winMmeHostApi->outputDeviceCount = 0; winMmeHostApi->outputDeviceCount = 0;
#if !defined(DRVM_MAPPER_PREFERRED_GET) result = ScanDeviceInfos( &winMmeHostApi->inheritedHostApiRep, hostApiIndex, &scanResults, &deviceCount );
/* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21)
#endif
/* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */
preferredDeviceStatusFlags = 0;
waveInPreferredDevice = -1;
waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
preferredDeviceStatusFlags = 0;
waveOutPreferredDevice = -1;
waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
maximumPossibleDeviceCount = 0;
inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
if( maximumPossibleDeviceCount > 0 ){
(*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
if( !(*hostApi)->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
/* allocate all device info structs in a contiguous block */
deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
if( !winMmeHostApi->winMmeDeviceIds )
{
result = paInsufficientMemory;
goto error;
}
GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
if( inputDeviceCount > 0 ){
/* -1 is the WAVE_MAPPER */
for( i = -1; i < inputDeviceCount; ++i ){
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
if( result != paNoError ) if( result != paNoError )
{
goto error; goto error;
if( deviceInfoInitializationSucceeded ){
if( (*hostApi)->info.defaultInputDevice == paNoDevice ){
/* if there is currently no default device, use the first one available */
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
}else if( winMmeDeviceId == waveInPreferredDevice ){
/* set the default device to the system preferred device */
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
} }
winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; /* FIXME for now we ignore the result of CommitDeviceInfos(), it should probably be an atomic non-failing operation */
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; CommitDeviceInfos( &winMmeHostApi->inheritedHostApiRep, hostApiIndex, scanResults, deviceCount );
winMmeHostApi->inputDeviceCount++;
(*hostApi)->info.deviceCount++;
}
}
}
if( outputDeviceCount > 0 ){
/* -1 is the WAVE_MAPPER */
for( i = -1; i < outputDeviceCount; ++i ){
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
if( result != paNoError )
goto error;
if( deviceInfoInitializationSucceeded ){
if( (*hostApi)->info.defaultOutputDevice == paNoDevice ){
/* if there is currently no default device, use the first one available */
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
}else if( winMmeDeviceId == waveOutPreferredDevice ){
/* set the default device to the system preferred device */
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
}
winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
winMmeHostApi->outputDeviceCount++;
(*hostApi)->info.deviceCount++;
}
}
}
}
InitializeDefaultDeviceIdsFromEnv( winMmeHostApi );
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
(*hostApi)->ScanDeviceInfos = 0; (*hostApi)->ScanDeviceInfos = ScanDeviceInfos;
(*hostApi)->CommitDeviceInfos = 0; (*hostApi)->CommitDeviceInfos = CommitDeviceInfos;
(*hostApi)->DisposeDeviceInfos = 0; (*hostApi)->DisposeDeviceInfos = DisposeDeviceInfos;
PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream, PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive, StopStream, AbortStream, IsStreamStopped, IsStreamActive,
@ -1417,7 +1294,290 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
return paFormatIsSupported; return paFormatIsSupported;
} }
/***********************************************************************************/
static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex hostApiIndex, void **scanResults, int *newDeviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
PaWinMmeDeviceInfo *deviceInfoArray;
//char comWasInitialized = winMmeHostApi->comWasInitialized;
PaError result = paNoError;
PaWinMmeScanDeviceInfosResults *outArgument = 0;
//DSDeviceNamesAndGUIDs deviceNamesAndGUIDs;
int i = 0;
int maximumPossibleDeviceCount = 0;
int inputDeviceCount, outputDeviceCount;
int deviceInfoInitializationSucceeded;
PaTime defaultLowLatency, defaultHighLatency;
DWORD waveInPreferredDevice, waveOutPreferredDevice;
DWORD preferredDeviceStatusFlags;
// Check preconditions
if( /*!comWasInitialized ||*/ scanResults == NULL || newDeviceCount == NULL )
return paInternalError;
/* initialize the out params */
*scanResults = NULL;
*newDeviceCount = 0;
#if !defined(DRVM_MAPPER_PREFERRED_GET)
/* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21)
#endif
/* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */
preferredDeviceStatusFlags = 0;
waveInPreferredDevice = -1;
waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
preferredDeviceStatusFlags = 0;
waveOutPreferredDevice = -1;
waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
maximumPossibleDeviceCount = 0;
inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; // assume there is a WAVE_MAPPER
outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1;// assume there is a WAVE_MAPPER
if( maximumPossibleDeviceCount > 0 )
{
/* Allocate the out param for all the info we need */
outArgument = (PaWinMmeScanDeviceInfosResults *) PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeScanDeviceInfosResults) );
if( !outArgument )
{
result = paInsufficientMemory;
goto error;
}
/* allocate array for pointers to PaDeviceInfo structs */
outArgument->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
if( !outArgument->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
// allocate all device info structs in a contiguous block
deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
if( !winMmeHostApi->winMmeDeviceIds )
{
result = paInsufficientMemory;
goto error;
}
for( i = 0 ; i < maximumPossibleDeviceCount; ++i )
{
PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = 0;
outArgument->deviceInfos[ i ] = deviceInfo;
}
outArgument->inputDeviceCount = 0;
outArgument->outputDeviceCount = 0;
GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
if( inputDeviceCount > 0 )
{
// -1 is the WAVE_MAPPER
for( i = -1; i < inputDeviceCount; ++i )
{
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = (PaWinMmeDeviceInfo*)outArgument->deviceInfos[*newDeviceCount];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
/* ignore error results here and just skip the device */
if( result != paNoError )
continue;
if( deviceInfoInitializationSucceeded )
{
if( outArgument->defaultInputDevice == paNoDevice )
{
// if there is currently no default device, use the first one available
outArgument->defaultInputDevice = *newDeviceCount;
}
else if( winMmeDeviceId == waveInPreferredDevice )
{
// set the default device to the system preferred device
outArgument->defaultInputDevice = *newDeviceCount;
}
winMmeHostApi->winMmeDeviceIds[ *newDeviceCount ] = winMmeDeviceId;
outArgument->inputDeviceCount++;
(*newDeviceCount)++;
}
}
}
if( outputDeviceCount > 0 )
{
// -1 is the WAVE_MAPPER
for( i = -1; i < outputDeviceCount; ++i )
{
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = (PaWinMmeDeviceInfo*)outArgument->deviceInfos[*newDeviceCount];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
/* ignore error results here and just skip the device */
if( result != paNoError )
continue;
if( deviceInfoInitializationSucceeded )
{
if( outArgument->defaultOutputDevice == paNoDevice )
{
// if there is currently no default device, use the first one available
outArgument->defaultOutputDevice = *newDeviceCount;
}
else if( winMmeDeviceId == waveOutPreferredDevice )
{
// set the default device to the system preferred device
outArgument->defaultOutputDevice = *newDeviceCount;
}
winMmeHostApi->winMmeDeviceIds[ *newDeviceCount ] = winMmeDeviceId;
outArgument->outputDeviceCount++;
(*newDeviceCount)++;
}
}
}
}
InitializeDefaultDeviceIdsFromEnv( winMmeHostApi );
*scanResults = outArgument;
return result;
error:
if( outArgument )
{
if( outArgument->deviceInfos )
{
if( outArgument->deviceInfos[0] )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, outArgument->deviceInfos[0] );
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, outArgument->deviceInfos );
}
}
return result;
}
static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *scanResults, int deviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
PaError result = paNoError;
int i = 0;
hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
/* Free any old memory which might be in the device info */
if( hostApi->deviceInfos )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, hostApi->deviceInfos[0] );
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, hostApi->deviceInfos );
hostApi->deviceInfos = NULL;
}
if( scanResults != NULL )
{
PaWinMmeScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinMmeScanDeviceInfosResults * ) scanResults;
if( deviceCount > 0 )
{
// use the array allocated in ScanDeviceInfos() as our deviceInfos
hostApi->deviceInfos = scanDeviceInfosResults->deviceInfos;
hostApi->info.defaultInputDevice = scanDeviceInfosResults->defaultInputDevice;
hostApi->info.defaultOutputDevice = scanDeviceInfosResults->defaultOutputDevice;
hostApi->info.deviceCount = deviceCount;
winMmeHostApi->inputDeviceCount = scanDeviceInfosResults->inputDeviceCount;
winMmeHostApi->outputDeviceCount = scanDeviceInfosResults->outputDeviceCount;
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
}
return result;
}
static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
if( scanResults != NULL )
{
PaWinMmeScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinMmeScanDeviceInfosResults * ) scanResults;
if( scanDeviceInfosResults->deviceInfos )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults->deviceInfos[0] ); // all device info structs are allocated in a block so we can destroy them here
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults->deviceInfos );
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
}
return paNoError;
}
/***********************************************************************************/
static void SelectBufferSizeAndCount( unsigned long baseBufferSize, static void SelectBufferSizeAndCount( unsigned long baseBufferSize,
unsigned long requestedLatency, unsigned long requestedLatency,