summaryrefslogtreecommitdiffstats
path: root/src/audio_core/device/device_session.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/device/device_session.cpp')
-rw-r--r--src/audio_core/device/device_session.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp
new file mode 100644
index 000000000..095fc96ce
--- /dev/null
+++ b/src/audio_core/device/device_session.cpp
@@ -0,0 +1,114 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/audio_core.h"
+#include "audio_core/audio_manager.h"
+#include "audio_core/device/audio_buffer.h"
+#include "audio_core/device/device_session.h"
+#include "audio_core/sink/sink_stream.h"
+#include "core/core.h"
+#include "core/memory.h"
+
+namespace AudioCore {
+
+DeviceSession::DeviceSession(Core::System& system_) : system{system_} {}
+
+DeviceSession::~DeviceSession() {
+ Finalize();
+}
+
+Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_format_,
+ u16 channel_count_, size_t session_id_, u32 handle_,
+ u64 applet_resource_user_id_, Sink::StreamType type_) {
+ if (stream) {
+ Finalize();
+ }
+ name = fmt::format("{}-{}", name_, session_id_);
+ type = type_;
+ sample_format = sample_format_;
+ channel_count = channel_count_;
+ session_id = session_id_;
+ handle = handle_;
+ applet_resource_user_id = applet_resource_user_id_;
+
+ if (type == Sink::StreamType::In) {
+ sink = &system.AudioCore().GetInputSink();
+ } else {
+ sink = &system.AudioCore().GetOutputSink();
+ }
+ stream = sink->AcquireSinkStream(system, channel_count, name, type);
+ initialized = true;
+ return ResultSuccess;
+}
+
+void DeviceSession::Finalize() {
+ if (initialized) {
+ Stop();
+ sink->CloseStream(stream);
+ stream = nullptr;
+ }
+}
+
+void DeviceSession::Start() {
+ stream->SetPlayedSampleCount(played_sample_count);
+ stream->Start();
+}
+
+void DeviceSession::Stop() {
+ if (stream) {
+ played_sample_count = stream->GetPlayedSampleCount();
+ stream->Stop();
+ }
+}
+
+void DeviceSession::AppendBuffers(std::span<AudioBuffer> buffers) const {
+ auto& memory{system.Memory()};
+
+ for (size_t i = 0; i < buffers.size(); i++) {
+ Sink::SinkBuffer new_buffer{
+ .frames = buffers[i].size / (channel_count * sizeof(s16)),
+ .frames_played = 0,
+ .tag = buffers[i].tag,
+ .consumed = false,
+ };
+
+ if (type == Sink::StreamType::In) {
+ std::vector<s16> samples{};
+ stream->AppendBuffer(new_buffer, samples);
+ } else {
+ std::vector<s16> samples(buffers[i].size / sizeof(s16));
+ memory.ReadBlockUnsafe(buffers[i].samples, samples.data(), buffers[i].size);
+ stream->AppendBuffer(new_buffer, samples);
+ }
+ }
+}
+
+void DeviceSession::ReleaseBuffer(AudioBuffer& buffer) const {
+ if (type == Sink::StreamType::In) {
+ auto& memory{system.Memory()};
+ auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))};
+ memory.WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);
+ }
+}
+
+bool DeviceSession::IsBufferConsumed(u64 tag) const {
+ if (stream) {
+ return stream->IsBufferConsumed(tag);
+ }
+ return true;
+}
+
+void DeviceSession::SetVolume(f32 volume) const {
+ if (stream) {
+ stream->SetSystemVolume(volume);
+ }
+}
+
+u64 DeviceSession::GetPlayedSampleCount() const {
+ if (stream) {
+ return stream->GetPlayedSampleCount();
+ }
+ return 0;
+}
+
+} // namespace AudioCore