summaryrefslogtreecommitdiff
path: root/audio/tests/wavetest/PropertyHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/tests/wavetest/PropertyHelper.cpp')
-rw-r--r--audio/tests/wavetest/PropertyHelper.cpp1095
1 files changed, 0 insertions, 1095 deletions
diff --git a/audio/tests/wavetest/PropertyHelper.cpp b/audio/tests/wavetest/PropertyHelper.cpp
deleted file mode 100644
index fb60d3cc..00000000
--- a/audio/tests/wavetest/PropertyHelper.cpp
+++ /dev/null
@@ -1,1095 +0,0 @@
-// ------------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft. All rights reserved.
-//
-// Module Name:
-//
-// EndpointPropertyHelpers.cpp
-//
-// Abstract:
-//
-// Implementation for common helpers of endpoint property
-//
-// -------------------------------------------------------------------------------
-#include "PreComp.h"
-#include <AVEndpointKeys.h>
-#include <Functiondiscoverykeys_devpkey.h>
-#include "PropertyHelper.h"
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetConnectorId
-//
-// Retrieve the connector id from the property store and checks if the connector exists
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetConnectorId
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- bool* hasConnector,
- UINT* pConnectorId
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetEndpointFriendlyName
-//
-// Retrieve the endpoint friendly name from the property store
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetEndpointFriendlyName
-(
- IMMDevice* pDevice,
- LPWSTR* ppwszEndpointName
-)
-{
- HRESULT hr = S_OK;
- wil::com_ptr_nothrow<IPropertyStore> spPropertyStore;
- wil::unique_prop_variant var;
- wil::unique_cotaskmem_string pwszName;
-
- *ppwszEndpointName = NULL;
-
- // Retrieve the endpoint friendly name from the propertey store
- if (!VERIFY_SUCCEEDED(hr = pDevice->OpenPropertyStore(STGM_READ, &spPropertyStore))) {
- return hr;
- }
- if (!VERIFY_SUCCEEDED(hr = spPropertyStore->GetValue(PKEY_Device_FriendlyName, &var))) {
- return hr;
- }
- if (!VERIFY_IS_TRUE(var.vt == VT_LPWSTR)) {
- hr = E_FAIL;
- return hr;
- }
-
- pwszName = wil::make_cotaskmem_string_nothrow(var.pwszVal);
- if (!VERIFY_IS_TRUE(pwszName.get() && wcslen(pwszName.get()) != 0)) {
- hr = E_FAIL;
- return hr;
- }
-
- *ppwszEndpointName = pwszName.release();
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetAudioFilterAsDevice
-//
-// Get the audio filter from MMDevice. This method is called to activate IKsControl, IKsFormatSupport or IKsGetProposedFormat.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetAudioFilterAsDevice
-(
- IMMDevice* pDevice,
- IMMDevice** ppAudioFilterAsDevice
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetCachedProcessingModes
-//
-// Read the processing mode characteristics from the property store and get all processing modes. This method applies to host and keyword detector pins only.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetCachedProcessingModes
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- ULONG *pCount,
- AUDIO_SIGNALPROCESSINGMODE **ppModes
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetProcessingModes
-//
-// Query for connector's processing modes property
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetProcessingModes
-(
- IMMDevice* pDevice,
- UINT pinId,
- ULONG *pCount,
- AUDIO_SIGNALPROCESSINGMODE **ppModes
-)
-{
- HRESULT hr = S_OK;
- wil::com_ptr_nothrow<IMMDevice> spAudioFilter;
- wil::com_ptr_nothrow<IKsControl> spKsControl;
- KSP_PIN pinProp;
- ULONG cbNeeded = 0;
- ULONG cbProperty;
- PKSMULTIPLE_ITEM pProperty = NULL;
- ULONG cbReturned = 0;
- AUDIO_SIGNALPROCESSINGMODE* pModes = NULL;
- CComHeapPtr<AUDIO_SIGNALPROCESSINGMODE> spModes;
-
- *pCount = 0;
- *ppModes = NULL;
-
- // Get the audio filter
- if (!VERIFY_SUCCEEDED(hr = GetAudioFilterAsDevice(pDevice, &spAudioFilter))) {
- return hr;
- }
-
- // Activate IKsControl
- if (!VERIFY_SUCCEEDED(hr = spAudioFilter->Activate(__uuidof(IKsControl), CLSCTX_ALL, NULL, (VOID**)&spKsControl))) {
- return hr;
- }
-
- // Read the audio signal processing mode property
- pinProp.Property.Set = KSPROPSETID_AudioSignalProcessing;
- pinProp.Property.Id = KSPROPERTY_AUDIOSIGNALPROCESSING_MODES;
- pinProp.Property.Flags = KSPROPERTY_TYPE_GET;
- pinProp.PinId = pinId & PARTID_MASK;
- pinProp.Reserved = 0;
-
- // Determined the needed size
- if (!VERIFY_SUCCEEDED(hr = spKsControl->KsProperty(&pinProp.Property, sizeof(KSP_PIN), NULL, 0, &cbNeeded))) {
- return hr;
- }
- if (!VERIFY_IS_TRUE(cbNeeded > 0) || !VERIFY_IS_TRUE((cbNeeded - sizeof(KSMULTIPLE_ITEM)) % sizeof(GUID) == 0)) {
- hr = E_NOTFOUND;
- return hr;
- }
-
- cbProperty = cbNeeded;
- pProperty = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(cbNeeded);
-
- if (!VERIFY_IS_NOT_NULL(pProperty)) {
- hr = E_OUTOFMEMORY;
- cbProperty = 0;
- return hr;
- }
-
- // Query the processing mode property
- if (!VERIFY_SUCCEEDED(hr = spKsControl->KsProperty(&pinProp.Property, sizeof(KSP_PIN), pProperty, cbNeeded, &cbReturned))) {
- goto Exit;
- }
-
- if (!VERIFY_IS_NOT_NULL(pProperty)) {
- hr = E_NOTFOUND;
- goto Exit;
- }
-
- if (!VERIFY_IS_TRUE(cbProperty >= (sizeof(KSMULTIPLE_ITEM) + pProperty->Count * sizeof(GUID)))) {
- hr = E_NOTFOUND;
- goto Exit;
- }
-
- pModes = reinterpret_cast<GUID*>(pProperty + 1);
-
- if (!VERIFY_IS_TRUE(spModes.Allocate(pProperty->Count)))
- {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
-
- memcpy(spModes, pModes, sizeof(AUDIO_SIGNALPROCESSINGMODE)*(pProperty->Count));
-
- *pCount = pProperty->Count;
- *ppModes = spModes.Detach();
-
-Exit:
- if (pProperty != NULL) {
- CoTaskMemFree(pProperty);
- }
- cbProperty = 0;
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetCachedSupportedFormatRecords
-//
-// Read the processing mode characteristics from the property store and get all supported formats for processing mode. This method applies to host and keyword detector pins only.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetCachedSupportedFormatRecords
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- AUDIO_SIGNALPROCESSINGMODE mode,
- ULONG *pCount,
- FORMAT_RECORD **ppFormatRecords
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetSupportedFormatRecords
-//
-// For pins do not have cached supported formats information, such as offload pin, we provide our predefined format list and check whether each is supported by the pin.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetSupportedFormatRecords
-(
- IMMDevice* pDevice,
- UINT pinId,
- EndpointConnectorType eConnectorType,
- AUDIO_SIGNALPROCESSINGMODE mode,
- STACKWISE_DATAFLOW dataFlow,
- ULONG *pCount,
- FORMAT_RECORD **ppFormatRecords
-)
-{
- HRESULT hr = S_OK;
- FORMAT_RECORD *pFormatRecords;
- UINT cFormatRecords = 0;
- CComHeapPtr<FORMAT_RECORD> spFormatRecords;
- BOOL isSupported = false;
- WAVEFORMATEX *pWfx;
- UINT32 u32DefaultPeriodicityInFrames = 0;
- UINT32 u32FundamentalPeriodicityInFrames = 0;
- UINT32 u32MinPeriodicityInFrames = 0;
- UINT32 u32MaxPeriodicityInFrames = 0;
- UINT32 u32MaxPeriodicityInFramesExtended = 0;
-
- // Init return
- *pCount = 0;
- *ppFormatRecords = NULL;
-
- pFormatRecords = new FORMAT_RECORD[COUNT_FORMATS];
- if (!VERIFY_IS_NOT_NULL(pFormatRecords)) {
- hr = E_OUTOFMEMORY;
- return hr;
- }
- memset(pFormatRecords, 0, sizeof(FORMAT_RECORD)*COUNT_FORMATS);
-
- for (ULONG i = 0; i < COUNT_FORMATS; i++) {
- pWfx = (WAVEFORMATEX*)&ListofFormats[i];
-
- // Check if format is supported
- if (!VERIFY_SUCCEEDED(hr = IsFormatSupported(pDevice, pinId, pWfx, &isSupported))) {
- return hr;
- }
-
- // If the format is supported, we discover the periodicity characteristics for the format and store them along with the format in our FORMAT_RECORD struct.
- if (isSupported) {
- if (!VERIFY_SUCCEEDED(hr = DiscoverPeriodicityCharacteristicsForFormat(pDevice, eConnectorType, mode, pWfx, dataFlow, &u32DefaultPeriodicityInFrames, &u32FundamentalPeriodicityInFrames, &u32MinPeriodicityInFrames, &u32MaxPeriodicityInFrames, &u32MaxPeriodicityInFramesExtended))) {
- return hr;
- }
-
- pFormatRecords[cFormatRecords].defaultPeriodInFrames = u32DefaultPeriodicityInFrames;
- pFormatRecords[cFormatRecords].fundamentalPeriodInFrames = u32FundamentalPeriodicityInFrames;
- pFormatRecords[cFormatRecords].minPeriodInFrames = u32MinPeriodicityInFrames;
- pFormatRecords[cFormatRecords].maxPeriodInFrames = u32MaxPeriodicityInFrames;
- pFormatRecords[cFormatRecords].maxPeriodInFramesExtended = u32MaxPeriodicityInFramesExtended;
- memcpy(&pFormatRecords[cFormatRecords].wfxEx, &ListofFormats[i], sizeof(WAVEFORMATEX) + ListofFormats[i].Format.cbSize);
- cFormatRecords++;
- }
- }
-
- if (!VERIFY_IS_TRUE(spFormatRecords.Allocate(cFormatRecords))) {
- hr = E_OUTOFMEMORY;
- return hr;
- }
-
- memcpy(spFormatRecords, pFormatRecords, sizeof(FORMAT_RECORD)*cFormatRecords);
- delete[] pFormatRecords;
-
- *pCount = cFormatRecords;
- *ppFormatRecords = spFormatRecords.Detach();
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// IsFormatSupported
-//
-// Wrap up the IKsFormatSupport::IsFormatSupported method.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT IsFormatSupported
-(
- IMMDevice* pDevice,
- UINT pinId,
- WAVEFORMATEX *pWfx,
- BOOL* pbSupported
-)
-{
- HRESULT hr = S_OK;
- wil::com_ptr_nothrow<IMMDevice> spAudioFilter;
- wil::com_ptr_nothrow<IDeviceTopology> spAudioFilterTopology;
- wil::com_ptr_nothrow<IPart> spPart;
- wil::com_ptr_nothrow<IKsFormatSupport> spFormatSupport;
- PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pKsRequestedFormat = NULL;
- PKSDATAFORMAT pKsFormat = NULL;
- KSDATAFORMAT_WAVEFORMATEXTENSIBLE KsWfex = {};
- DWORD cbKsFormat = 0;
-
- // Init return
- *pbSupported = FALSE;
-
- // Get the audio filter
- if (!VERIFY_SUCCEEDED(hr = GetAudioFilterAsDevice(pDevice, &spAudioFilter))) {
- return hr;
- }
-
- // Activate an IDeviceTopology on the filter
- if (!VERIFY_SUCCEEDED(hr = spAudioFilter->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spAudioFilterTopology))) {
- return hr;
- }
-
- // Get the connector
- if (!VERIFY_SUCCEEDED(hr = spAudioFilterTopology->GetPartById(pinId, &spPart))) {
- return hr;
- }
-
- // Activate IKsFormatSupport interface
- if (!VERIFY_SUCCEEDED(hr = spPart->Activate(CLSCTX_ALL, __uuidof(IKsFormatSupport), (void**)&spFormatSupport))) {
- return hr;
- }
-
- // Convert to KSDATAFORMAT_WAVEFORMATEX
- if (!VERIFY_SUCCEEDED(hr = CreateKSFormatFromWFXFormat(pWfx, (KSDATAFORMAT_WAVEFORMATEX**)&pKsRequestedFormat))) {
- return hr;
- }
-
- if (pKsRequestedFormat->DataFormat.FormatSize < sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE))
- {
- memcpy(&KsWfex, pKsRequestedFormat, pKsRequestedFormat->DataFormat.FormatSize);
- pKsFormat = reinterpret_cast<KSDATAFORMAT *>(&KsWfex);
- cbKsFormat = sizeof(KsWfex);
- }
- else
- {
- pKsFormat = reinterpret_cast<KSDATAFORMAT *>(pKsRequestedFormat);
- cbKsFormat = pKsRequestedFormat->DataFormat.FormatSize;
- }
-
- // Expect that pbFormat is really a KSDATAFORMAT
- if (!VERIFY_IS_TRUE(cbKsFormat >= sizeof(KSDATAFORMAT))) {
- hr = E_INVALIDARG;
- return hr;
- }
-
- // validate return pointers (this is an externally callable method)
- if (!VERIFY_IS_TRUE(pKsFormat)) {
- hr = E_POINTER;
- return hr;
- }
-
- if (!VERIFY_SUCCEEDED(hr = spFormatSupport->IsFormatSupported(pKsFormat, cbKsFormat, pbSupported))) {
- return hr;
- }
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// DiscoverPeriodicityCharacteristicsForFormat
-//
-// Discover the periodicity characteristics for given format.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT DiscoverPeriodicityCharacteristicsForFormat
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- AUDIO_SIGNALPROCESSINGMODE mode,
- WAVEFORMATEX *pWfx,
- STACKWISE_DATAFLOW dataFlow,
- UINT32 *pDefaultPeriodicityInFrames,
- UINT32 *pFundamentalPeriodicityInFrames,
- UINT32 *pMinPeriodicityInFrames,
- UINT32 *pMaxPeriodicityInFrames,
- UINT32 *pMaxPeriodicityInFramesExtended
-)
-{
- HRESULT hr = S_OK;
- HNSTIME hnsDefaultPeriod = kSystemDefaultPeriod;
- UINT32 ActualPeriodicityInFrames;
-
- // Verify format is not null
- if (!VERIFY_IS_NOT_NULL(pWfx)) {
- hr = E_INVALIDARG;
- return hr;
- }
-
- *pDefaultPeriodicityInFrames =
- *pFundamentalPeriodicityInFrames =
- *pMinPeriodicityInFrames =
- *pMaxPeriodicityInFrames = HNSTIME_TO_FRAMES_DOUBLE(hnsDefaultPeriod, pWfx->nSamplesPerSec);
-
- // Check to see whether the endpoint supports the default periodicity and return the actual periodicity
- if (!VERIFY_SUCCEEDED(hr = CheckConnectorSupportForPeriodicity(pDevice, eConnectorType, mode, pWfx, dataFlow, hnsDefaultPeriod, &ActualPeriodicityInFrames))) {
- return hr;
- }
-
- // Use what we get as the default, max, min and fundamental periodicity
- *pDefaultPeriodicityInFrames =
- *pFundamentalPeriodicityInFrames =
- *pMinPeriodicityInFrames =
- *pMaxPeriodicityInFrames = ActualPeriodicityInFrames;
-
- // Max periodicity is capped to the default periodicity for all clients except extended periodicity clients
- *pMaxPeriodicityInFramesExtended = *pMaxPeriodicityInFrames;
- if (*pMaxPeriodicityInFrames > *pDefaultPeriodicityInFrames)
- {
- *pMaxPeriodicityInFrames = *pDefaultPeriodicityInFrames;
- }
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// CheckConnectorSupportForPeriodicity
-//
-// Check to see if the connector supports the specified periodicity and return the actual periodicity.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT CheckConnectorSupportForPeriodicity
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- AUDIO_SIGNALPROCESSINGMODE mode,
- WAVEFORMATEX *pWfx,
- STACKWISE_DATAFLOW dataFlow,
- HNSTIME RequestedPeriodicity,
- UINT32 *pActualPeriodicityInFrames
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetCachedDefaultFormat
-//
-// Read the default device format from the property store. Use audio engine device format for all other pin types. For Keyword Detector pin, it has a different default device format.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetCachedDefaultFormat
-(
- IMMDevice* pDevice,
- EndpointConnectorType eConnectorType,
- WAVEFORMATEX** ppDefaultFormat
-)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetProposedFormatForProcessingMode
-//
-// Wrap up the IKsGetProposedFormat::GetProposedFormatForMode method.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetProposedFormatForProcessingMode
-(
- IMMDevice* pDevice,
- UINT pinId,
- AUDIO_SIGNALPROCESSINGMODE mode,
- WAVEFORMATEX **ppProposedFormat
-)
-{
- HRESULT hr = S_OK;
- wil::com_ptr_nothrow<IMMDevice> spAudioFilter;
- wil::com_ptr_nothrow<IDeviceTopology> spAudioFilterTopology;
- wil::com_ptr_nothrow<IPart> spPart;
-
-
-
- PKSDATAFORMAT pKsProposedFormat = NULL;
- WAVEFORMATEXTENSIBLE* pWfxEx = NULL;
-
- // Init return
- *ppProposedFormat = NULL;
-
- if (!VERIFY_SUCCEEDED(hr = GetAudioFilterAsDevice(pDevice, &spAudioFilter))) {
- return hr;
- }
-
- // Activate an IDeviceTopology on the filter
- if (!VERIFY_SUCCEEDED(hr = spAudioFilter->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spAudioFilterTopology))) {
- return hr;
- }
-
- // Get the connector
- if (!VERIFY_SUCCEEDED(hr = spAudioFilterTopology->GetPartById(pinId, &spPart))) {
- return hr;
- }
-
- // Retrieve the proposed format for a specific processing mode and store it in pKsProposedFormat...
-
-
-
-
-
-
-
-
-
-
-
-
- // Allocate memory for ppOffloadDefaultFormat and copy pKsDataDeviceFormat to ppOffloadDefaultFormat
- pWfxEx = (WAVEFORMATEXTENSIBLE *)CoTaskMemAlloc(sizeof(WAVEFORMATEX) + ((PKSDATAFORMAT_WAVEFORMATEX)pKsProposedFormat)->WaveFormatEx.cbSize);
- if (!VERIFY_IS_NOT_NULL(pWfxEx)) {
- CoTaskMemFree(pKsProposedFormat);
- hr = E_OUTOFMEMORY;
- return hr;
- }
- memcpy(pWfxEx, &(((PKSDATAFORMAT_WAVEFORMATEX)pKsProposedFormat)->WaveFormatEx), sizeof(WAVEFORMATEX) + ((PKSDATAFORMAT_WAVEFORMATEX)pKsProposedFormat)->WaveFormatEx.cbSize);
- *ppProposedFormat = (WAVEFORMATEX*)pWfxEx;
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// GetCurrentAvailiablePinInstanceCount
-//
-// Query for the connector's pin instance count property.
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-HRESULT GetAvailiablePinInstanceCount
-(
- IMMDevice* pDevice,
- UINT pinId,
- UINT32* pAvailablePinInstanceCount
-)
-{
- HRESULT hr = S_OK;
- wil::com_ptr_nothrow<IMMDevice> spAudioFilter;
- wil::com_ptr_nothrow<IKsControl> spKsControl;
- KSP_PIN pinProp;
- KSPIN_CINSTANCES pinInstances;
- ULONG cbReturned = 0;
-
- *pAvailablePinInstanceCount = 0;
-
- if (!VERIFY_SUCCEEDED(hr = GetAudioFilterAsDevice(pDevice, &spAudioFilter))) {
- return hr;
- }
-
- if (!VERIFY_SUCCEEDED(hr = spAudioFilter->Activate(__uuidof(IKsControl), CLSCTX_ALL, NULL, (VOID**)&spKsControl))) {
- return hr;
- }
-
- // Read the pin instance count
- pinProp.Property.Set = KSPROPSETID_Pin;
- pinProp.Property.Id = KSPROPERTY_PIN_CINSTANCES;
- pinProp.Property.Flags = KSPROPERTY_TYPE_GET;
- pinProp.PinId = pinId & PARTID_MASK;
- pinProp.Reserved = 0;
-
- if (!VERIFY_SUCCEEDED(hr = spKsControl->KsProperty(&pinProp.Property, sizeof(KSP_PIN), &pinInstances, sizeof(KSPIN_CINSTANCES), &cbReturned))) {
- return hr;
- }
-
- *pAvailablePinInstanceCount = pinInstances.PossibleCount - pinInstances.CurrentCount;
-
- return hr;
-}