From d7f2d90fd32320bdcc39ad712fd0a1f753031edc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 13 Mar 2023 13:17:43 +0100 Subject: [PATCH] pcm/Normalizer: no in-place editing, separate src/dest parameters This eliminates the memcpy() call from NormalizeFilter::FilterPCM(). --- src/filter/plugins/NormalizeFilterPlugin.cxx | 13 ++++++------- src/pcm/Normalizer.cxx | 14 ++++++++------ src/pcm/Normalizer.hxx | 2 +- test/run_normalize.cxx | 5 +++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/filter/plugins/NormalizeFilterPlugin.cxx b/src/filter/plugins/NormalizeFilterPlugin.cxx index 868787a09..e87ab637a 100644 --- a/src/filter/plugins/NormalizeFilterPlugin.cxx +++ b/src/filter/plugins/NormalizeFilterPlugin.cxx @@ -8,8 +8,7 @@ #include "pcm/Buffer.hxx" #include "pcm/AudioFormat.hxx" #include "pcm/Normalizer.hxx" - -#include +#include "util/SpanCast.hxx" class NormalizeFilter final : public Filter { PcmNormalizer normalizer; @@ -49,13 +48,13 @@ PreparedNormalizeFilter::Open(AudioFormat &audio_format) } std::span -NormalizeFilter::FilterPCM(std::span src) +NormalizeFilter::FilterPCM(std::span _src) { - auto *dest = (int16_t *)buffer.Get(src.size()); - memcpy(dest, src.data(), src.size()); + const auto src = FromBytesStrict(_src); + auto *dest = (int16_t *)buffer.GetT(src.size()); - normalizer.ProcessS16({dest, src.size() / 2}); - return { (const std::byte *)dest, src.size() }; + normalizer.ProcessS16(dest, src); + return std::as_bytes(std::span{dest, src.size()}); } const FilterPlugin normalize_filter_plugin = { diff --git a/src/pcm/Normalizer.cxx b/src/pcm/Normalizer.cxx index cb15ca27b..164d0fef9 100644 --- a/src/pcm/Normalizer.cxx +++ b/src/pcm/Normalizer.cxx @@ -6,9 +6,11 @@ #include "Clamp.hxx" #include "SampleFormat.hxx" #include "Traits.hxx" +#include "util/Compiler.h" void -PcmNormalizer::ProcessS16(const std::span audio) noexcept +PcmNormalizer::ProcessS16(int16_t *gcc_restrict dest, + const std::span src) noexcept { constexpr SampleFormat format = SampleFormat::S16; using Traits = SampleTraits; @@ -16,8 +18,8 @@ PcmNormalizer::ProcessS16(const std::span audio) noexcept const int slot = (pos + 1) % bufsz; int peakVal = 1, peakPos = 0; - for (std::size_t i = 0; i < audio.size(); i++) { - int val = audio[i]; + for (std::size_t i = 0; i < src.size(); i++) { + int val = src[i]; if (val < 0) val = -val; if (val > peakVal) @@ -52,7 +54,7 @@ PcmNormalizer::ProcessS16(const std::span audio) noexcept newGain = 1 << 10; //! Make sure the adjusted gain won't cause clipping - std::size_t ramp = audio.size(); + std::size_t ramp = src.size(); if ((peakVal*newGain >> 10) > Traits::MAX) { newGain = (Traits::MAX << 10)/peakVal; @@ -69,9 +71,9 @@ PcmNormalizer::ProcessS16(const std::span audio) noexcept curGain = 1 << 10; const int delta = (newGain - curGain) / (int)ramp; - for (std::size_t i = 0; i < audio.size(); i++) { + for (std::size_t i = 0; i < src.size(); i++) { //! Amplify the sample - audio[i] = PcmClamp(audio[i] * curGain >> 10); + *dest++ = PcmClamp(src[i] * curGain >> 10); //! Adjust the gain if (i < ramp) diff --git a/src/pcm/Normalizer.hxx b/src/pcm/Normalizer.hxx index 0c826343d..93dff4f81 100644 --- a/src/pcm/Normalizer.hxx +++ b/src/pcm/Normalizer.hxx @@ -41,7 +41,7 @@ public: } //! Process 16-bit signed data - void ProcessS16(std::span audio) noexcept; + void ProcessS16(int16_t *dest, std::span src) noexcept; }; //! TODO: Compressor_Process_int32, Compressor_Process_float, others as needed diff --git a/test/run_normalize.cxx b/test/run_normalize.cxx index ac8bfd140..592209b71 100644 --- a/test/run_normalize.cxx +++ b/test/run_normalize.cxx @@ -37,8 +37,9 @@ try { static std::byte buffer[4096]; ssize_t nbytes; while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) { - normalizer.ProcessS16(FromBytesStrict(std::span{buffer}.first(nbytes))); - [[maybe_unused]] ssize_t ignored = write(1, buffer, nbytes); + static int16_t dest[2048]; + normalizer.ProcessS16(dest, FromBytesStrict(std::span{buffer}.first(nbytes))); + [[maybe_unused]] ssize_t ignored = write(1, dest, nbytes); } return EXIT_SUCCESS;