File: win_device.cpp

package info (click to toggle)
faudio 21.02-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,576 kB
  • sloc: ansic: 25,642; cpp: 10,815; cs: 1,899; sh: 82; makefile: 21
file content (100 lines) | stat: -rw-r--r-- 2,330 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <setupapi.h>

#include <FAudio.h>

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<SP_DEVICE_INTERFACE_DETAIL_DATA *>(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;
}