diff options
author | bunnei <bunneidev@gmail.com> | 2018-07-28 19:40:50 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-07-31 03:45:24 +0200 |
commit | 9ef227e09d6e374008d9536935d01c11a6ca06bd (patch) | |
tree | 55a0169ab36ff521770a94a59b857063caf65f8b | |
parent | audio_core: Misc. improvements to stream/buffer/audio_out. (diff) | |
download | yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar.gz yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar.bz2 yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar.lz yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar.xz yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.tar.zst yuzu-9ef227e09d6e374008d9536935d01c11a6ca06bd.zip |
-rw-r--r-- | src/audio_core/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/audio_core/null_sink.h | 27 | ||||
-rw-r--r-- | src/audio_core/sink.h | 29 | ||||
-rw-r--r-- | src/audio_core/sink_details.cpp | 38 | ||||
-rw-r--r-- | src/audio_core/sink_details.h | 32 | ||||
-rw-r--r-- | src/audio_core/sink_stream.h | 32 |
6 files changed, 163 insertions, 0 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index f00a55994..6bc8f586a 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -2,8 +2,13 @@ add_library(audio_core STATIC audio_out.cpp audio_out.h buffer.h + null_sink.h stream.cpp stream.h + sink.h + sink_details.cpp + sink_details.h + sink_stream.h ) create_target_directory_groups(audio_core) diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h new file mode 100644 index 000000000..2e04438f7 --- /dev/null +++ b/src/audio_core/null_sink.h @@ -0,0 +1,27 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "audio_core/sink.h" + +namespace AudioCore { + +class NullSink final : public Sink { +public: + explicit NullSink(std::string){}; + ~NullSink() override = default; + + SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/) override { + return null_sink_stream; + } + +private: + struct NullSinkStreamImpl final : SinkStream { + void EnqueueSamples(u32 /*num_channels*/, const s16* /*samples*/, + size_t /*sample_count*/) override {} + } null_sink_stream; +}; + +} // namespace AudioCore diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h new file mode 100644 index 000000000..d1bb98c3d --- /dev/null +++ b/src/audio_core/sink.h @@ -0,0 +1,29 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> + +#include "audio_core/sink_stream.h" +#include "common/common_types.h" + +namespace AudioCore { + +constexpr char auto_device_name[] = "auto"; + +/** + * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed + * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate. + * They are dumb outputs. + */ +class Sink { +public: + virtual ~Sink() = default; + virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) = 0; +}; + +using SinkPtr = std::unique_ptr<Sink>; + +} // namespace AudioCore diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp new file mode 100644 index 000000000..6396d8065 --- /dev/null +++ b/src/audio_core/sink_details.cpp @@ -0,0 +1,38 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <algorithm> +#include <memory> +#include <string> +#include <vector> +#include "audio_core/null_sink.h" +#include "audio_core/sink_details.h" +#include "common/logging/log.h" + +namespace AudioCore { + +// g_sink_details is ordered in terms of desirability, with the best choice at the top. +const std::vector<SinkDetails> g_sink_details = { + SinkDetails{"null", &std::make_unique<NullSink, std::string>, + [] { return std::vector<std::string>{"null"}; }}, +}; + +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 {}", sink_id); + } + // 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 new file mode 100644 index 000000000..aa8aae1a9 --- /dev/null +++ b/src/audio_core/sink_details.h @@ -0,0 +1,32 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <functional> +#include <memory> +#include <vector> + +namespace AudioCore { + +class Sink; + +struct SinkDetails { + SinkDetails(const char* id_, std::function<std::unique_ptr<Sink>(std::string)> factory_, + std::function<std::vector<std::string>()> list_devices_) + : id(id_), factory(factory_), list_devices(list_devices_) {} + + /// Name for this sink. + const char* id; + /// A method to call to construct an instance of this type of sink. + std::function<std::unique_ptr<Sink>(std::string device_id)> factory; + /// A method to call to list available devices. + std::function<std::vector<std::string>()> list_devices; +}; + +extern const std::vector<SinkDetails> g_sink_details; + +const SinkDetails& GetSinkDetails(std::string sink_id); + +} // namespace AudioCore diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h new file mode 100644 index 000000000..e7a3f01b0 --- /dev/null +++ b/src/audio_core/sink_stream.h @@ -0,0 +1,32 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> + +#include "common/common_types.h" + +namespace AudioCore { + +/** + * Accepts samples in stereo signed PCM16 format to be output. Sinks *do not* handle resampling and + * expect the correct sample rate. They are dumb outputs. + */ +class SinkStream { +public: + virtual ~SinkStream() = default; + + /** + * Feed stereo samples to sink. + * @param num_channels Number of channels used. + * @param samples Samples in interleaved stereo PCM16 format. + * @param sample_count Number of samples. + */ + virtual void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) = 0; +}; + +using SinkStreamPtr = std::unique_ptr<SinkStream>; + +} // namespace AudioCore |