From b10b05078a209b7ae1908f2048308c61f88b95bb Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sat, 30 May 2020 20:59:41 +0200 Subject: [PATCH] The fill simd helper is just an alias for absl::c_fill The pass-by-value alias is still necessary for cases where you pass an rvalue to the function (which happens often when e.g. you take a subspan) --- benchmarks/BM_pan.cpp | 2 +- src/sfizz/AudioSpan.h | 2 +- src/sfizz/HistoricalBuffer.h | 2 +- src/sfizz/ModifierHelpers.h | 16 ++++++++-------- src/sfizz/SIMDHelpers.h | 5 +---- src/sfizz/SIMDSSE.cpp | 20 -------------------- src/sfizz/Voice.cpp | 12 ++++++------ 7 files changed, 18 insertions(+), 41 deletions(-) diff --git a/benchmarks/BM_pan.cpp b/benchmarks/BM_pan.cpp index 8cafb079..70707ee9 100644 --- a/benchmarks/BM_pan.cpp +++ b/benchmarks/BM_pan.cpp @@ -67,7 +67,7 @@ BENCHMARK_DEFINE_F(PanArray, BlockOps)(benchmark::State& state) { ScopedFTZ ftz; for (auto _ : state) { - sfz::fill(span2, 1.0f); + sfz::fill(span2, 1.0f); sfz::add(span1, span2); sfz::applyGain(piFour(), span2); sfz::cos(span2, span1); diff --git a/src/sfizz/AudioSpan.h b/src/sfizz/AudioSpan.h index 23c9d340..21fcb4be 100644 --- a/src/sfizz/AudioSpan.h +++ b/src/sfizz/AudioSpan.h @@ -279,7 +279,7 @@ public: { static_assert(!std::is_const::value, "Can't allow mutating operations on const AudioSpans"); for (size_t i = 0; i < numChannels; ++i) - sfz::fill(getSpan(i), value); + sfz::fill(getSpan(i), value); } /** diff --git a/src/sfizz/HistoricalBuffer.h b/src/sfizz/HistoricalBuffer.h index e2b3b8e5..a52b8932 100644 --- a/src/sfizz/HistoricalBuffer.h +++ b/src/sfizz/HistoricalBuffer.h @@ -35,7 +35,7 @@ public: void resize(size_t size) { buffer.resize(size); - fill(absl::MakeSpan(buffer), 0.0); + fill(absl::MakeSpan(buffer), ValueType { 0 }); index = 0; validMean = false; } diff --git a/src/sfizz/ModifierHelpers.h b/src/sfizz/ModifierHelpers.h index 8e01610a..e3d8006e 100644 --- a/src/sfizz/ModifierHelpers.h +++ b/src/sfizz/ModifierHelpers.h @@ -74,7 +74,7 @@ void linearEnvelope(const EventVector& events, absl::Span envelope, F&& l lastValue = linearRamp(envelope.subspan(lastDelay, length), lastValue, step); lastDelay += length; } - fill(envelope.subspan(lastDelay), lastValue); + fill(envelope.subspan(lastDelay), lastValue); } template @@ -100,7 +100,7 @@ void linearEnvelope(const EventVector& events, absl::Span envelope, F&& l const auto length = min(events[i].delay, maxDelay) - lastDelay; if (difference < step) { - fill(envelope.subspan(lastDelay, length), lastValue); + fill(envelope.subspan(lastDelay, length), lastValue); lastValue = nextValue; lastDelay += length; continue; @@ -109,12 +109,12 @@ void linearEnvelope(const EventVector& events, absl::Span envelope, F&& l const auto numSteps = static_cast(difference / step); const auto stepLength = static_cast(length / numSteps); for (int i = 0; i < numSteps; ++i) { - fill(envelope.subspan(lastDelay, stepLength), lastValue); + fill(envelope.subspan(lastDelay, stepLength), lastValue); lastValue += lastValue <= nextValue ? step : -step; lastDelay += stepLength; } } - fill(envelope.subspan(lastDelay), lastValue); + fill(envelope.subspan(lastDelay), lastValue); } template @@ -137,7 +137,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop lastValue = nextValue; lastDelay += length; } - fill(envelope.subspan(lastDelay), lastValue); + fill(envelope.subspan(lastDelay), lastValue); } template @@ -170,7 +170,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue; if (difference < step) { - fill(envelope.subspan(lastDelay, length), lastValue); + fill(envelope.subspan(lastDelay, length), lastValue); lastValue = nextValue; lastDelay += length; continue; @@ -179,12 +179,12 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop const auto numSteps = std::round(std::log(difference) / logStep); const auto stepLength = static_cast(length / numSteps); for (int i = 0; i < static_cast(numSteps); ++i) { - fill(envelope.subspan(lastDelay, stepLength), lastValue); + fill(envelope.subspan(lastDelay, stepLength), lastValue); lastValue = nextValue > lastValue ? lastValue * step : lastValue / step; lastDelay += stepLength; } } - fill(envelope.subspan(lastDelay), lastValue); + fill(envelope.subspan(lastDelay), lastValue); } template diff --git a/src/sfizz/SIMDHelpers.h b/src/sfizz/SIMDHelpers.h index b8915297..d22ef484 100644 --- a/src/sfizz/SIMDHelpers.h +++ b/src/sfizz/SIMDHelpers.h @@ -151,15 +151,12 @@ inline void writeInterleaved(absl::Span inputLeft, absl::Span +template void fill(absl::Span output, T value) noexcept { absl::c_fill(output, value); } -template <> -void fill(absl::Span output, float value) noexcept; - /** * @brief Exp math function * diff --git a/src/sfizz/SIMDSSE.cpp b/src/sfizz/SIMDSSE.cpp index b0dcf2d9..3c9fdb8f 100644 --- a/src/sfizz/SIMDSSE.cpp +++ b/src/sfizz/SIMDSSE.cpp @@ -16,26 +16,6 @@ constexpr uintptr_t TypeAlignment = 4; -template <> -void sfz::fill(absl::Span output, float value) noexcept -{ - const auto mmValue = _mm_set_ps1(value); - auto* out = output.begin(); - const auto* lastAligned = prevAligned(output.end()); - - while (unaligned(out) && out < lastAligned) - *out++ = value; - - while (out < lastAligned) // we should only need to test a single channel - { - _mm_store_ps(out, mmValue); - out += TypeAlignment; - } - - while (out < output.end()) - *out++ = value; -} - template <> void sfz::exp(absl::Span input, absl::Span output) noexcept { diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 98509af6..adca60c1 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -358,7 +358,7 @@ void sfz::Voice::panStageMono(AudioSpan buffer) noexcept copy(leftBuffer, rightBuffer); // Apply panning - fill(*modulationSpan, region->pan); + fill(*modulationSpan, region->pan); for (const auto& mod : region->panCC) { linearModifier(resources, *tempSpan, mod, normalizePercents); add(*tempSpan, *modulationSpan); @@ -379,7 +379,7 @@ void sfz::Voice::panStageStereo(AudioSpan buffer) noexcept return; // Apply panning - fill(*modulationSpan, region->pan); + fill(*modulationSpan, region->pan); for (const auto& mod : region->panCC) { linearModifier(resources, *tempSpan, mod, normalizePercents); add(*tempSpan, *modulationSpan); @@ -387,14 +387,14 @@ void sfz::Voice::panStageStereo(AudioSpan buffer) noexcept pan(*modulationSpan, leftBuffer, rightBuffer); // Apply the width/position process - fill(*modulationSpan, region->width); + fill(*modulationSpan, region->width); for (const auto& mod : region->widthCC) { linearModifier(resources, *tempSpan, mod, normalizePercents); add(*tempSpan, *modulationSpan); } width(*modulationSpan, leftBuffer, rightBuffer); - fill(*modulationSpan, region->position); + fill(*modulationSpan, region->position); for (const auto& mod : region->positionCC) { linearModifier(resources, *tempSpan, mod, normalizePercents); add(*tempSpan, *modulationSpan); @@ -457,7 +457,7 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept if (!jumps || !bends || !indices || !coeffs) return; - fill(*jumps, pitchRatio * speedRatio); + fill(*jumps, pitchRatio * speedRatio); const auto events = resources.midiState.getPitchEvents(); const auto bendLambda = [this](float bend) { @@ -588,7 +588,7 @@ void sfz::Voice::fillWithGenerator(AudioSpan buffer) noexcept return; float keycenterFrequency = midiNoteFrequency(region->pitchKeycenter); - fill(*frequencies, pitchRatio * keycenterFrequency); + fill(*frequencies, pitchRatio * keycenterFrequency); const auto events = resources.midiState.getPitchEvents(); const auto bendLambda = [this](float bend) {