rpcsx/rpcs3/Emu/Audio/FAudio/faudio_enumerator.cpp

91 lines
1.9 KiB
C++

#ifndef HAVE_FAUDIO
#error "FAudio support disabled but still being built."
#endif
#include "Emu/Audio/FAudio/faudio_enumerator.h"
#include <array>
#include <algorithm>
#include "Utilities/StrUtil.h"
#include "util/logs.hpp"
LOG_CHANNEL(faudio_dev_enum);
faudio_enumerator::faudio_enumerator() : audio_device_enumerator()
{
FAudio *tmp{};
if (u32 res = FAudioCreate(&tmp, 0, FAUDIO_DEFAULT_PROCESSOR))
{
faudio_dev_enum.error("FAudioCreate() failed(0x%08x)", res);
return;
}
// All succeeded, "commit"
instance = tmp;
}
faudio_enumerator::~faudio_enumerator()
{
if (instance != nullptr)
{
FAudio_StopEngine(instance);
FAudio_Release(instance);
}
}
std::vector<audio_device_enumerator::audio_device> faudio_enumerator::get_output_devices()
{
if (!instance)
{
return {};
}
u32 dev_cnt{};
if (u32 res = FAudio_GetDeviceCount(instance, &dev_cnt))
{
faudio_dev_enum.error("FAudio_GetDeviceCount() failed(0x%08x)", res);
return {};
}
if (dev_cnt == 0)
{
faudio_dev_enum.warning("No devices available");
return {};
}
std::vector<audio_device> device_list{};
for (u32 dev_idx = 0; dev_idx < dev_cnt; dev_idx++)
{
FAudioDeviceDetails dev_info{};
if (u32 res = FAudio_GetDeviceDetails(instance, dev_idx, &dev_info))
{
faudio_dev_enum.error("FAudio_GetDeviceDetails() failed(0x%08x)", res);
continue;
}
audio_device dev =
{
.id = std::to_string(dev_idx),
.name = utf16_to_utf8(std::bit_cast<char16_t*>(&dev_info.DisplayName[0])),
.max_ch = dev_info.OutputFormat.Format.nChannels
};
if (dev.name.empty())
{
dev.name = "Device " + dev.id;
}
faudio_dev_enum.notice("Found device: id=%s, name=%s, max_ch=%d", dev.id, dev.name, dev.max_ch);
device_list.emplace_back(dev);
}
std::sort(device_list.begin(), device_list.end(), [](audio_device_enumerator::audio_device a, audio_device_enumerator::audio_device b)
{
return a.name < b.name;
});
return device_list;
}