PaError PaWasapi_UpdateDeviceList();
-/** Returns current sound format of the device assigned to the opened stream. Format is represented by
+/** Returns current audio format of the device assigned to the opened stream. Format is represented by
PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. Use this function to reconfirm format if
PA's processor is overriden and paWinWasapiRedirectHostProcessor flag is specified.
int PaWasapi_GetDeviceCurrentFormat( PaStream *pStream, void *pFormat, unsigned int nFormatSize, int bOutput );
-/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
- WAVEFORMATEXTENSIBLE structure.
+/** Returns default audio format for device in Shared Mode. Format is represented by
+ PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure and obtained by getting
+ the device property with a PKEY_AudioEngine_DeviceFormat key.
@param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
@param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes.
int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );
+/** Returns mix audio format for device in Shared Mode. Format is represented by
+ PaWinWaveFormat or WAVEFORMATEXTENSIBLE structureand obtained by
+ IAudioClient::GetMixFormat.
+
+ @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
+ @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes.
+ @param nDevice Device index.
+
+ @return Non-negative value indicating the number of bytes copied into format decriptor
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+*/
+int PaWasapi_GetDeviceMixFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );
+
+
/** Returns device role (PaWasapiDeviceRole enum).
@param nDevice Device index.
// Default format (setup through Control Panel by user)
WAVEFORMATEXTENSIBLE DefaultFormat;
+ // Mix format (internal format used by WASAPI audio engine)
+ WAVEFORMATEXTENSIBLE MixFormat;
+
// Fields filled from IMMEndpoint'sGetDataFlow
EDataFlow flow;
#ifndef PA_WINRT
IMMDeviceCollection* pEndPoints = NULL;
IMMDeviceEnumerator *pEnumerator = NULL;
-#else
- WAVEFORMATEX *mixFormat;
#endif
IAudioClient *tmpClient;
hr = S_OK;
}
+ // Get mix format
+ {
+ WAVEFORMATEX *mixFormat;
+
+ hr = IAudioClient_GetMixFormat(tmpClient, &mixFormat);
+ if (SUCCEEDED(hr))
+ {
+ memcpy(&paWasapi->devInfo[i].MixFormat, mixFormat, min(sizeof(paWasapi->devInfo[i].MixFormat), (sizeof(*mixFormat) + mixFormat->cbSize)));
+ CoTaskMemFree(mixFormat);
+ }
+ }
+
+ // Register WINRT device
#ifdef PA_WINRT
- // Get mix format which will treat as default device format
- hr = IAudioClient_GetMixFormat(tmpClient, &mixFormat);
if (SUCCEEDED(hr))
{
// Default device
// State
paWasapi->devInfo[i].state = DEVICE_STATE_ACTIVE;
- // Default format
- memcpy(&paWasapi->devInfo[i].DefaultFormat, mixFormat, min(sizeof(paWasapi->devInfo[i].DefaultFormat), (sizeof(*mixFormat) + mixFormat->cbSize)));
- CoTaskMemFree(mixFormat);
+ // Default format is always a mix format
+ paWasapi->devInfo[i].DefaultFormat = paWasapi->devInfo[i].MixFormat;
// Form-factor
paWasapi->devInfo[i].formFactor = UnknownFormFactor;
// we can now fill in portaudio device data
deviceInfo->maxInputChannels = 0;
deviceInfo->maxOutputChannels = 0;
- deviceInfo->defaultSampleRate = paWasapi->devInfo[i].DefaultFormat.Format.nSamplesPerSec;
+ deviceInfo->defaultSampleRate = paWasapi->devInfo[i].MixFormat.Format.nSamplesPerSec;
switch (paWasapi->devInfo[i].flow)
{
case eRender: {
- deviceInfo->maxOutputChannels = paWasapi->devInfo[i].DefaultFormat.Format.nChannels;
+ deviceInfo->maxOutputChannels = paWasapi->devInfo[i].MixFormat.Format.nChannels;
deviceInfo->defaultHighOutputLatency = nano100ToSeconds(paWasapi->devInfo[i].DefaultDevicePeriod);
deviceInfo->defaultLowOutputLatency = nano100ToSeconds(paWasapi->devInfo[i].MinimumDevicePeriod);
PA_DEBUG(("WASAPI:%d| def.SR[%d] max.CH[%d] latency{hi[%f] lo[%f]}\n", i, (UINT32)deviceInfo->defaultSampleRate,
deviceInfo->maxOutputChannels, (float)deviceInfo->defaultHighOutputLatency, (float)deviceInfo->defaultLowOutputLatency));
break;}
case eCapture: {
- deviceInfo->maxInputChannels = paWasapi->devInfo[i].DefaultFormat.Format.nChannels;
+ deviceInfo->maxInputChannels = paWasapi->devInfo[i].MixFormat.Format.nChannels;
deviceInfo->defaultHighInputLatency = nano100ToSeconds(paWasapi->devInfo[i].DefaultDevicePeriod);
deviceInfo->defaultLowInputLatency = nano100ToSeconds(paWasapi->devInfo[i].MinimumDevicePeriod);
PA_DEBUG(("WASAPI:%d| def.SR[%d] max.CH[%d] latency{hi[%f] lo[%f]}\n", i, (UINT32)deviceInfo->defaultSampleRate,
return size;
}
+// ------------------------------------------------------------------------------------------
+int PaWasapi_GetDeviceMixFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice )
+{
+ PaError ret;
+ PaWasapiHostApiRepresentation *paWasapi;
+ UINT32 size;
+ PaDeviceIndex index;
+
+ if (pFormat == NULL)
+ return paBadBufferPtr;
+ if (nFormatSize <= 0)
+ return paBufferTooSmall;
+
+ // Get API
+ paWasapi = _GetHostApi(&ret);
+ if (paWasapi == NULL)
+ return ret;
+
+ // Get device index
+ ret = PaUtil_DeviceIndexToHostApiDeviceIndex(&index, nDevice, &paWasapi->inheritedHostApiRep);
+ if (ret != paNoError)
+ return ret;
+
+ // Validate index
+ if ((UINT32)index >= paWasapi->deviceCount)
+ return paInvalidDevice;
+
+ size = min(nFormatSize, (UINT32)sizeof(paWasapi->devInfo[ index ].MixFormat));
+ memcpy(pFormat, &paWasapi->devInfo[ index ].MixFormat, size);
+
+ return size;
+}
+
// ------------------------------------------------------------------------------------------
int PaWasapi_GetDeviceRole( PaDeviceIndex nDevice )
{