hotplug: added connectionId parameter to PaDeviceInfo and bumped struct version number. added PaUtil_MakeDeviceConnectionId() function and used it to initialize connectionId in all host APIs. updated patest_refresh_device_list to display connection id. NOTE: persistent connection ids have not been implemented in dsound and wdmks, so refreshing the device list will change connection ids.

This commit is contained in:
Ross Bencina 2016-09-02 20:27:39 +10:00
commit d41ba780b2
14 changed files with 56 additions and 17 deletions

View file

@ -500,7 +500,7 @@ typedef void PaDevicesChangedCallback( void *userData );
@see PaStreamFinishedCallback
*/
PaError Pa_SetDevicesChangedCallback( void *userData, PaStreamFinishedCallback* devicesChangedCallback );
PaError Pa_SetDevicesChangedCallback( void *userData, PaDevicesChangedCallback* devicesChangedCallback );
/** The type used to represent monotonic time in seconds. PaTime is
@ -548,12 +548,20 @@ typedef unsigned long PaSampleFormat;
#define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */
/** A unique stable identifier for the duration of device connection,
or PA initialize/terminate, whichever is shorter.
@see Pa_RefreshDeviceList()
*/
typedef unsigned long PaDeviceConnectionId;
/** A structure providing information and capabilities of PortAudio devices.
Devices may support input, output or both input and output.
*/
typedef struct PaDeviceInfo
{
int structVersion; /* this is struct version 2 */
int structVersion; /* this is struct version 3 */
const char *name;
PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/
@ -568,6 +576,8 @@ typedef struct PaDeviceInfo
PaTime defaultHighOutputLatency;
double defaultSampleRate;
PaDeviceConnectionId connectionId; /**< @see PaDeviceConnectionId */
} PaDeviceInfo;

View file

@ -1955,3 +1955,9 @@ void PaUtil_DevicesChanged(unsigned state, void* pData)
PaUtil_UnlockHotPlug();
}
static PaDeviceConnectionId nextDeviceConnectionId_ = 1000;
PaDeviceConnectionId PaUtil_MakeDeviceConnectionId( void )
{
return nextDeviceConnectionId_++;
}

View file

@ -171,6 +171,9 @@ typedef struct PaUtilPrivatePaFrontHostApiInfo {
}PaUtilPrivatePaFrontHostApiInfo;
PaDeviceConnectionId PaUtil_MakeDeviceConnectionId( void );
/** The common header for all data structures whose pointers are passed through
the hostApiSpecificStreamInfo field of the PaStreamParameters structure.
Note that in order to keep the public PortAudio interface clean, this structure

View file

@ -1189,9 +1189,11 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d
}
}
baseDeviceInfo->structVersion = 2;
baseDeviceInfo->structVersion = 3;
baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
baseDeviceInfo->name = deviceHwInfo->name;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
devInfo->alsaName = deviceHwInfo->alsaName;
devInfo->isPlug = deviceHwInfo->isPlug;

View file

@ -636,7 +636,7 @@ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostA
hpiDevice->streamIndex = j;
hpiDevice->streamIsOutput = 0;
/* Set common PortAudio device stats */
baseDeviceInfo->structVersion = 2;
baseDeviceInfo->structVersion = 3;
/* Make sure name string is owned by API info structure */
sprintf( srcName,
"Adapter %d (%4X) - Input Stream %d", i+1, type, j+1 );
@ -656,6 +656,7 @@ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostA
/* HPI interface can actually handle any sampling rate to 1 Hz accuracy,
* so this default is as good as any */
baseDeviceInfo->defaultSampleRate = 44100;
baseDeviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
/* Store device in global PortAudio list */
hostApi->deviceInfos[deviceIndex++] = (PaDeviceInfo *) hpiDevice;
@ -678,7 +679,7 @@ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostA
hpiDevice->streamIndex = j;
hpiDevice->streamIsOutput = 1;
/* Set common PortAudio device stats */
baseDeviceInfo->structVersion = 2;
baseDeviceInfo->structVersion = 3;
/* Make sure name string is owned by API info structure */
sprintf( srcName,
"Adapter %d (%4X) - Output Stream %d", i+1, type, j+1 );
@ -698,6 +699,7 @@ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostA
/* HPI interface can actually handle any sampling rate to 1 Hz accuracy,
* so this default is as good as any */
baseDeviceInfo->defaultSampleRate = 44100;
baseDeviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
/* Store device in global PortAudio list */
hostApi->deviceInfos[deviceIndex++] = (PaDeviceInfo *) hpiDevice;

View file

@ -1322,10 +1322,11 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = names[i];
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError )
{

View file

@ -659,7 +659,7 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
memset(deviceInfo, 0, sizeof(PaDeviceInfo));
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
/* Get the device name using CFString */
@ -693,6 +693,7 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
CFRelease(nameRef);
}
deviceInfo->name = name;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
/* Try to get the default sample rate. Don't fail if we can't get this. */
propSize = sizeof(Float64);

View file

@ -993,6 +993,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
}
deviceInfo->name = name;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
return result;
@ -1162,7 +1163,8 @@ http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html
}
deviceInfo->name = name;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
return result;
error:
@ -1482,7 +1484,7 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
for( i = 0 ; i < maximumNewDeviceCount; ++i )
{
PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = 0;

View file

@ -573,7 +573,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
strlen(client_names[client_index]) + 1 ), paInsufficientMemory );
strcpy( (char *)curDevInfo->name, client_names[client_index] );
curDevInfo->structVersion = 2;
curDevInfo->structVersion = 3;
curDevInfo->hostApi = jackApi->hostApiIndex;
/* JACK is very inflexible: there is one sample rate the whole
@ -634,6 +634,8 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
commonApi->info.defaultInputDevice = client_index;
if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 )
commonApi->info.defaultOutputDevice = client_index;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
}
error:

View file

@ -298,7 +298,7 @@ PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name,
{
PaError result = paNoError;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
if( allocations )
{
size_t len = strlen( name ) + 1;
@ -316,6 +316,7 @@ PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name,
deviceInfo->defaultHighInputLatency = defaultHighInputLatency;
deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency;
deviceInfo->defaultSampleRate = defaultSampleRate;
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
error:
return result;

View file

@ -1314,7 +1314,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
{
DWORD state = 0;
PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
PA_DEBUG(("WASAPI: device idx: %02d\n", i));
@ -1508,6 +1508,8 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
break;
}
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
(*hostApi)->deviceInfos[i] = deviceInfo;
++(*hostApi)->info.deviceCount;
}

View file

@ -3530,7 +3530,7 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
for( i = 0 ; i < totalDeviceCount; ++i )
{
PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = 0;
outArgument->deviceInfos[ i ] = deviceInfo;
@ -3573,11 +3573,13 @@ static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaH
wdmDeviceInfo->filter = pFilter;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = wdmDeviceInfo->compositeName;
/* deviceInfo->hostApiSpecificDeviceInfo = &pFilter->devInfo; */
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
wdmDeviceInfo->pin = pin->pinId;
/* Get the name of the "device" */

View file

@ -789,6 +789,8 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId,
QueryInputWaveFormatEx, deviceInfo->maxInputChannels );
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
*success = 1;
error:
@ -924,6 +926,8 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId,
QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels );
deviceInfo->connectionId = PaUtil_MakeDeviceConnectionId();
*success = 1;
error:
@ -1069,7 +1073,7 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
@ -1112,7 +1116,7 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;

View file

@ -13,8 +13,9 @@ void printDevices()
const PaHostApiInfo *hostApiInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
assert( deviceInfo != 0 );
assert( deviceInfo->structVersion >= 3 ); /* should be the case if all APIs have implemented connectionId */
printf( "%d %s (%s)\n", i, deviceInfo->name, hostApiInfo->name );
printf( "%d (conn id: %d) %s (%s)\n", i, deviceInfo->connectionId, deviceInfo->name, hostApiInfo->name );
}
}