-
Notifications
You must be signed in to change notification settings - Fork 0
/
WindowsMicScanner.cpp
157 lines (130 loc) · 4.68 KB
/
WindowsMicScanner.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "WindowsMicScanner.h"
#include <iostream>
#include <string>
#include <list>
#include <MMDeviceAPI.h>
#include <AudioClient.h>
#include <AudioPolicy.h>
#include <avrt.h>
#include <atlstr.h>
#include <functiondiscoverykeys.h>
#include "StringUtils.h"
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
void WindowsMicScanner::getDeviceByMicrofoneName(std::wstring micName) {
HRESULT hr = S_OK;
IMMDeviceEnumerator* pEnumerator = NULL;
BOOL result = FALSE;
hr = CoInitialize(0);
// Create the device enumerator.
hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator);
hr = pEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &dCol);
UINT dCount;
hr = dCol->GetCount(&dCount);
std::list<std::wstring> micsFound;
for (UINT i = 0; i < dCount; i++)
{
IMMDevice* pCaptureDevice = NULL;
hr = dCol->Item(i, &pCaptureDevice);
IPropertyStore* pProps = NULL;
hr = pCaptureDevice->OpenPropertyStore(
STGM_READ, &pProps);
PROPVARIANT varName;
// Initialize container for property value.
PropVariantInit(&varName);
// Get the endpoint's friendly-name property.
hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
std::wstring nameStr(varName.pwszVal);
micsFound.push_back(nameStr.c_str());
// #2 Determine whether it is the microphone device you are focusing on
std::size_t found = nameStr.find(micName);
if (found != std::string::npos)
{
// Print endpoint friendly name.
// printf("Endpoint friendly name: \"%S\"\n", varName.pwszVal);
// Get the session manager.
hr = pCaptureDevice->Activate(
__uuidof(IAudioSessionManager2),
CLSCTX_ALL,
NULL,
(void**)&pSessionManager
);
break;
}
}
// Get session state
if (!pSessionManager)
{
std::string micsFoundStr = micsFound.empty() ? "no active mics" : StringUtils::join(micsFound, ", ");
throw std::invalid_argument("Not found mic matching filter \"" + StringUtils::ws2s(micName) + "\". Microphones: " + micsFoundStr);
}
else {
micsFound.clear();
}
// Clean up.
SAFE_RELEASE(pEnumerator);
}
std::list<std::wstring> WindowsMicScanner::getActiveDevices() {
HRESULT hr = S_OK;
int cbSessionCount = 0;
LPWSTR pswSession = NULL;
IAudioSessionEnumerator* pSessionList = NULL;
IAudioSessionControl* pSessionControl = NULL;
IAudioSessionControl2* pSessionControl2 = NULL;
// Get the current list of sessions.
hr = pSessionManager->GetSessionEnumerator(&pSessionList);
// Get the session count.
hr = pSessionList->GetCount(&cbSessionCount);
//wprintf_s(L"Session count: %d\n", cbSessionCount);
std::list<std::wstring> appsUsingThisMic;
for (int index = 0; index < cbSessionCount; index++)
{
SAFE_RELEASE(pSessionControl);
// Get the <n>th session.
hr = pSessionList->GetSession(index, &pSessionControl);
hr = pSessionControl->QueryInterface(
__uuidof(IAudioSessionControl2), (void**)&pSessionControl2);
// Exclude system sound session
hr = pSessionControl2->IsSystemSoundsSession();
if (S_OK == hr)
{
//wprintf_s(L" this is a system sound.\n");
continue;
}
// Optional. Determine which application is using Microphone for recording
LPWSTR instId = NULL;
hr = pSessionControl2->GetSessionInstanceIdentifier(&instId);
if (S_OK == hr)
{
//wprintf_s(L"SessionInstanceIdentifier: %s\n", instId);
}
AudioSessionState state;
std::wstring winstId;
hr = pSessionControl->GetState(&state);
switch (state)
{
case AudioSessionStateInactive:
//wprintf_s(L"Session state: Inactive\n", state);
break;
case AudioSessionStateActive:
// #3 Active state indicates it is recording, otherwise is not recording.
//wprintf_s(L"Session state: Active\n", state);
winstId = instId;
appsUsingThisMic.push_back(winstId.substr(56));
break;
case AudioSessionStateExpired:
//wprintf_s(L"Session state: Expired\n", state);
break;
}
}
// Clean up.
SAFE_RELEASE(pSessionControl);
SAFE_RELEASE(pSessionList);
SAFE_RELEASE(pSessionControl2);
return appsUsingThisMic;
}