diff options
| author | 2023-06-22 21:53:07 -0700 | |
|---|---|---|
| committer | 2023-06-22 21:53:07 -0700 | |
| commit | 2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8 (patch) | |
| tree | d82f2cf4f7a5e9773616846c095a941b282a84f6 /src/audio_core/sink | |
| parent | Merge pull request #10806 from liamwhite/worst-fs-implementation-ever (diff) | |
| parent | Remove memory allocations in some hot paths (diff) | |
| download | yuzu-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.h | 2 | ||||
| -rw-r--r-- | src/audio_core/sink/sink_stream.cpp | 15 | ||||
| -rw-r--r-- | src/audio_core/sink/sink_stream.h | 5 |
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 | ||
| 19 | namespace AudioCore::Sink { | 19 | namespace AudioCore::Sink { |
| 20 | 20 | ||
| 21 | void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) { | 21 | void 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 | ||
| 21 | namespace Core { | 22 | namespace 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 | ||
| 260 | using SinkStreamPtr = std::unique_ptr<SinkStream>; | 263 | using SinkStreamPtr = std::unique_ptr<SinkStream>; |