audio_core: Implement OpenAL backend (#6450)
This commit is contained in:
parent
ce553ab995
commit
055a58f01e
48 changed files with 1042 additions and 576 deletions
|
@ -14,6 +14,9 @@
|
|||
#ifdef HAVE_CUBEB
|
||||
#include "audio_core/cubeb_sink.h"
|
||||
#endif
|
||||
#ifdef HAVE_OPENAL
|
||||
#include "audio_core/openal_sink.h"
|
||||
#endif
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
@ -22,8 +25,10 @@ struct SinkDetails {
|
|||
using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
|
||||
using ListDevicesFn = std::vector<std::string> (*)();
|
||||
|
||||
/// Type of this sink.
|
||||
SinkType type;
|
||||
/// Name for this sink.
|
||||
const char* id;
|
||||
std::string_view name;
|
||||
/// A method to call to construct an instance of this type of sink.
|
||||
FactoryFn factory;
|
||||
/// A method to call to list available devices.
|
||||
|
@ -31,61 +36,66 @@ struct SinkDetails {
|
|||
};
|
||||
|
||||
// sink_details is ordered in terms of desirability, with the best choice at the top.
|
||||
constexpr SinkDetails sink_details[] = {
|
||||
constexpr std::array sink_details = {
|
||||
#ifdef HAVE_CUBEB
|
||||
SinkDetails{"cubeb",
|
||||
SinkDetails{SinkType::Cubeb, "Cubeb",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<CubebSink>(device_id);
|
||||
},
|
||||
&ListCubebSinkDevices},
|
||||
#endif
|
||||
#ifdef HAVE_OPENAL
|
||||
SinkDetails{SinkType::OpenAL, "OpenAL",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<OpenALSink>(std::string(device_id));
|
||||
},
|
||||
&ListOpenALSinkDevices},
|
||||
#endif
|
||||
#ifdef HAVE_SDL2
|
||||
SinkDetails{"sdl2",
|
||||
SinkDetails{SinkType::SDL2, "SDL2",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<SDL2Sink>(std::string(device_id));
|
||||
},
|
||||
&ListSDL2SinkDevices},
|
||||
#endif
|
||||
SinkDetails{"null",
|
||||
SinkDetails{SinkType::Null, "None",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<NullSink>(device_id);
|
||||
},
|
||||
[] { return std::vector<std::string>{"null"}; }},
|
||||
[] { return std::vector<std::string>{"None"}; }},
|
||||
};
|
||||
|
||||
const SinkDetails& GetSinkDetails(std::string_view sink_id) {
|
||||
auto iter =
|
||||
std::find_if(std::begin(sink_details), std::end(sink_details),
|
||||
[sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
|
||||
const SinkDetails& GetSinkDetails(SinkType sink_type) {
|
||||
auto iter = std::find_if(
|
||||
sink_details.begin(), sink_details.end(),
|
||||
[sink_type](const auto& sink_detail) { return sink_detail.type == sink_type; });
|
||||
|
||||
if (sink_id == "auto" || iter == std::end(sink_details)) {
|
||||
if (sink_id != "auto") {
|
||||
LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id);
|
||||
if (sink_type == SinkType::Auto || iter == sink_details.end()) {
|
||||
if (sink_type != SinkType::Auto) {
|
||||
LOG_ERROR(Audio, "AudioCore::GetSinkDetails given invalid sink_type {}", sink_type);
|
||||
}
|
||||
// Auto-select.
|
||||
// sink_details is ordered in terms of desirability, with the best choice at the front.
|
||||
iter = std::begin(sink_details);
|
||||
iter = sink_details.begin();
|
||||
}
|
||||
|
||||
return *iter;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::vector<const char*> GetSinkIDs() {
|
||||
std::vector<const char*> sink_ids(std::size(sink_details));
|
||||
|
||||
std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
|
||||
[](const auto& sink) { return sink.id; });
|
||||
|
||||
return sink_ids;
|
||||
std::string_view GetSinkName(SinkType sink_type) {
|
||||
if (sink_type == SinkType::Auto) {
|
||||
return "Auto";
|
||||
}
|
||||
return GetSinkDetails(sink_type).name;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetDeviceListForSink(std::string_view sink_id) {
|
||||
return GetSinkDetails(sink_id).list_devices();
|
||||
std::vector<std::string> GetDeviceListForSink(SinkType sink_type) {
|
||||
return GetSinkDetails(sink_type).list_devices();
|
||||
}
|
||||
|
||||
std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id) {
|
||||
return GetSinkDetails(sink_id).factory(device_id);
|
||||
std::unique_ptr<Sink> CreateSinkFromID(SinkType sink_type, std::string_view device_id) {
|
||||
return GetSinkDetails(sink_type).factory(device_id);
|
||||
}
|
||||
|
||||
} // namespace AudioCore
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue