diff options
| author | Silent <zdanio95@gmail.com> | 2019-08-17 13:08:58 +0200 |
|---|---|---|
| committer | Silent <zdanio95@gmail.com> | 2021-01-12 19:25:38 +0100 |
| commit | 11c5150c168f13dca001c9217f7c27cd250fb1b4 (patch) | |
| tree | b0aaca44b41a5e62a2fedb73a4f321d70a0a296b /Source/Core/AudioCommon/WASAPIStream.cpp | |
| parent | c373890505ee3cce3687078d4fe99b8f38ca9d2b (diff) | |
AudioCommon/WASAPI: Factorize device enumeration logic into a function to greatly reduce code duplication
Diffstat (limited to 'Source/Core/AudioCommon/WASAPIStream.cpp')
| -rw-r--r-- | Source/Core/AudioCommon/WASAPIStream.cpp | 83 |
1 files changed, 26 insertions, 57 deletions
diff --git a/Source/Core/AudioCommon/WASAPIStream.cpp b/Source/Core/AudioCommon/WASAPIStream.cpp index 552e60cd55..7664356132 100644 --- a/Source/Core/AudioCommon/WASAPIStream.cpp +++ b/Source/Core/AudioCommon/WASAPIStream.cpp @@ -77,14 +77,13 @@ static bool HandleWinAPI(std::string_view message, HRESULT result) return SUCCEEDED(result); } - -std::vector<std::string> WASAPIStream::GetAvailableDevices() +static void ForEachNamedDevice(const std::function<bool(ComPtr<IMMDevice>, std::string)>& callback) { HRESULT result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); // RPC_E_CHANGED_MODE means that thread has COM already initialized with a different threading // model. We don't necessarily need multithreaded model here, so don't treat this as an error if (result != RPC_E_CHANGED_MODE && !HandleWinAPI("Failed to call CoInitialize", result)) - return {}; + return; wil::unique_couninitialize_call cleanup; if (FAILED(result)) @@ -97,20 +96,17 @@ std::vector<std::string> WASAPIStream::GetAvailableDevices() IID_PPV_ARGS(enumerator.GetAddressOf())); if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result)) - return {}; + return; ComPtr<IMMDeviceCollection> devices; result = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, devices.GetAddressOf()); if (!HandleWinAPI("Failed to get available devices", result)) - return {}; + return; UINT count; devices->GetCount(&count); - std::vector<std::string> device_names; - device_names.reserve(count); - for (u32 i = 0; i < count; i++) { ComPtr<IMMDevice> device; @@ -128,64 +124,37 @@ std::vector<std::string> WASAPIStream::GetAvailableDevices() wil::unique_prop_variant device_name; device_properties->GetValue(PKEY_Device_FriendlyName, device_name.addressof()); - device_names.push_back(TStrToUTF8(device_name.pwszVal)); + if (!callback(std::move(device), TStrToUTF8(device_name.pwszVal))) + break; } - - return device_names; } -ComPtr<IMMDevice> WASAPIStream::GetDeviceByName(std::string_view name) +std::vector<std::string> WASAPIStream::GetAvailableDevices() { - HRESULT result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); - // RPC_E_CHANGED_MODE means that thread has COM already initialized with a different threading - // model. We don't necessarily need multithreaded model here, so don't treat this as an error - if (result != RPC_E_CHANGED_MODE && !HandleWinAPI("Failed to call CoInitialize", result)) - return nullptr; - - wil::unique_couninitialize_call cleanup; - if (FAILED(result)) - cleanup.release(); // CoUninitialize must be matched with each successful CoInitialize call, so - // don't call it if initialize fails - - ComPtr<IMMDeviceEnumerator> enumerator; - - result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(enumerator.GetAddressOf())); - - if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result)) - return nullptr; - - ComPtr<IMMDeviceCollection> devices; - result = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, devices.GetAddressOf()); - - if (!HandleWinAPI("Failed to get available devices", result)) - return nullptr; - - UINT count; - devices->GetCount(&count); - - for (u32 i = 0; i < count; i++) - { - ComPtr<IMMDevice> device; - devices->Item(i, device.GetAddressOf()); - if (!HandleWinAPI("Failed to get device " + std::to_string(i), result)) - continue; - - ComPtr<IPropertyStore> device_properties; + std::vector<std::string> device_names; - result = device->OpenPropertyStore(STGM_READ, device_properties.GetAddressOf()); + ForEachNamedDevice([&device_names](ComPtr<IMMDevice>, std::string n) { + device_names.push_back(std::move(n)); + return true; + }); - if (!HandleWinAPI("Failed to initialize IPropertyStore", result)) - continue; + return device_names; +} - wil::unique_prop_variant device_name; - device_properties->GetValue(PKEY_Device_FriendlyName, device_name.addressof()); +ComPtr<IMMDevice> WASAPIStream::GetDeviceByName(std::string_view name) +{ + ComPtr<IMMDevice> device; - if (TStrToUTF8(device_name.pwszVal) == name) - return device; - } + ForEachNamedDevice([&device, &name](ComPtr<IMMDevice> d, std::string n) { + if (n == name) + { + device = std::move(d); + return false; + } + return true; + }); - return nullptr; + return device; } bool WASAPIStream::Init() |
