live update

This commit is contained in:
2022-07-15 02:34:34 +02:00
parent ff996e8e55
commit b621d1266c
9 changed files with 303 additions and 55 deletions

View File

@@ -38,18 +38,14 @@ void setDefaultAudioDevice(ApplicationData* appData, const wchar_t* deviceId, ER
}
}
void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType)
void loadAudioDevices(ApplicationData* appData, std::vector<AudioDevice>& deviceList, EDataFlow deviceType)
{
deviceList.clear();
HRESULT err;
IMMDeviceEnumerator* deviceEnumerator = NULL;
IMMDeviceCollection* deviceCollection = NULL;
err = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
if (isError(err, "Failed to set up audio device enumerator: ")) return;
err = deviceEnumerator->EnumAudioEndpoints(deviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &deviceCollection);
err = appData->deviceEnumerator->EnumAudioEndpoints(deviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &deviceCollection);
if (isError(err, "Failed to enumerate audio devices: ")) return;
UINT deviceCount;
@@ -58,7 +54,7 @@ void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType
IMMDevice* defaultConsoleDevice = NULL;
LPWSTR defaultConsoleId = nullptr;
err = deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eConsole, &defaultConsoleDevice);
err = appData->deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eConsole, &defaultConsoleDevice);
if (!FAILED(err))
{
defaultConsoleDevice->GetId(&defaultConsoleId);
@@ -66,7 +62,7 @@ void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType
IMMDevice* defaultMediaOutput = NULL;
LPWSTR defaultMediaId = nullptr;
err = deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eMultimedia, &defaultMediaOutput);
err = appData->deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eMultimedia, &defaultMediaOutput);
if (!FAILED(err))
{
defaultMediaOutput->GetId(&defaultMediaId);
@@ -74,7 +70,7 @@ void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType
IMMDevice* defaultCommunicationOutput = NULL;
LPWSTR defaultCommunicationId = nullptr;
err = deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eCommunications, &defaultCommunicationOutput);
err = appData->deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eCommunications, &defaultCommunicationOutput);
if (!FAILED(err))
{
defaultCommunicationOutput->GetId(&defaultCommunicationId);
@@ -82,48 +78,54 @@ void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType
for (UINT i = 0; i < deviceCount; i += 1)
{
IMMDevice* device;
err = deviceCollection->Item(i, &device);
isError(err, std::stringstream("Failed to get device ") << i << ": ");
AudioDevice deviceData{};
err = deviceCollection->Item(i, &deviceData.device);
if (isError(err, std::stringstream("Failed to get device ") << i << ": "))
{
continue;
}
LPWSTR deviceId;
err = device->GetId(&deviceId);
err = deviceData.device->GetId(&deviceId);
isError(err, std::stringstream("Failed to get device id ") << i << ": ");
deviceData.id = std::wstring(deviceId);
IPropertyStore* propertyStore;
err = device->OpenPropertyStore(STGM_READ, &propertyStore);
err = deviceData.device->OpenPropertyStore(STGM_READ, &propertyStore);
isError(err, std::stringstream("Failed to open device ") << i << "prop store: ");
PROPVARIANT deviceNameProp;
const wchar_t* deviceName;
err = getDevicePropertyString(propertyStore, PKEY_Device_FriendlyName, &deviceNameProp, deviceName);
isError(err, std::stringstream("Failed to read name of device ") << i << ": ");
deviceData.name = utf8Encode(deviceName);
DWORD deviceState;
err = device->GetState(&deviceState);
err = deviceData.device->GetState(&deviceData.state);
isError(err, std::stringstream("Failed to reat state of device ") << i << ": ");
IAudioEndpointVolume* volumeInterface;
err = device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&volumeInterface);
err = deviceData.device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&deviceData.volumeInterface);
isError(err, "Failed to get audio endpoint volume interface: ");
IAudioMeterInformation* meterInterface;
err = device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&meterInterface);
err = deviceData.device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&deviceData.meterInterface);
isError(err, "Failed to get audio meter interface: ");
deviceList.push_back({
device,
volumeInterface,
meterInterface,
std::wstring(deviceId),
utf8Encode(deviceName),
deviceState,
utf8Encode(defaultConsoleId) == utf8Encode(deviceId),
utf8Encode(defaultMediaId) == utf8Encode(deviceId),
utf8Encode(defaultCommunicationId) == utf8Encode(deviceId),
});
if (defaultConsoleId)
{
deviceData.isDefaultConsole = wcscmp(defaultConsoleId, deviceId) == 0;
}
if (defaultMediaId)
{
deviceData.isDefaultMedia = wcscmp(defaultMediaId, deviceId) == 0;
}
if (defaultCommunicationId)
{
deviceData.isDefaultCommunication = wcscmp(defaultCommunicationId, deviceId) == 0;
}
deviceList.push_back(std::move(deviceData));
// Free stuff
if (propertyStore)
{
propertyStore->Release();
@@ -131,22 +133,18 @@ void loadAudioDevices(std::vector<AudioDevice>& deviceList, EDataFlow deviceType
CoTaskMemFree(deviceId);
}
if (deviceEnumerator)
{
deviceEnumerator->Release();
}
std::sort(deviceList.begin(), deviceList.end(), [](AudioDevice& a, AudioDevice& b) { return a.state < b.state; });
if (deviceCollection)
{
deviceCollection->Release();
}
std::sort(deviceList.begin(), deviceList.end(), [](AudioDevice& a, AudioDevice& b) { return a.state < b.state; });
}
void reloadDeviceLists(ApplicationData* appData)
{
loadAudioDevices(appData->playbackDevices, EDataFlow::eRender);
loadAudioDevices(appData->recordingDevices, EDataFlow::eCapture);
loadAudioDevices(appData, appData->playbackDevices, EDataFlow::eRender);
loadAudioDevices(appData, appData->recordingDevices, EDataFlow::eCapture);
}
float getVolume(IAudioEndpointVolume* volumeInterface)
@@ -169,4 +167,4 @@ float getMeterValue(IAudioMeterInformation* meterInterface)
}
return volume;
}
}