summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-14 21:48:17 -0500
committerGravatar GitHub2018-12-14 21:48:17 -0500
commitb88430c29908a0f0b9cdbce139fac4f9c392eec6 (patch)
tree6554f524db5348ae005504a4dd13954342ca9008
parentMerge pull request #1899 from lioncash/state (diff)
parentaudio_core: Make g_sink_details internally linked (diff)
downloadyuzu-b88430c29908a0f0b9cdbce139fac4f9c392eec6.tar.gz
yuzu-b88430c29908a0f0b9cdbce139fac4f9c392eec6.tar.xz
yuzu-b88430c29908a0f0b9cdbce139fac4f9c392eec6.zip
Merge pull request #1902 from lioncash/audio
audio_core: Make g_sink_details internally linked
Diffstat (limited to '')
-rw-r--r--src/audio_core/audio_out.cpp3
-rw-r--r--src/audio_core/cubeb_sink.cpp2
-rw-r--r--src/audio_core/cubeb_sink.h2
-rw-r--r--src/audio_core/null_sink.h2
-rw-r--r--src/audio_core/sink_details.cpp53
-rw-r--r--src/audio_core/sink_details.h25
-rw-r--r--src/yuzu/configuration/configure_audio.cpp7
7 files changed, 58 insertions, 36 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index 0c8f5b18e..cbba17632 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -30,8 +30,7 @@ static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
30StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, 30StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name,
31 Stream::ReleaseCallback&& release_callback) { 31 Stream::ReleaseCallback&& release_callback) {
32 if (!sink) { 32 if (!sink) {
33 const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id); 33 sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id);
34 sink = sink_details.factory(Settings::values.audio_device_id);
35 } 34 }
36 35
37 return std::make_shared<Stream>( 36 return std::make_shared<Stream>(
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index d31a1c844..097328901 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -107,7 +107,7 @@ private:
107 static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state); 107 static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state);
108}; 108};
109 109
110CubebSink::CubebSink(std::string target_device_name) { 110CubebSink::CubebSink(std::string_view target_device_name) {
111 if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) { 111 if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) {
112 LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); 112 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
113 return; 113 return;
diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h
index 59cbf05e9..efb9d1634 100644
--- a/src/audio_core/cubeb_sink.h
+++ b/src/audio_core/cubeb_sink.h
@@ -15,7 +15,7 @@ namespace AudioCore {
15 15
16class CubebSink final : public Sink { 16class CubebSink final : public Sink {
17public: 17public:
18 explicit CubebSink(std::string device_id); 18 explicit CubebSink(std::string_view device_id);
19 ~CubebSink() override; 19 ~CubebSink() override;
20 20
21 SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, 21 SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
index a78d78893..61a28d542 100644
--- a/src/audio_core/null_sink.h
+++ b/src/audio_core/null_sink.h
@@ -10,7 +10,7 @@ namespace AudioCore {
10 10
11class NullSink final : public Sink { 11class NullSink final : public Sink {
12public: 12public:
13 explicit NullSink(std::string){}; 13 explicit NullSink(std::string_view) {}
14 ~NullSink() override = default; 14 ~NullSink() override = default;
15 15
16 SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/, 16 SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/,
diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp
index 67cf1f3b2..a848eb1c9 100644
--- a/src/audio_core/sink_details.cpp
+++ b/src/audio_core/sink_details.cpp
@@ -14,31 +14,68 @@
14#include "common/logging/log.h" 14#include "common/logging/log.h"
15 15
16namespace AudioCore { 16namespace AudioCore {
17namespace {
18struct SinkDetails {
19 using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
20 using ListDevicesFn = std::vector<std::string> (*)();
17 21
18// g_sink_details is ordered in terms of desirability, with the best choice at the top. 22 /// Name for this sink.
19const std::vector<SinkDetails> g_sink_details = { 23 const char* id;
24 /// A method to call to construct an instance of this type of sink.
25 FactoryFn factory;
26 /// A method to call to list available devices.
27 ListDevicesFn list_devices;
28};
29
30// sink_details is ordered in terms of desirability, with the best choice at the top.
31constexpr SinkDetails sink_details[] = {
20#ifdef HAVE_CUBEB 32#ifdef HAVE_CUBEB
21 SinkDetails{"cubeb", &std::make_unique<CubebSink, std::string>, &ListCubebSinkDevices}, 33 SinkDetails{"cubeb",
34 [](std::string_view device_id) -> std::unique_ptr<Sink> {
35 return std::make_unique<CubebSink>(device_id);
36 },
37 &ListCubebSinkDevices},
22#endif 38#endif
23 SinkDetails{"null", &std::make_unique<NullSink, std::string>, 39 SinkDetails{"null",
40 [](std::string_view device_id) -> std::unique_ptr<Sink> {
41 return std::make_unique<NullSink>(device_id);
42 },
24 [] { return std::vector<std::string>{"null"}; }}, 43 [] { return std::vector<std::string>{"null"}; }},
25}; 44};
26 45
27const SinkDetails& GetSinkDetails(std::string_view sink_id) { 46const SinkDetails& GetSinkDetails(std::string_view sink_id) {
28 auto iter = 47 auto iter =
29 std::find_if(g_sink_details.begin(), g_sink_details.end(), 48 std::find_if(std::begin(sink_details), std::end(sink_details),
30 [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); 49 [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
31 50
32 if (sink_id == "auto" || iter == g_sink_details.end()) { 51 if (sink_id == "auto" || iter == std::end(sink_details)) {
33 if (sink_id != "auto") { 52 if (sink_id != "auto") {
34 LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id); 53 LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id);
35 } 54 }
36 // Auto-select. 55 // Auto-select.
37 // g_sink_details is ordered in terms of desirability, with the best choice at the front. 56 // sink_details is ordered in terms of desirability, with the best choice at the front.
38 iter = g_sink_details.begin(); 57 iter = std::begin(sink_details);
39 } 58 }
40 59
41 return *iter; 60 return *iter;
42} 61}
62} // Anonymous namespace
63
64std::vector<const char*> GetSinkIDs() {
65 std::vector<const char*> sink_ids(std::size(sink_details));
66
67 std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
68 [](const auto& sink) { return sink.id; });
69
70 return sink_ids;
71}
72
73std::vector<std::string> GetDeviceListForSink(std::string_view sink_id) {
74 return GetSinkDetails(sink_id).list_devices();
75}
76
77std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id) {
78 return GetSinkDetails(sink_id).factory(device_id);
79}
43 80
44} // namespace AudioCore 81} // namespace AudioCore
diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h
index 03534b187..bc8786270 100644
--- a/src/audio_core/sink_details.h
+++ b/src/audio_core/sink_details.h
@@ -4,34 +4,21 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <functional>
8#include <memory>
9#include <string> 7#include <string>
10#include <string_view> 8#include <string_view>
11#include <utility>
12#include <vector> 9#include <vector>
13 10
14namespace AudioCore { 11namespace AudioCore {
15 12
16class Sink; 13class Sink;
17 14
18struct SinkDetails { 15/// Retrieves the IDs for all available audio sinks.
19 using FactoryFn = std::function<std::unique_ptr<Sink>(std::string)>; 16std::vector<const char*> GetSinkIDs();
20 using ListDevicesFn = std::function<std::vector<std::string>()>;
21 17
22 SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_) 18/// Gets the list of devices for a particular sink identified by the given ID.
23 : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {} 19std::vector<std::string> GetDeviceListForSink(std::string_view sink_id);
24 20
25 /// Name for this sink. 21/// Creates an audio sink identified by the given device ID.
26 const char* id; 22std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id);
27 /// A method to call to construct an instance of this type of sink.
28 FactoryFn factory;
29 /// A method to call to list available devices.
30 ListDevicesFn list_devices;
31};
32
33extern const std::vector<SinkDetails> g_sink_details;
34
35const SinkDetails& GetSinkDetails(std::string_view sink_id);
36 23
37} // namespace AudioCore 24} // namespace AudioCore
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index eb1da0f9e..5d9ccc6e8 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -17,8 +17,8 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
17 17
18 ui->output_sink_combo_box->clear(); 18 ui->output_sink_combo_box->clear();
19 ui->output_sink_combo_box->addItem("auto"); 19 ui->output_sink_combo_box->addItem("auto");
20 for (const auto& sink_detail : AudioCore::g_sink_details) { 20 for (const char* id : AudioCore::GetSinkIDs()) {
21 ui->output_sink_combo_box->addItem(sink_detail.id); 21 ui->output_sink_combo_box->addItem(id);
22 } 22 }
23 23
24 connect(ui->volume_slider, &QSlider::valueChanged, this, 24 connect(ui->volume_slider, &QSlider::valueChanged, this,
@@ -97,8 +97,7 @@ void ConfigureAudio::updateAudioDevices(int sink_index) {
97 ui->audio_device_combo_box->addItem(AudioCore::auto_device_name); 97 ui->audio_device_combo_box->addItem(AudioCore::auto_device_name);
98 98
99 const std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString(); 99 const std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
100 const std::vector<std::string> device_list = AudioCore::GetSinkDetails(sink_id).list_devices(); 100 for (const auto& device : AudioCore::GetDeviceListForSink(sink_id)) {
101 for (const auto& device : device_list) {
102 ui->audio_device_combo_box->addItem(QString::fromStdString(device)); 101 ui->audio_device_combo_box->addItem(QString::fromStdString(device));
103 } 102 }
104} 103}