From ff1cbb6c4949ec9074c56513fc10ce7f9fd9dfd1 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 15 May 2020 17:58:28 +0200 Subject: [PATCH] Resample one-coeff only --- benchmarks/BM_interpolationCast.cpp | 14 ++++++-------- src/sfizz/MathHelpers.h | 4 ++-- src/sfizz/SIMDDummy.cpp | 4 ++-- src/sfizz/SIMDHelpers.h | 21 +++++++++------------ src/sfizz/SIMDNEON.cpp | 4 ++-- src/sfizz/SIMDSSE.cpp | 26 +++++++++++--------------- src/sfizz/Voice.cpp | 25 +++++++++++-------------- 7 files changed, 43 insertions(+), 55 deletions(-) diff --git a/benchmarks/BM_interpolationCast.cpp b/benchmarks/BM_interpolationCast.cpp index ea12845a..b3743530 100644 --- a/benchmarks/BM_interpolationCast.cpp +++ b/benchmarks/BM_interpolationCast.cpp @@ -22,8 +22,7 @@ public: std::mt19937 gen { rd() }; std::uniform_real_distribution dist { 0, maxJump }; jumps = std::vector(state.range(0)); - leftCoeffs = std::vector(state.range(0)); - rightCoeffs = std::vector(state.range(0)); + coeffs = std::vector(state.range(0)); floatJumps = std::vector(state.range(0)); absl::c_generate(floatJumps, [&]() { return dist(gen); }); } @@ -33,8 +32,7 @@ public: } std::vector jumps; - std::vector leftCoeffs; - std::vector rightCoeffs; + std::vector coeffs; std::vector floatJumps; }; @@ -42,28 +40,28 @@ public: BENCHMARK_DEFINE_F(InterpolationCast, Scalar)(benchmark::State& state) { for (auto _ : state) { - sfz::sfzInterpolationCast(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs)); + sfz::sfzInterpolationCast(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(coeffs)); } } BENCHMARK_DEFINE_F(InterpolationCast, SIMD)(benchmark::State& state) { for (auto _ : state) { - sfz::sfzInterpolationCast(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs)); + sfz::sfzInterpolationCast(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(coeffs)); } } BENCHMARK_DEFINE_F(InterpolationCast, Scalar_Unaligned)(benchmark::State& state) { for (auto _ : state) { - sfz::sfzInterpolationCast(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1)); + sfz::sfzInterpolationCast(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(coeffs).subspan(1)); } } BENCHMARK_DEFINE_F(InterpolationCast, SIMD_Unaligned)(benchmark::State& state) { for (auto _ : state) { - sfz::sfzInterpolationCast(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1)); + sfz::sfzInterpolationCast(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(coeffs).subspan(1)); } } diff --git a/src/sfizz/MathHelpers.h b/src/sfizz/MathHelpers.h index d8976c88..284d3580 100644 --- a/src/sfizz/MathHelpers.h +++ b/src/sfizz/MathHelpers.h @@ -156,9 +156,9 @@ inline CXX14_CONSTEXPR void incrementAll(T& first, Args&... rest) } template -constexpr ValueType linearInterpolation(ValueType left, ValueType right, ValueType leftCoeff, ValueType rightCoeff) +constexpr ValueType linearInterpolation(ValueType left, ValueType right, ValueType coeff) { - return left * leftCoeff + right * rightCoeff; + return left * (static_cast(1.0) - coeff) + right * coeff; } template diff --git a/src/sfizz/SIMDDummy.cpp b/src/sfizz/SIMDDummy.cpp index 2a0ca34d..718d8a1c 100644 --- a/src/sfizz/SIMDDummy.cpp +++ b/src/sfizz/SIMDDummy.cpp @@ -163,9 +163,9 @@ void sfz::cumsum(absl::Span input, absl::Span o } template<> -void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span leftCoeffs, absl::Span rightCoeffs) noexcept +void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept { - sfzInterpolationCast(floatJumps, jumps, leftCoeffs, rightCoeffs); + sfzInterpolationCast(floatJumps, jumps, coeffs); } template <> diff --git a/src/sfizz/SIMDHelpers.h b/src/sfizz/SIMDHelpers.h index 7773b794..0600ddd6 100644 --- a/src/sfizz/SIMDHelpers.h +++ b/src/sfizz/SIMDHelpers.h @@ -939,12 +939,11 @@ void cumsum(absl::Span input, absl::Span output namespace _internals { template - void snippetSFZInterpolationCast(const T*& floatJump, int*& jump, T*& leftCoeff, T*& rightCoeff) + void snippetSFZInterpolationCast(const T*& floatJump, int*& jump, T*& coeff) { *jump = static_cast(*floatJump); - *rightCoeff = *floatJump - static_cast(*jump); - *leftCoeff = static_cast(1.0) - *rightCoeff; - incrementAll(floatJump, leftCoeff, rightCoeff, jump); + *coeff = *floatJump - static_cast(*jump); + incrementAll(floatJump, coeff, jump); } } @@ -960,24 +959,22 @@ namespace _internals { * @param rightCoeffs the right interpolation coefficients */ template -void sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span leftCoeffs, absl::Span rightCoeffs) noexcept +void sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept { CHECK(jumps.size() >= floatJumps.size()); - CHECK(jumps.size() == leftCoeffs.size()); - CHECK(jumps.size() == rightCoeffs.size()); + CHECK(jumps.size() == coeffs.size()); auto floatJump = floatJumps.data(); auto jump = jumps.data(); - auto leftCoeff = leftCoeffs.data(); - auto rightCoeff = rightCoeffs.data(); - const auto sentinel = floatJump + min(floatJumps.size(), jumps.size(), leftCoeffs.size(), rightCoeffs.size()); + auto coeff = coeffs.data(); + const auto sentinel = floatJump + min(floatJumps.size(), jumps.size(), coeffs.size()); while (floatJump < sentinel) - _internals::snippetSFZInterpolationCast(floatJump, jump, leftCoeff, rightCoeff); + _internals::snippetSFZInterpolationCast(floatJump, jump, coeff); } template <> -void sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span leftCoeffs, absl::Span rightCoeffs) noexcept; +void sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept; namespace _internals { template diff --git a/src/sfizz/SIMDNEON.cpp b/src/sfizz/SIMDNEON.cpp index 6a6dc8d1..e229d954 100644 --- a/src/sfizz/SIMDNEON.cpp +++ b/src/sfizz/SIMDNEON.cpp @@ -227,9 +227,9 @@ void sfz::cumsum(absl::Span input, absl::Span o } template<> -void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span leftCoeffs, absl::Span rightCoeffs) noexcept +void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept { - sfzInterpolationCast(floatJumps, jumps, leftCoeffs, rightCoeffs); + sfzInterpolationCast(floatJumps, jumps, coeffs); } template <> diff --git a/src/sfizz/SIMDSSE.cpp b/src/sfizz/SIMDSSE.cpp index 062d5476..ae0cd07e 100644 --- a/src/sfizz/SIMDSSE.cpp +++ b/src/sfizz/SIMDSSE.cpp @@ -786,37 +786,33 @@ void sfz::cumsum(absl::Span input, absl::Span o } template <> -void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span leftCoeffs, absl::Span rightCoeffs) noexcept +void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept { - sfz::sfzInterpolationCast(floatJumps, jumps, leftCoeffs, rightCoeffs); + sfz::sfzInterpolationCast(floatJumps, jumps, coeffs); // CHECK(jumps.size() >= floatJumps.size()); - // CHECK(jumps.size() == leftCoeffs.size()); - // CHECK(jumps.size() == rightCoeffs.size()); + // CHECK(jumps.size() == coeffs.size()); // auto floatJump = floatJumps.data(); // auto jump = jumps.data(); - // auto leftCoeff = leftCoeffs.data(); - // auto rightCoeff = rightCoeffs.data(); - // const auto sentinel = floatJump + min(floatJumps.size(), jumps.size(), leftCoeffs.size(), rightCoeffs.size()); + // auto coeff = coeffs.data(); + // const auto sentinel = floatJump + min(floatJumps.size(), jumps.size(), coeffs.size()); // const auto lastAligned = prevAligned(sentinel); - // while (unaligned(floatJump, reinterpret_cast(jump), leftCoeff, rightCoeff) && floatJump < lastAligned) - // _internals::snippetSFZInterpolationCast(floatJump, jump, leftCoeff, rightCoeff); + // while (unaligned(floatJump, reinterpret_cast(jump), coeff) && floatJump < lastAligned) + // _internals::snippetSFZInterpolationCast(floatJump, jump, coeff); // while (floatJump < lastAligned) { // auto mmFloatJumps = _mm_load_ps(floatJump); // auto mmIndices = _mm_cvtps_epi32(_mm_sub_ps(mmFloatJumps, _mm_set_ps1(0.4999999552965164184570312f))); // _mm_store_si128(reinterpret_cast<__m128i*>(jump), mmIndices); - // auto mmRight = _mm_sub_ps(mmFloatJumps, _mm_cvtepi32_ps(mmIndices)); - // auto mmLeft = _mm_sub_ps(_mm_set_ps1(1.0f), mmRight); - // _mm_store_ps(leftCoeff, mmLeft); - // _mm_store_ps(rightCoeff, mmRight); - // incrementAll(floatJump, jump, leftCoeff, rightCoeff); + // auto mmCoeff = _mm_sub_ps(mmFloatJumps, _mm_cvtepi32_ps(mmIndices)); + // _mm_store_ps(coeff, mmCoeff); + // incrementAll(floatJump, jump, coeff); // } // while(floatJump < sentinel) - // _internals::snippetSFZInterpolationCast(floatJump, jump, leftCoeff, rightCoeff); + // _internals::snippetSFZInterpolationCast(floatJump, jump, coeff); } template <> diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 3c4bc442..b35f3e43 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -443,10 +443,9 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept auto jumps = resources.bufferPool.getBuffer(numSamples); auto bends = resources.bufferPool.getBuffer(numSamples); - auto leftCoeffs = resources.bufferPool.getBuffer(numSamples); - auto rightCoeffs = resources.bufferPool.getBuffer(numSamples); + auto coeffs = resources.bufferPool.getBuffer(numSamples); auto indices = resources.bufferPool.getIndexBuffer(numSamples); - if (!jumps || !bends || !indices || !rightCoeffs || !leftCoeffs) + if (!jumps || !bends || !indices || !coeffs) return; fill(*jumps, pitchRatio * speedRatio); @@ -470,7 +469,7 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept jumps->front() += floatPositionOffset; cumsum(*jumps, *jumps); - sfzInterpolationCast(*jumps, *indices, *leftCoeffs, *rightCoeffs); + sfzInterpolationCast(*jumps, *indices, *coeffs); add(sourcePosition, *indices); if (region->shouldLoop() && region->loopEnd(currentPromise->oversamplingFactor) <= source.getNumFrames()) { @@ -500,35 +499,33 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept #endif egEnvelope.startRelease(i, true); fill(indices->subspan(i), sampleEnd); - fill(leftCoeffs->subspan(i), 0.0f); - fill(rightCoeffs->subspan(i), 1.0f); + fill(coeffs->subspan(i), 1.0f); break; } } } auto ind = indices->data(); - auto leftCoeff = leftCoeffs->data(); - auto rightCoeff = rightCoeffs->data(); + auto coeff = coeffs->data(); auto leftSource = source.getConstSpan(0); auto left = buffer.getChannel(0); if (source.getNumChannels() == 1) { while (ind < indices->end()) { - *left = linearInterpolation(leftSource[*ind], leftSource[*ind + 1], *leftCoeff, *rightCoeff); - incrementAll(ind, left, leftCoeff, rightCoeff); + *left = linearInterpolation(leftSource[*ind], leftSource[*ind + 1], *coeff); + incrementAll(ind, left, coeff); } } else { auto right = buffer.getChannel(1); auto rightSource = source.getConstSpan(1); while (ind < indices->end()) { - *left = linearInterpolation(leftSource[*ind], leftSource[*ind + 1], *leftCoeff, *rightCoeff); - *right = linearInterpolation(rightSource[*ind], rightSource[*ind + 1], *leftCoeff, *rightCoeff); - incrementAll(ind, left, right, leftCoeff, rightCoeff); + *left = linearInterpolation(leftSource[*ind], leftSource[*ind + 1], *coeff); + *right = linearInterpolation(rightSource[*ind], rightSource[*ind + 1], *coeff); + incrementAll(ind, left, right, coeff); } } sourcePosition = indices->back(); - floatPositionOffset = rightCoeffs->back(); + floatPositionOffset = coeffs->back(); #if 0 ASSERT(!hasNanInf(buffer.getConstSpan(0)));