diff options
Diffstat (limited to 'src/audio_core/device/device_session.cpp')
-rw-r--r-- | src/audio_core/device/device_session.cpp | 114 |
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 |