diff options
Diffstat (limited to 'src/audio_core')
-rw-r--r-- | src/audio_core/audio_core.cpp | 16 | ||||
-rw-r--r-- | src/audio_core/null_sink.h | 6 | ||||
-rw-r--r-- | src/audio_core/sdl2_sink.cpp | 30 | ||||
-rw-r--r-- | src/audio_core/sdl2_sink.h | 5 | ||||
-rw-r--r-- | src/audio_core/sink.h | 9 | ||||
-rw-r--r-- | src/audio_core/sink_details.cpp | 19 | ||||
-rw-r--r-- | src/audio_core/sink_details.h | 2 |
7 files changed, 69 insertions, 18 deletions
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp index ba6acf28e..84f9c03a7 100644 --- a/src/audio_core/audio_core.cpp +++ b/src/audio_core/audio_core.cpp @@ -56,20 +56,8 @@ void AddAddressSpace(Kernel::VMManager& address_space) { } void SelectSink(std::string sink_id) { - auto iter = - std::find_if(g_sink_details.begin(), g_sink_details.end(), - [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); - - if (sink_id == "auto" || iter == g_sink_details.end()) { - if (sink_id != "auto") { - LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id %s", sink_id.c_str()); - } - // Auto-select. - // g_sink_details is ordered in terms of desirability, with the best choice at the front. - iter = g_sink_details.begin(); - } - - DSP::HLE::SetSink(iter->factory()); + const SinkDetails& sink_details = GetSinkDetails(sink_id); + DSP::HLE::SetSink(sink_details.factory()); } void EnableStretching(bool enable) { diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index e7668438c..c732926a2 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -23,6 +23,12 @@ public: size_t SamplesInQueue() const override { return 0; } + + void SetDevice(int device_id) override {} + + std::vector<std::string> GetDeviceList() const override { + return {}; + } }; } // namespace AudioCore diff --git a/src/audio_core/sdl2_sink.cpp b/src/audio_core/sdl2_sink.cpp index 4b66cd826..933c5f16d 100644 --- a/src/audio_core/sdl2_sink.cpp +++ b/src/audio_core/sdl2_sink.cpp @@ -4,12 +4,12 @@ #include <list> #include <numeric> -#include <vector> #include <SDL.h> #include "audio_core/audio_core.h" #include "audio_core/sdl2_sink.h" #include "common/assert.h" #include "common/logging/log.h" +#include "core/settings.h" namespace AudioCore { @@ -42,10 +42,24 @@ SDL2Sink::SDL2Sink() : impl(std::make_unique<Impl>()) { SDL_AudioSpec obtained_audiospec; SDL_zero(obtained_audiospec); - impl->audio_device_id = - SDL_OpenAudioDevice(nullptr, false, &desired_audiospec, &obtained_audiospec, 0); + int device_count = SDL_GetNumAudioDevices(0); + device_list.clear(); + for (int i = 0; i < device_count; ++i) { + device_list.push_back(SDL_GetAudioDeviceName(i, 0)); + } + + const char* device = nullptr; + + if (device_count >= 1 && Settings::values.audio_device_id != "auto" && + !Settings::values.audio_device_id.empty()) { + device = Settings::values.audio_device_id.c_str(); + } + + impl->audio_device_id = SDL_OpenAudioDevice(device, false, &desired_audiospec, + &obtained_audiospec, SDL_AUDIO_ALLOW_ANY_CHANGE); if (impl->audio_device_id <= 0) { - LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed with: %s", SDL_GetError()); + LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed with code %d for device \"%s\"", + impl->audio_device_id, Settings::values.audio_device_id.c_str()); return; } @@ -69,6 +83,10 @@ unsigned int SDL2Sink::GetNativeSampleRate() const { return impl->sample_rate; } +std::vector<std::string> SDL2Sink::GetDeviceList() const { + return device_list; +} + void SDL2Sink::EnqueueSamples(const s16* samples, size_t sample_count) { if (impl->audio_device_id <= 0) return; @@ -96,6 +114,10 @@ size_t SDL2Sink::SamplesInQueue() const { return total_size; } +void SDL2Sink::SetDevice(int device_id) { + this->device_id = device_id; +} + void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) { Impl* impl = reinterpret_cast<Impl*>(impl_); diff --git a/src/audio_core/sdl2_sink.h b/src/audio_core/sdl2_sink.h index ccd0f7c7e..ce75733b7 100644 --- a/src/audio_core/sdl2_sink.h +++ b/src/audio_core/sdl2_sink.h @@ -21,9 +21,14 @@ public: size_t SamplesInQueue() const override; + std::vector<std::string> GetDeviceList() const override; + void SetDevice(int device_id); + private: struct Impl; std::unique_ptr<Impl> impl; + int device_id; + std::vector<std::string> device_list; }; } // namespace AudioCore diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h index 08f3bab5b..558c8c0fe 100644 --- a/src/audio_core/sink.h +++ b/src/audio_core/sink.h @@ -31,6 +31,15 @@ public: /// Samples enqueued that have not been played yet. virtual std::size_t SamplesInQueue() const = 0; + + /** + * Sets the desired output device. + * @paran device_id Id of the desired device. + */ + virtual void SetDevice(int device_id) = 0; + + /// Returns the list of available devices. + virtual std::vector<std::string> GetDeviceList() const = 0; }; } // namespace diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp index 95ccc9e9d..6972395af 100644 --- a/src/audio_core/sink_details.cpp +++ b/src/audio_core/sink_details.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> #include <memory> #include <vector> #include "audio_core/null_sink.h" @@ -9,6 +10,7 @@ #ifdef HAVE_SDL2 #include "audio_core/sdl2_sink.h" #endif +#include "common/logging/log.h" namespace AudioCore { @@ -20,4 +22,21 @@ const std::vector<SinkDetails> g_sink_details = { {"null", []() { return std::make_unique<NullSink>(); }}, }; +const SinkDetails& GetSinkDetails(std::string sink_id) { + auto iter = + std::find_if(g_sink_details.begin(), g_sink_details.end(), + [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); + + if (sink_id == "auto" || iter == g_sink_details.end()) { + if (sink_id != "auto") { + LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id %s", sink_id.c_str()); + } + // Auto-select. + // g_sink_details is ordered in terms of desirability, with the best choice at the front. + iter = g_sink_details.begin(); + } + + return *iter; +} + } // namespace AudioCore diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h index 4b30cf835..9d3735171 100644 --- a/src/audio_core/sink_details.h +++ b/src/audio_core/sink_details.h @@ -24,4 +24,6 @@ struct SinkDetails { extern const std::vector<SinkDetails> g_sink_details; +const SinkDetails& GetSinkDetails(std::string sink_id); + } // namespace AudioCore |