mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-13 16:07:57 -05:00
Project Andio
This commit is contained in:
114
src/audio_core/device/device_session.cpp
Normal file
114
src/audio_core/device/device_session.cpp
Normal file
@ -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
|
Reference in New Issue
Block a user