Мне нужна помощь в связывании устройств отображения с соответствующими аудиоустройствами, и, в конце концов, я хочу иметь путь к аудиоустройству с использованием WinApi и C ++.
Проблема в том, что нет прямого способа выполнить sh this.
Что у меня сейчас: из MSDN я могу перечислить аудио конечные устройства, и некоторые из них являются графическими c аудио карты:
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
void PrintEndpointNames()
{
HRESULT hr = S_OK;
IMMDeviceEnumerator* pEnumerator = NULL;
IMMDeviceCollection* pCollection = NULL;
IMMDevice* pEndpoint = NULL;
IPropertyStore* pProps = NULL;
LPWSTR pwszID = NULL;
hr = CoInitialize((LPVOID)NULL);
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
EXIT_ON_ERROR(hr)
hr = pEnumerator->EnumAudioEndpoints(
eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED | DEVICE_STATE_UNPLUGGED,
&pCollection);
EXIT_ON_ERROR(hr)
UINT count;
hr = pCollection->GetCount(&count);
EXIT_ON_ERROR(hr)
if (count == 0)
{
printf("No endpoints found.\n");
}
// Each loop prints the name of an endpoint device.
for (ULONG i = 0; i < count; i++)
{
// Get pointer to endpoint number i.
hr = pCollection->Item(i, &pEndpoint);
EXIT_ON_ERROR(hr)
// Get the endpoint ID string.
hr = pEndpoint->GetId(&pwszID);
EXIT_ON_ERROR(hr)
hr = pEndpoint->OpenPropertyStore(
STGM_READ, &pProps);
EXIT_ON_ERROR(hr)
PROPVARIANT varName;
// Initialize container for property value.
PropVariantInit(&varName);
// Get the endpoint's friendly-name property.
hr = pProps->GetValue(
PKEY_Device_FriendlyName, &varName);
EXIT_ON_ERROR(hr)
// Print endpoint friendly name and endpoint ID.
printf("Endpoint %d: \"%S\" (%S)\n",
i, varName.pwszVal, pwszID);
CoTaskMemFree(pwszID);
pwszID = NULL;
PropVariantClear(&varName);
SAFE_RELEASE(pProps)
SAFE_RELEASE(pEndpoint)
}
SAFE_RELEASE(pEnumerator)
SAFE_RELEASE(pCollection)
return;
CoUninitialize();
Exit:
printf("Error!\n");
CoTaskMemFree(pwszID);
SAFE_RELEASE(pEnumerator)
SAFE_RELEASE(pCollection)
SAFE_RELEASE(pEndpoint)
SAFE_RELEASE(pProps)
}
Но как определить, какие из них являются аудиоустройствами графической c карты, я не знаю.
Я также нашел структуру , которая определяет информацию о цифровом аудиоустройстве, связанном с дисплеем
и я попытался получить от него некоторую информацию, запустив этот код:
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
HRESULT GetJackInfo(IMMDevice* pDevice)
{
HRESULT hr = S_OK;
IDeviceTopology* pDeviceTopology = NULL;
IConnector* pConnFrom = NULL;
IConnector* pConnTo = NULL;
IPart* pPart = NULL;
IKsJackSinkInformation* pJackInf = NULL;
KSJACK_SINK_INFORMATION pJackSinkInformation;
if (NULL == pDevice )
{
return E_POINTER;
}
// Get the endpoint device's IDeviceTopology interface.
hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL,
NULL, (void**)&pDeviceTopology);
EXIT_ON_ERROR(hr)
// The device topology for an endpoint device always
// contains just one connector (connector number 0).
hr = pDeviceTopology->GetConnector(0, &pConnFrom);
EXIT_ON_ERROR(hr)
// Step across the connection to the jack on the adapter.
hr = pConnFrom->GetConnectedTo(&pConnTo);
if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
{
// The adapter device is not currently active.
hr = E_NOINTERFACE;
}
EXIT_ON_ERROR(hr)
// Get the connector's IPart interface.
hr = pConnTo->QueryInterface(__uuidof(IPart), (void**)&pPart);
EXIT_ON_ERROR(hr)
hr = pPart->Activate(CLSCTX_ALL,
__uuidof(IKsJackSinkInformation), (void**)&pJackInf);
EXIT_ON_ERROR(hr)
hr = pJackInf->GetJackSinkInformation(&pJackSinkInformation);
Exit:
SAFE_RELEASE(pDeviceTopology)
SAFE_RELEASE(pConnFrom)
SAFE_RELEASE(pConnTo)
SAFE_RELEASE(pPart)
return hr;
}
IMMDevice* pDevice
я получил от выполнения предыдущего кода, и единственное, что делает этот код, это pPart->Activate
, терпит неудачу, если устройство не является аудиоустройством графической c карты, а когда нет, pJackInf->GetJackSinkInformation
устанавливает странные идентификаторы в структуре KSJACK_SINK_INFORMATION
, например: PortId = {LowPart=3206951034 HighPart=-1360285969 }
когда CCD api возвращает мне adapterId = {LowPart=56473 HighPart=0 }
для всех дисплеев. И я не могу найти способ обнаружить аудиоустройство дисплея.
Буду очень благодарен за любую помощь.