summaryrefslogtreecommitdiff
path: root/src/audio_core/sink
diff options
context:
space:
mode:
authorGravatar bunnei2023-06-22 21:53:07 -0700
committerGravatar GitHub2023-06-22 21:53:07 -0700
commit2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8 (patch)
treed82f2cf4f7a5e9773616846c095a941b282a84f6 /src/audio_core/sink
parentMerge pull request #10806 from liamwhite/worst-fs-implementation-ever (diff)
parentRemove memory allocations in some hot paths (diff)
downloadyuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.tar.gz
yuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.tar.xz
yuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.zip
Merge pull request #10457 from Kelebek1/optimise
Remove memory allocations in some hot paths
Diffstat (limited to 'src/audio_core/sink')
-rw-r--r--src/audio_core/sink/null_sink.h2
-rw-r--r--src/audio_core/sink/sink_stream.cpp15
-rw-r--r--src/audio_core/sink/sink_stream.h5
3 files changed, 13 insertions, 9 deletions
diff --git a/src/audio_core/sink/null_sink.h b/src/audio_core/sink/null_sink.h
index 1215d3cd2..b6b43c93e 100644
--- a/src/audio_core/sink/null_sink.h
+++ b/src/audio_core/sink/null_sink.h
@@ -20,7 +20,7 @@ public:
20 explicit NullSinkStreamImpl(Core::System& system_, StreamType type_) 20 explicit NullSinkStreamImpl(Core::System& system_, StreamType type_)
21 : SinkStream{system_, type_} {} 21 : SinkStream{system_, type_} {}
22 ~NullSinkStreamImpl() override {} 22 ~NullSinkStreamImpl() override {}
23 void AppendBuffer(SinkBuffer&, std::vector<s16>&) override {} 23 void AppendBuffer(SinkBuffer&, std::span<s16>) override {}
24 std::vector<s16> ReleaseBuffer(u64) override { 24 std::vector<s16> ReleaseBuffer(u64) override {
25 return {}; 25 return {};
26 } 26 }
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index 9a718a9cc..404dcd0e9 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -18,7 +18,7 @@
18 18
19namespace AudioCore::Sink { 19namespace AudioCore::Sink {
20 20
21void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) { 21void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
22 if (type == StreamType::In) { 22 if (type == StreamType::In) {
23 queue.enqueue(buffer); 23 queue.enqueue(buffer);
24 queued_buffers++; 24 queued_buffers++;
@@ -66,15 +66,16 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
66 static_cast<s16>(std::clamp(right_sample, min, max)); 66 static_cast<s16>(std::clamp(right_sample, min, max));
67 } 67 }
68 68
69 samples.resize(samples.size() / system_channels * device_channels); 69 samples = samples.subspan(0, samples.size() / system_channels * device_channels);
70 70
71 } else if (system_channels == 2 && device_channels == 6) { 71 } else if (system_channels == 2 && device_channels == 6) {
72 // We need moar samples! Not all games will provide 6 channel audio. 72 // We need moar samples! Not all games will provide 6 channel audio.
73 // TODO: Implement some upmixing here. Currently just passthrough, with other 73 // TODO: Implement some upmixing here. Currently just passthrough, with other
74 // channels left as silence. 74 // channels left as silence.
75 std::vector<s16> new_samples(samples.size() / system_channels * device_channels, 0); 75 auto new_size = samples.size() / system_channels * device_channels;
76 tmp_samples.resize_destructive(new_size);
76 77
77 for (u32 read_index = 0, write_index = 0; read_index < samples.size(); 78 for (u32 read_index = 0, write_index = 0; read_index < new_size;
78 read_index += system_channels, write_index += device_channels) { 79 read_index += system_channels, write_index += device_channels) {
79 const auto left_sample{static_cast<s16>(std::clamp( 80 const auto left_sample{static_cast<s16>(std::clamp(
80 static_cast<s32>( 81 static_cast<s32>(
@@ -82,7 +83,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
82 volume), 83 volume),
83 min, max))}; 84 min, max))};
84 85
85 new_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; 86 tmp_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample;
86 87
87 const auto right_sample{static_cast<s16>(std::clamp( 88 const auto right_sample{static_cast<s16>(std::clamp(
88 static_cast<s32>( 89 static_cast<s32>(
@@ -90,9 +91,9 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
90 volume), 91 volume),
91 min, max))}; 92 min, max))};
92 93
93 new_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; 94 tmp_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample;
94 } 95 }
95 samples = std::move(new_samples); 96 samples = std::span<s16>(tmp_samples);
96 97
97 } else if (volume != 1.0f) { 98 } else if (volume != 1.0f) {
98 for (u32 i = 0; i < samples.size(); i++) { 99 for (u32 i = 0; i < samples.size(); i++) {
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index 41cbadc9c..98d72ace1 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -16,6 +16,7 @@
16#include "common/polyfill_thread.h" 16#include "common/polyfill_thread.h"
17#include "common/reader_writer_queue.h" 17#include "common/reader_writer_queue.h"
18#include "common/ring_buffer.h" 18#include "common/ring_buffer.h"
19#include "common/scratch_buffer.h"
19#include "common/thread.h" 20#include "common/thread.h"
20 21
21namespace Core { 22namespace Core {
@@ -170,7 +171,7 @@ public:
170 * @param buffer - Audio buffer information to be queued. 171 * @param buffer - Audio buffer information to be queued.
171 * @param samples - The s16 samples to be queue for playback. 172 * @param samples - The s16 samples to be queue for playback.
172 */ 173 */
173 virtual void AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples); 174 virtual void AppendBuffer(SinkBuffer& buffer, std::span<s16> samples);
174 175
175 /** 176 /**
176 * Release a buffer. Audio In only, will fill a buffer with recorded samples. 177 * Release a buffer. Audio In only, will fill a buffer with recorded samples.
@@ -255,6 +256,8 @@ private:
255 /// Signalled when ring buffer entries are consumed 256 /// Signalled when ring buffer entries are consumed
256 std::condition_variable_any release_cv; 257 std::condition_variable_any release_cv;
257 std::mutex release_mutex; 258 std::mutex release_mutex;
259 /// Temporary buffer for appending samples when upmixing
260 Common::ScratchBuffer<s16> tmp_samples{};
258}; 261};
259 262
260using SinkStreamPtr = std::unique_ptr<SinkStream>; 263using SinkStreamPtr = std::unique_ptr<SinkStream>;