summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon/CubebUtils.cpp
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2024-05-09 14:51:30 +0400
committerSepalani <sepalani@hotmail.fr>2025-05-07 20:33:22 +0400
commit1ac40f25a2ced19f8a7729f1974cefacf207c845 (patch)
treeea3e02a675c7e940164494b7f17fe1d48d4558ba /Source/Core/AudioCommon/CubebUtils.cpp
parent451e36defcb59f3f0ce72f67a1b49c59f7ab13c3 (diff)
IOS/USB: Emulate Wii Speak using cubeb
Based on @noahpistilli (Sketch) PR: https://github.com/dolphin-emu/dolphin/pull/12567 Fixed the Windows support and the heisenbug caused by uninitialized members. Config system integration finalized.
Diffstat (limited to 'Source/Core/AudioCommon/CubebUtils.cpp')
-rw-r--r--Source/Core/AudioCommon/CubebUtils.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/Source/Core/AudioCommon/CubebUtils.cpp b/Source/Core/AudioCommon/CubebUtils.cpp
index 6ad94f612c..e63f75c26e 100644
--- a/Source/Core/AudioCommon/CubebUtils.cpp
+++ b/Source/Core/AudioCommon/CubebUtils.cpp
@@ -72,3 +72,101 @@ std::shared_ptr<cubeb> CubebUtils::GetContext()
weak = shared = {ctx, DestroyContext};
return shared;
}
+
+std::vector<std::pair<std::string, std::string>> CubebUtils::ListInputDevices()
+{
+ std::vector<std::pair<std::string, std::string>> devices;
+
+ cubeb_device_collection collection;
+ auto cubeb_ctx = CubebUtils::GetContext();
+ const int r = cubeb_enumerate_devices(cubeb_ctx.get(), CUBEB_DEVICE_TYPE_INPUT, &collection);
+
+ if (r != CUBEB_OK)
+ {
+ ERROR_LOG_FMT(AUDIO, "Error listing cubeb input devices");
+ return devices;
+ }
+
+ INFO_LOG_FMT(AUDIO, "Listing cubeb input devices:");
+ for (uint32_t i = 0; i < collection.count; i++)
+ {
+ const auto& info = collection.device[i];
+ const auto device_state = info.state;
+ const char* state_name = [device_state] {
+ switch (device_state)
+ {
+ case CUBEB_DEVICE_STATE_DISABLED:
+ return "disabled";
+ case CUBEB_DEVICE_STATE_UNPLUGGED:
+ return "unplugged";
+ case CUBEB_DEVICE_STATE_ENABLED:
+ return "enabled";
+ default:
+ return "unknown?";
+ }
+ }();
+
+ // According to cubeb_device_info definition in cubeb.h:
+ // > "Optional vendor name, may be NULL."
+ // In practice, it seems some other fields might be NULL as well.
+ static constexpr auto fmt_str = [](const char* ptr) constexpr -> const char* {
+ return (ptr == nullptr) ? "(null)" : ptr;
+ };
+
+ INFO_LOG_FMT(AUDIO,
+ "[{}] Device ID: {}\n"
+ "\tName: {}\n"
+ "\tGroup ID: {}\n"
+ "\tVendor: {}\n"
+ "\tState: {}",
+ i, fmt_str(info.device_id), fmt_str(info.friendly_name), fmt_str(info.group_id),
+ fmt_str(info.vendor_name), state_name);
+
+ if (info.device_id == nullptr)
+ continue; // Shouldn't happen
+
+ if (info.state == CUBEB_DEVICE_STATE_ENABLED)
+ {
+ devices.emplace_back(info.device_id, fmt_str(info.friendly_name));
+ }
+ }
+
+ cubeb_device_collection_destroy(cubeb_ctx.get(), &collection);
+
+ return devices;
+}
+
+cubeb_devid CubebUtils::GetInputDeviceById(std::string_view id)
+{
+ if (id.empty())
+ return nullptr;
+
+ cubeb_device_collection collection;
+ auto cubeb_ctx = CubebUtils::GetContext();
+ const int r = cubeb_enumerate_devices(cubeb_ctx.get(), CUBEB_DEVICE_TYPE_INPUT, &collection);
+
+ if (r != CUBEB_OK)
+ {
+ ERROR_LOG_FMT(AUDIO, "Error enumerating cubeb input devices");
+ return nullptr;
+ }
+
+ cubeb_devid device_id = nullptr;
+ for (uint32_t i = 0; i < collection.count; i++)
+ {
+ const auto& info = collection.device[i];
+ if (id.compare(info.device_id) == 0)
+ {
+ device_id = info.devid;
+ break;
+ }
+ }
+ if (device_id == nullptr)
+ {
+ WARN_LOG_FMT(AUDIO, "Failed to find selected input device, defaulting to system preferences");
+ }
+
+ cubeb_device_collection_destroy(cubeb_ctx.get(), &collection);
+
+ return device_id;
+}