#define WIN32_LEAN_AND_MEAN #include #include #include const IID DEVINTERFACE_AUDIO_RENDER = { 0xe6327cad, 0xdcec, 0x4949, {0xae, 0x8a, 0x99, 0x1e, 0x97, 0x6a, 0x79, 0xd2 } }; const DWORD MAX_FRIENDLY_NAME = 2048; static wchar_t friendlyName[MAX_FRIENDLY_NAME]; LPCWSTR win_device_id_to_friendly_name(LPCWSTR deviceId) { LPCWSTR result = NULL; HDEVINFO devInfoSet = SetupDiGetClassDevs(&DEVINTERFACE_AUDIO_RENDER, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (devInfoSet == INVALID_HANDLE_VALUE) { return NULL; } SP_DEVINFO_DATA devInfo; devInfo.cbSize = sizeof(SP_DEVINFO_DATA); SP_DEVICE_INTERFACE_DATA devInterface; devInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); DWORD deviceIndex = 0; for (;;) { if (!SetupDiEnumDeviceInterfaces(devInfoSet, 0, &DEVINTERFACE_AUDIO_RENDER, deviceIndex, &devInterface)) { break; } deviceIndex++; DWORD reqSize = 0; SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, NULL, 0, &reqSize, NULL); SP_DEVICE_INTERFACE_DETAIL_DATA *interfaceDetail = reinterpret_cast(new uint8_t[reqSize]); if (!interfaceDetail) { break; } interfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, interfaceDetail, reqSize, NULL, &devInfo)) { delete[] interfaceDetail; continue; } if (_wcsicmp(deviceId, interfaceDetail->DevicePath) != 0) { delete[] interfaceDetail; continue; } delete[] interfaceDetail; if (!SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfo, SPDRP_FRIENDLYNAME, NULL, (LPBYTE) friendlyName, MAX_FRIENDLY_NAME * sizeof(wchar_t), NULL)) { continue; } result = friendlyName; break; } if (devInfoSet) { SetupDiDestroyDeviceInfoList(devInfoSet); } return result; } uint32_t device_index_from_device_id(FAudio *faudio, LPCWSTR deviceId) { LPCWSTR friendlyName = win_device_id_to_friendly_name(deviceId); uint32_t dev_count; FAudio_GetDeviceCount(faudio, &dev_count); for (uint32_t i = 0; i < dev_count; ++i) { FAudioDeviceDetails dev_details; FAudio_GetDeviceDetails(faudio, i, &dev_details); if (_wcsicmp((LPCWSTR) dev_details.DisplayName, friendlyName) == 0) { return i; } } return 0; }