6 changed files with 163 additions and 0 deletions
-
5src/audio_core/CMakeLists.txt
-
27src/audio_core/null_sink.h
-
29src/audio_core/sink.h
-
38src/audio_core/sink_details.cpp
-
32src/audio_core/sink_details.h
-
32src/audio_core/sink_stream.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 |
|||
@ -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 |
|||
@ -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
|
|||
@ -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 |
|||
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue