Browse Source

Merge branch 'winrt' into 'master'

WinRT: fixed failure to initialize WASAPI when Capture device is not provided by OS, and additional minor corrections.

Merged-on: https://assembla.com/code/portaudio/git/merge_requests/5913713
mr/new/c5e8f1dca7f2d1b9c3d5c92a3f6f174870c303d8
Dmitry Kostjuchenko 1 year ago
parent
commit
9923e1dc31
2 changed files with 234 additions and 110 deletions
  1. 14
    0
      include/pa_win_wasapi.h
  2. 220
    110
      src/hostapi/wasapi/pa_win_wasapi.c

+ 14
- 0
include/pa_win_wasapi.h View File

@@ -291,6 +291,18 @@ typedef struct PaWasapiStreamInfo
PaWasapiStreamInfo;


/** Update device list.
This function will be available if PA_WASAPI_MAX_CONST_DEVICE_COUNT is defined with maximum
constant WASAPI device count (defined by default with value 32).
If PA_WASAPI_MAX_CONST_DEVICE_COUNT is set to 0 during compile time the implementation will not
define PaWasapi_UpdateDeviceList() and thus updating device list can only be possible by calling
Pa_Terminate() and then Pa_Initialize().

@return Error code indicating success or failure.
*/
PaError PaWasapi_UpdateDeviceList();


/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
WAVEFORMATEXTENSIBLE structure.

@@ -356,6 +368,7 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
/** Get number of jacks associated with a WASAPI device. Use this method to determine if
there are any jacks associated with the provided WASAPI device. Not all audio devices
will support this capability. This is valid for both input and output devices.

@param nDevice device index.
@param jcount Number of jacks is returned in this variable
@return Error code indicating success or failure
@@ -369,6 +382,7 @@ PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
number of jacks associated with device. If jcount is greater than zero, then
each jack from 0 to jcount can be queried with this function to get the jack
description.

@param nDevice device index.
@param jindex Which jack to return information
@param KSJACK_DESCRIPTION This structure filled in on success.

+ 220
- 110
src/hostapi/wasapi/pa_win_wasapi.c View File

@@ -47,6 +47,12 @@
#include <process.h>
#include <assert.h>

// Max device count (if defined) causes max constant device count in the device list that
// enables PaWasapi_UpdateDeviceList() API and makes it possible to update WASAPI list dynamically
#ifndef PA_WASAPI_MAX_CONST_DEVICE_COUNT
#define PA_WASAPI_MAX_CONST_DEVICE_COUNT 32
#endif

// WinRT
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define PA_WINRT
@@ -432,11 +438,6 @@ typedef struct

PaWinUtilComInitializationResult comInitializationResult;

//in case we later need the synch
#ifndef PA_WINRT
IMMDeviceEnumerator *enumerator;
#endif

//this is the REAL number of devices, whether they are usefull to PA or not!
UINT32 deviceCount;

@@ -639,6 +640,9 @@ static HRESULT __LogHostError(HRESULT res, const char *func, const char *file, i
text = "UNKNOWN ERROR";
}
PRINT(("WASAPI ERROR HRESULT: 0x%X : %s\n [FUNCTION: %s FILE: %s {LINE: %d}]\n", res, text, func, file, line));
#ifndef PA_ENABLE_DEBUG_OUTPUT
(void)func; (void)file; (void)line;
#endif
PA_SKELETON_SET_LAST_HOST_ERROR(res, text);
return res;
}
@@ -649,7 +653,11 @@ static PaError __LogPaError(PaError err, const char *func, const char *file, int
{
if (err == paNoError)
return err;

PRINT(("WASAPI ERROR PAERROR: %i : %s\n [FUNCTION: %s FILE: %s {LINE: %d}]\n", err, Pa_GetErrorText(err), func, file, line));
#ifndef PA_ENABLE_DEBUG_OUTPUT
(void)func; (void)file; (void)line;
#endif
return err;
}

@@ -1344,7 +1352,7 @@ static IActivateAudioInterfaceCompletionHandler *CreateActivateAudioInterfaceCom

// ------------------------------------------------------------------------------------------
#ifdef PA_WINRT
static HRESULT ActivateAudioInterface_WINRT(const PaWasapiDeviceInfo *deviceInfo, const IID *iid, void **obj)
static HRESULT ActivateAudioInterface_WINRT(EDataFlow flow, const IID *iid, void **obj)
{
#define PA_WASAPI_DEVICE_PATH_LEN 64
@@ -1356,7 +1364,7 @@ static HRESULT ActivateAudioInterface_WINRT(const PaWasapiDeviceInfo *deviceInfo
OLECHAR devicePath[PA_WASAPI_DEVICE_PATH_LEN] = { 0 };

// Get device path in form L"{DEVICE_GUID}"
switch (deviceInfo->flow)
switch (flow)
{
case eRender:
StringFromGUID2(&DEVINTERFACE_AUDIO_RENDER, devicePath, PA_WASAPI_DEVICE_PATH_LEN - 1);
@@ -1399,7 +1407,7 @@ static HRESULT ActivateAudioInterface(const PaWasapiDeviceInfo *deviceInfo, IAud
#ifndef PA_WINRT
return IMMDevice_Activate(deviceInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void **)client);
#else
return ActivateAudioInterface_WINRT(deviceInfo, GetAudioClientIID(), (void **)client);
return ActivateAudioInterface_WINRT(deviceInfo->flow, GetAudioClientIID(), (void **)client);
#endif
}

@@ -1416,61 +1424,28 @@ static DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn,
#endif

// ------------------------------------------------------------------------------------------
PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
static PaError CreateDeviceList(PaWasapiHostApiRepresentation *paWasapi, PaHostApiIndex hostApiIndex)
{
PaUtilHostApiRepresentation *hostApi = (PaUtilHostApiRepresentation *)paWasapi;
PaError result = paNoError;
PaWasapiHostApiRepresentation *paWasapi;
PaDeviceInfo *deviceInfoArray;
HRESULT hr = S_OK;
UINT i;
#ifndef PA_WINRT
IMMDeviceCollection* pEndPoints = NULL;
IMMDeviceEnumerator *pEnumerator = NULL;
#else
WAVEFORMATEX *mixFormat;
#endif
IAudioClient *tmpClient;

#ifndef PA_WINRT
if (!SetupAVRT())
{
PRINT(("WASAPI: No AVRT! (not VISTA?)"));
return paNoError;
}
#endif

paWasapi = (PaWasapiHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaWasapiHostApiRepresentation) );
if (paWasapi == NULL)
{
result = paInsufficientMemory;
goto error;
}
memset( paWasapi, 0, sizeof(PaWasapiHostApiRepresentation) ); /* ensure all fields are zeroed. especially paWasapi->allocations */

result = PaWinUtil_CoInitialize( paWASAPI, &paWasapi->comInitializationResult );
if( result != paNoError )
{
goto error;
}

paWasapi->allocations = PaUtil_CreateAllocationGroup();
if (paWasapi->allocations == NULL)
{
result = paInsufficientMemory;
goto error;
}

*hostApi = &paWasapi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paWASAPI;
(*hostApi)->info.name = "Windows WASAPI";
(*hostApi)->info.deviceCount = 0;
(*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice;
// Make sure device list empty
if ((paWasapi->deviceCount != 0) || (hostApi->info.deviceCount != 0))
return paInternalError;

#ifndef PA_WINRT
paWasapi->enumerator = NULL;
hr = CoCreateInstance(&pa_CLSID_IMMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER,
&pa_IID_IMMDeviceEnumerator, (void **)&paWasapi->enumerator);
&pa_IID_IMMDeviceEnumerator, (void **)&pEnumerator);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
@@ -1480,7 +1455,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
{
{
IMMDevice *defaultRenderer = NULL;
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(paWasapi->enumerator, eRender, eMultimedia, &defaultRenderer);
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(pEnumerator, eRender, eMultimedia, &defaultRenderer);
if (hr != S_OK)
{
if (hr != E_NOTFOUND) {
@@ -1504,7 +1479,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd

{
IMMDevice *defaultCapturer = NULL;
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(paWasapi->enumerator, eCapture, eMultimedia, &defaultCapturer);
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(pEnumerator, eCapture, eMultimedia, &defaultCapturer);
if (hr != S_OK)
{
if (hr != E_NOTFOUND) {
@@ -1527,7 +1502,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
}
}

hr = IMMDeviceEnumerator_EnumAudioEndpoints(paWasapi->enumerator, eAll, DEVICE_STATE_ACTIVE, &pEndPoints);
hr = IMMDeviceEnumerator_EnumAudioEndpoints(pEnumerator, eAll, DEVICE_STATE_ACTIVE, &pEndPoints);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
@@ -1538,7 +1513,17 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);

#else
paWasapi->deviceCount = 2;
// Determine number of available devices by activating AudioClient for render and capture data flows
if (!FAILED(ActivateAudioInterface_WINRT(eRender, GetAudioClientIID(), &tmpClient)))
{
paWasapi->deviceCount++;
SAFE_RELEASE(tmpClient);
}
if (!FAILED(ActivateAudioInterface_WINRT(eCapture, GetAudioClientIID(), &tmpClient)))
{
paWasapi->deviceCount++;
SAFE_RELEASE(tmpClient);
}
#endif

paWasapi->devInfo = (PaWasapiDeviceInfo *)PaUtil_AllocateMemory(sizeof(PaWasapiDeviceInfo) * paWasapi->deviceCount);
@@ -1547,14 +1532,19 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
result = paInsufficientMemory;
goto error;
}
for (i = 0; i < paWasapi->deviceCount; ++i)
memset(&paWasapi->devInfo[i], 0, sizeof(PaWasapiDeviceInfo));
memset(paWasapi->devInfo, 0, sizeof(PaWasapiDeviceInfo) * paWasapi->deviceCount);

if (paWasapi->deviceCount > 0)
{
(*hostApi)->deviceInfos = (PaDeviceInfo **)PaUtil_GroupAllocateMemory(
paWasapi->allocations, sizeof(PaDeviceInfo *) * paWasapi->deviceCount);
if ((*hostApi)->deviceInfos == NULL)
UINT32 deviceCount = paWasapi->deviceCount;
#if defined(PA_WASAPI_MAX_CONST_DEVICE_COUNT) && (PA_WASAPI_MAX_CONST_DEVICE_COUNT > 0)
if (deviceCount < PA_WASAPI_MAX_CONST_DEVICE_COUNT)
deviceCount = PA_WASAPI_MAX_CONST_DEVICE_COUNT;
#endif

hostApi->deviceInfos = (PaDeviceInfo **)PaUtil_GroupAllocateMemory(
paWasapi->allocations, sizeof(PaDeviceInfo *) * deviceCount);
if (hostApi->deviceInfos == NULL)
{
result = paInsufficientMemory;
goto error;
@@ -1562,12 +1552,13 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd

/* allocate all device info structs in a contiguous block */
deviceInfoArray = (PaDeviceInfo *)PaUtil_GroupAllocateMemory(
paWasapi->allocations, sizeof(PaDeviceInfo) * paWasapi->deviceCount);
paWasapi->allocations, sizeof(PaDeviceInfo) * deviceCount);
if (deviceInfoArray == NULL)
{
result = paInsufficientMemory;
goto error;
}
memset(deviceInfoArray, 0, sizeof(PaDeviceInfo) * deviceCount);

for (i = 0; i < paWasapi->deviceCount; ++i)
{
@@ -1596,11 +1587,11 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd

if (lstrcmpW(paWasapi->devInfo[i].szDeviceID, paWasapi->defaultCapturer) == 0)
{// we found the default input!
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
hostApi->info.defaultInputDevice = hostApi->info.deviceCount;
}
if (lstrcmpW(paWasapi->devInfo[i].szDeviceID, paWasapi->defaultRenderer) == 0)
{// we found the default output!
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
}
}

@@ -1623,25 +1614,21 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd

// "Friendly" Name
{
char *deviceName;
PROPVARIANT value;
PropVariantInit(&value);
hr = IPropertyStore_GetValue(pProperty, &PKEY_Device_FriendlyName, &value);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
deviceInfo->name = NULL;
deviceName = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1);
if (deviceName == NULL)
if ((deviceInfo->name = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1)) == NULL)
{
result = paInsufficientMemory;
goto error;
}
if (value.pwszVal)
WideCharToMultiByte(CP_UTF8, 0, value.pwszVal, (int)wcslen(value.pwszVal), deviceName, MAX_STR_LEN - 1, 0, 0);
WideCharToMultiByte(CP_UTF8, 0, value.pwszVal, (int)wcslen(value.pwszVal), (char *)deviceInfo->name, MAX_STR_LEN - 1, 0, 0);
else
_snprintf(deviceName, MAX_STR_LEN - 1, "baddev%d", i);
deviceInfo->name = deviceName;
_snprintf((char *)deviceInfo->name, MAX_STR_LEN - 1, "baddev%d", i);
PropVariantClear(&value);
PA_DEBUG(("WASAPI:%d| name[%s]\n", i, deviceInfo->name));
}
@@ -1706,7 +1693,6 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
#endif

// Create temp Audio Client instance to query additional details
IAudioClient *tmpClient = NULL;
hr = ActivateAudioInterface(&paWasapi->devInfo[i], &tmpClient);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
@@ -1735,9 +1721,9 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
{
// Default device
if (i == 0)
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
else
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
hostApi->info.defaultInputDevice = hostApi->info.deviceCount;

// State
paWasapi->devInfo[i].state = DEVICE_STATE_ACTIVE;
@@ -1750,8 +1736,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
paWasapi->devInfo[i].formFactor = UnknownFormFactor;

// Name
deviceInfo->name = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1);
if (deviceInfo->name == NULL)
if ((deviceInfo->name = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1)) == NULL)
{
SAFE_RELEASE(tmpClient);
result = paInsufficientMemory;
@@ -1805,35 +1790,39 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
break;
}

(*hostApi)->deviceInfos[i] = deviceInfo;
++(*hostApi)->info.deviceCount;
hostApi->deviceInfos[i] = deviceInfo;
++hostApi->info.deviceCount;
}
}

(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;

PaUtil_InitializeStreamInterface( &paWasapi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, GetStreamCpuLoad,
PaUtil_DummyRead, PaUtil_DummyWrite,
PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );

PaUtil_InitializeStreamInterface( &paWasapi->blockingStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, PaUtil_DummyGetCpuLoad,
ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
#if defined(PA_WASAPI_MAX_CONST_DEVICE_COUNT) && (PA_WASAPI_MAX_CONST_DEVICE_COUNT > 0)
if (hostApi->info.deviceCount < PA_WASAPI_MAX_CONST_DEVICE_COUNT)
{
for (i = hostApi->info.deviceCount; i < PA_WASAPI_MAX_CONST_DEVICE_COUNT; ++i)
{
PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;

if ((deviceInfo->name = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, 1)) == NULL)
{
result = paInsufficientMemory;
goto error;
}
((char *)deviceInfo->name)[0] = 0;

// findout if platform workaround is required
paWasapi->useWOW64Workaround = UseWOW64Workaround();
hostApi->deviceInfos[i] = deviceInfo;
++hostApi->info.deviceCount;
}
}
#endif
}

#ifndef PA_WINRT
SAFE_RELEASE(pEndPoints);
SAFE_RELEASE(pEnumerator);
#endif

PRINT(("WASAPI: initialized ok\n"));
PRINT(("WASAPI: device list created ok\n"));

return paNoError;

@@ -1843,44 +1832,119 @@ error:

#ifndef PA_WINRT
SAFE_RELEASE(pEndPoints);
SAFE_RELEASE(pEnumerator);
#endif

Terminate((PaUtilHostApiRepresentation *)paWasapi);

// Safety if error was not set so that we do not think initialize was a success
if (result == paNoError) {
if (result == paNoError)
result = paInternalError;
}

return result;
}

// ------------------------------------------------------------------------------------------
static void Terminate( PaUtilHostApiRepresentation *hostApi )
PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{
UINT i;
PaWasapiHostApiRepresentation *paWasapi = (PaWasapiHostApiRepresentation*)hostApi;
if (paWasapi == NULL)
return;
PaError result = paInternalError;
PaWasapiHostApiRepresentation *paWasapi;

// Release IMMDeviceEnumerator
#ifndef PA_WINRT
SAFE_RELEASE(paWasapi->enumerator);
if (!SetupAVRT())
{
PRINT(("WASAPI: No AVRT! (not VISTA?)"));
return paNoError;
}
#endif

paWasapi = (PaWasapiHostApiRepresentation *)PaUtil_AllocateMemory(sizeof(PaWasapiHostApiRepresentation));
if (paWasapi == NULL)
{
result = paInsufficientMemory;
goto error;
}
memset(paWasapi, 0, sizeof(PaWasapiHostApiRepresentation)); /* ensure all fields are zeroed. especially paWasapi->allocations */

result = PaWinUtil_CoInitialize(paWASAPI, &paWasapi->comInitializationResult);
if (result != paNoError)
goto error;

paWasapi->allocations = PaUtil_CreateAllocationGroup();
if (paWasapi->allocations == NULL)
{
result = paInsufficientMemory;
goto error;
}

// Fill basic interface info
*hostApi = &paWasapi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paWASAPI;
(*hostApi)->info.name = "Windows WASAPI";
(*hostApi)->info.deviceCount = 0;
(*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice;
(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;

// Fill the device list
if ((result = CreateDeviceList(paWasapi, hostApiIndex)) != paNoError)
goto error;

// Detect if platform workaround is required
paWasapi->useWOW64Workaround = UseWOW64Workaround();

PaUtil_InitializeStreamInterface( &paWasapi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, GetStreamCpuLoad,
PaUtil_DummyRead, PaUtil_DummyWrite,
PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );

PaUtil_InitializeStreamInterface( &paWasapi->blockingStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, PaUtil_DummyGetCpuLoad,
ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );

PRINT(("WASAPI: initialized ok\n"));

return paNoError;

error:

PRINT(("WASAPI: failed %s error[%d|%s]\n", __FUNCTION__, result, Pa_GetErrorText(result)));

Terminate((PaUtilHostApiRepresentation *)paWasapi);

return result;
}

// ------------------------------------------------------------------------------------------
static void ReleaseWasapiDeviceInfoList( PaWasapiHostApiRepresentation *paWasapi )
{
UINT32 i;

// Release device info bound objects and device info itself
for (i = 0; i < paWasapi->deviceCount; ++i)
{
PaWasapiDeviceInfo *info = &paWasapi->devInfo[i];
#ifndef PA_WINRT
SAFE_RELEASE(info->device);
#else
(void)info;
SAFE_RELEASE(paWasapi->devInfo[i].device);
#endif
}
PaUtil_FreeMemory(paWasapi->devInfo);

if (paWasapi->allocations)
paWasapi->deviceCount = 0;
}

// ------------------------------------------------------------------------------------------
static void Terminate( PaUtilHostApiRepresentation *hostApi )
{
PaWasapiHostApiRepresentation *paWasapi = (PaWasapiHostApiRepresentation*)hostApi;
if (paWasapi == NULL)
return;

ReleaseWasapiDeviceInfoList(paWasapi);

if (paWasapi->allocations != NULL)
{
PaUtil_FreeAllAllocations(paWasapi->allocations);
PaUtil_DestroyAllocationGroup(paWasapi->allocations);
@@ -1911,6 +1975,52 @@ static PaWasapiHostApiRepresentation *_GetHostApi(PaError *_error)
}

// ------------------------------------------------------------------------------------------
static PaError UpdateDeviceList()
{
int i;
PaError ret;
PaWasapiHostApiRepresentation *paWasapi;
PaUtilHostApiRepresentation *hostApi;

// Get API
hostApi = (PaUtilHostApiRepresentation *)(paWasapi = _GetHostApi(&ret));
if (paWasapi == NULL)
return ret;

// Release WASAPI internal device info list
ReleaseWasapiDeviceInfoList(paWasapi);

// Release external device info list
if (hostApi->deviceInfos != NULL)
{
for (i = 0; i < hostApi->info.deviceCount; ++i)
{
PaUtil_GroupFreeMemory(paWasapi->allocations, (void *)hostApi->deviceInfos[i]->name);
}
PaUtil_GroupFreeMemory(paWasapi->allocations, hostApi->deviceInfos[0]);
PaUtil_GroupFreeMemory(paWasapi->allocations, hostApi->deviceInfos);

hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
}

// Fill possibly updated device list
if ((ret = CreateDeviceList(paWasapi, Pa_HostApiTypeIdToHostApiIndex(paWASAPI))) != paNoError)
return ret;

return paNoError;
}

// ------------------------------------------------------------------------------------------
#if defined(PA_WASAPI_MAX_CONST_DEVICE_COUNT) && (PA_WASAPI_MAX_CONST_DEVICE_COUNT > 0)
PaError PaWasapi_UpdateDeviceList()
{
return UpdateDeviceList();
}
#endif

// ------------------------------------------------------------------------------------------
int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice )
{
PaError ret;

Loading…
Cancel
Save