diff options
Diffstat (limited to 'src/audio_core')
| -rw-r--r-- | src/audio_core/device/device_session.cpp | 6 | ||||
| -rw-r--r-- | src/audio_core/renderer/command/data_source/decode.cpp | 21 | ||||
| -rw-r--r-- | src/audio_core/renderer/command/effect/aux_.cpp | 82 | ||||
| -rw-r--r-- | src/audio_core/sink/sink_stream.cpp | 34 | ||||
| -rw-r--r-- | src/audio_core/sink/sink_stream.h | 3 |
5 files changed, 52 insertions, 94 deletions
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index 86811fcb8..c41d9d1ea 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp @@ -92,9 +92,9 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) { if (type == Sink::StreamType::In) { stream->AppendBuffer(new_buffer, tmp_samples); } else { - system.ApplicationMemory().ReadBlockUnsafe(buffer.samples, tmp_samples.data(), - buffer.size); - stream->AppendBuffer(new_buffer, tmp_samples); + Core::Memory::CpuGuestMemory<s16, Core::Memory::GuestMemoryFlags::UnsafeRead> samples( + system.ApplicationMemory(), buffer.samples, buffer.size / sizeof(s16)); + stream->AppendBuffer(new_buffer, samples); } } } diff --git a/src/audio_core/renderer/command/data_source/decode.cpp b/src/audio_core/renderer/command/data_source/decode.cpp index f45933203..257aa866e 100644 --- a/src/audio_core/renderer/command/data_source/decode.cpp +++ b/src/audio_core/renderer/command/data_source/decode.cpp @@ -28,7 +28,6 @@ constexpr std::array<u8, 3> PitchBySrcQuality = {4, 8, 4}; template <typename T> static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, const DecodeArg& req) { - std::array<T, TempBufferSize> tmp_samples{}; constexpr s32 min{std::numeric_limits<s16>::min()}; constexpr s32 max{std::numeric_limits<s16>::max()}; @@ -49,19 +48,18 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, const VAddr source{req.buffer + (((req.start_offset + req.offset) * channel_count) * sizeof(T))}; const u64 size{channel_count * samples_to_decode}; - const u64 size_bytes{size * sizeof(T)}; - - memory.ReadBlockUnsafe(source, tmp_samples.data(), size_bytes); + Core::Memory::CpuGuestMemory<T, Core::Memory::GuestMemoryFlags::UnsafeRead> samples( + memory, source, size); if constexpr (std::is_floating_point_v<T>) { for (u32 i = 0; i < samples_to_decode; i++) { - auto sample{static_cast<s32>(tmp_samples[i * channel_count + req.target_channel] * + auto sample{static_cast<s32>(samples[i * channel_count + req.target_channel] * std::numeric_limits<s16>::max())}; out_buffer[i] = static_cast<s16>(std::clamp(sample, min, max)); } } else { for (u32 i = 0; i < samples_to_decode; i++) { - out_buffer[i] = tmp_samples[i * channel_count + req.target_channel]; + out_buffer[i] = samples[i * channel_count + req.target_channel]; } } } break; @@ -74,16 +72,17 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, } const VAddr source{req.buffer + ((req.start_offset + req.offset) * sizeof(T))}; - memory.ReadBlockUnsafe(source, tmp_samples.data(), samples_to_decode * sizeof(T)); + Core::Memory::CpuGuestMemory<T, Core::Memory::GuestMemoryFlags::UnsafeRead> samples( + memory, source, samples_to_decode); if constexpr (std::is_floating_point_v<T>) { for (u32 i = 0; i < samples_to_decode; i++) { - auto sample{static_cast<s32>(tmp_samples[i * channel_count + req.target_channel] * + auto sample{static_cast<s32>(samples[i * channel_count + req.target_channel] * std::numeric_limits<s16>::max())}; out_buffer[i] = static_cast<s16>(std::clamp(sample, min, max)); } } else { - std::memcpy(out_buffer.data(), tmp_samples.data(), samples_to_decode * sizeof(s16)); + std::memcpy(out_buffer.data(), samples.data(), samples_to_decode * sizeof(s16)); } break; } @@ -101,7 +100,6 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, */ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, const DecodeArg& req) { - std::array<u8, TempBufferSize> wavebuffer{}; constexpr u32 SamplesPerFrame{14}; constexpr u32 NibblesPerFrame{16}; @@ -139,7 +137,8 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, } const auto size{std::max((samples_to_process / 8U) * SamplesPerFrame, 8U)}; - memory.ReadBlockUnsafe(req.buffer + position_in_frame / 2, wavebuffer.data(), size); + Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::UnsafeRead> wavebuffer( + memory, req.buffer + position_in_frame / 2, size); auto context{req.adpcm_context}; auto header{context->header}; diff --git a/src/audio_core/renderer/command/effect/aux_.cpp b/src/audio_core/renderer/command/effect/aux_.cpp index c5650effa..a3e12b3e7 100644 --- a/src/audio_core/renderer/command/effect/aux_.cpp +++ b/src/audio_core/renderer/command/effect/aux_.cpp @@ -21,23 +21,13 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in } AuxInfo::AuxInfoDsp info{}; - auto info_ptr{&info}; - bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <= - (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))}; + memory.ReadBlockUnsafe(aux_info, &info, sizeof(AuxInfo::AuxInfoDsp)); - if (host_safe) [[likely]] { - info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info); - } else { - memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp)); - } + info.read_offset = 0; + info.write_offset = 0; + info.total_sample_count = 0; - info_ptr->read_offset = 0; - info_ptr->write_offset = 0; - info_ptr->total_sample_count = 0; - - if (!host_safe) [[unlikely]] { - memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp)); - } + memory.WriteBlockUnsafe(aux_info, &info, sizeof(AuxInfo::AuxInfoDsp)); } /** @@ -86,17 +76,9 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, } AuxInfo::AuxInfoDsp send_info{}; - auto send_ptr = &send_info; - bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <= - (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp)); - - if (host_safe) [[likely]] { - send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_); - } else { - memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp)); - } + memory.ReadBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp)); - u32 target_write_offset{send_ptr->write_offset + write_offset}; + u32 target_write_offset{send_info.write_offset + write_offset}; if (target_write_offset > count_max) { return 0; } @@ -105,15 +87,9 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, u32 read_pos{0}; while (write_count > 0) { u32 to_write{std::min(count_max - target_write_offset, write_count)}; - const auto write_addr = send_buffer + target_write_offset * sizeof(s32); - bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <= - (Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))}; - if (write_safe) [[likely]] { - auto ptr = memory.GetPointer(write_addr); - std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32)); - } else { - memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32), - &input[read_pos], to_write * sizeof(s32)); + if (to_write > 0) { + const auto write_addr = send_buffer + target_write_offset * sizeof(s32); + memory.WriteBlockUnsafe(write_addr, &input[read_pos], to_write * sizeof(s32)); } target_write_offset = (target_write_offset + to_write) % count_max; write_count -= to_write; @@ -121,13 +97,10 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, } if (update_count) { - send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max; - } - - if (!host_safe) [[unlikely]] { - memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp)); + send_info.write_offset = (send_info.write_offset + update_count) % count_max; } + memory.WriteBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp)); return write_count_; } @@ -174,17 +147,9 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, } AuxInfo::AuxInfoDsp return_info{}; - auto return_ptr = &return_info; - bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <= - (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp)); + memory.ReadBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp)); - if (host_safe) [[likely]] { - return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_); - } else { - memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp)); - } - - u32 target_read_offset{return_ptr->read_offset + read_offset}; + u32 target_read_offset{return_info.read_offset + read_offset}; if (target_read_offset > count_max) { return 0; } @@ -193,15 +158,9 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, u32 write_pos{0}; while (read_count > 0) { u32 to_read{std::min(count_max - target_read_offset, read_count)}; - const auto read_addr = return_buffer + target_read_offset * sizeof(s32); - bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <= - (Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))}; - if (read_safe) [[likely]] { - auto ptr = memory.GetPointer(read_addr); - std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32)); - } else { - memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32), - &output[write_pos], to_read * sizeof(s32)); + if (to_read > 0) { + const auto read_addr = return_buffer + target_read_offset * sizeof(s32); + memory.ReadBlockUnsafe(read_addr, &output[write_pos], to_read * sizeof(s32)); } target_read_offset = (target_read_offset + to_read) % count_max; read_count -= to_read; @@ -209,13 +168,10 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, } if (update_count) { - return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max; - } - - if (!host_safe) [[unlikely]] { - memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp)); + return_info.read_offset = (return_info.read_offset + update_count) % count_max; } + memory.WriteBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp)); return read_count_; } diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 404dcd0e9..6081352a2 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -12,6 +12,7 @@ #include "audio_core/sink/sink_stream.h" #include "common/common_types.h" #include "common/fixed_point.h" +#include "common/scope_exit.h" #include "common/settings.h" #include "core/core.h" #include "core/core_timing.h" @@ -19,9 +20,12 @@ namespace AudioCore::Sink { void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { - if (type == StreamType::In) { + SCOPE_EXIT({ queue.enqueue(buffer); - queued_buffers++; + ++queued_buffers; + }); + + if (type == StreamType::In) { return; } @@ -66,16 +70,17 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { static_cast<s16>(std::clamp(right_sample, min, max)); } - samples = samples.subspan(0, samples.size() / system_channels * device_channels); + samples_buffer.Push(samples.subspan(0, samples.size() / system_channels * device_channels)); + return; + } - } else if (system_channels == 2 && device_channels == 6) { + if (system_channels == 2 && device_channels == 6) { // We need moar samples! Not all games will provide 6 channel audio. // TODO: Implement some upmixing here. Currently just passthrough, with other // channels left as silence. - auto new_size = samples.size() / system_channels * device_channels; - tmp_samples.resize_destructive(new_size); + std::vector<s16> new_samples(samples.size() / system_channels * device_channels); - for (u32 read_index = 0, write_index = 0; read_index < new_size; + for (u32 read_index = 0, write_index = 0; read_index < samples.size(); read_index += system_channels, write_index += device_channels) { const auto left_sample{static_cast<s16>(std::clamp( static_cast<s32>( @@ -83,7 +88,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { volume), min, max))}; - tmp_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; + new_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; const auto right_sample{static_cast<s16>(std::clamp( static_cast<s32>( @@ -91,20 +96,21 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { volume), min, max))}; - tmp_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; + new_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; } - samples = std::span<s16>(tmp_samples); - } else if (volume != 1.0f) { - for (u32 i = 0; i < samples.size(); i++) { + samples_buffer.Push(new_samples); + return; + } + + if (volume != 1.0f) { + for (u32 i = 0; i < samples.size(); ++i) { samples[i] = static_cast<s16>( std::clamp(static_cast<s32>(static_cast<f32>(samples[i]) * volume), min, max)); } } samples_buffer.Push(samples); - queue.enqueue(buffer); - queued_buffers++; } std::vector<s16> SinkStream::ReleaseBuffer(u64 num_samples) { diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h index 98d72ace1..6a4996ca3 100644 --- a/src/audio_core/sink/sink_stream.h +++ b/src/audio_core/sink/sink_stream.h @@ -16,7 +16,6 @@ #include "common/polyfill_thread.h" #include "common/reader_writer_queue.h" #include "common/ring_buffer.h" -#include "common/scratch_buffer.h" #include "common/thread.h" namespace Core { @@ -256,8 +255,6 @@ private: /// Signalled when ring buffer entries are consumed std::condition_variable_any release_cv; std::mutex release_mutex; - /// Temporary buffer for appending samples when upmixing - Common::ScratchBuffer<s16> tmp_samples{}; }; using SinkStreamPtr = std::unique_ptr<SinkStream>; |
