Changed the width helpers ; need SIMD version still

This commit is contained in:
Paul Fd 2020-02-10 21:23:30 +01:00
parent 90d680f0c3
commit 754a7f8be7
3 changed files with 32 additions and 79 deletions

View file

@ -54,67 +54,16 @@ public:
}; };
BENCHMARK_DEFINE_F(WidthPosArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(WidthPosArray, Scalar)(benchmark::State& state) {
ScopedFTZ ftz;
for (auto _ : state)
{
auto widthPtr = width.data();
auto posPtr = position.data();
auto leftPtr = left.data();
auto rightPtr = right.data();
const auto sentinel = width.data() + width.size();
while(widthPtr < sentinel)
{
auto mid = (*leftPtr + *rightPtr) * sqrtTwoInv<float>;
auto side = (*leftPtr - *rightPtr) * sqrtTwoInv<float>;
sfz::_internals::snippetWidth(*widthPtr, mid, side);
auto midRight = mid;
sfz::_internals::snippetPan(*posPtr, mid, midRight);
*leftPtr = (mid + side) * sqrtTwoInv<float>;
*rightPtr = (midRight - side) * sqrtTwoInv<float>;
incrementAll(leftPtr, rightPtr, widthPtr, posPtr);
}
}
}
BENCHMARK_DEFINE_F(WidthPosArray, BlockOps)(benchmark::State& state) {
ScopedFTZ ftz; ScopedFTZ ftz;
const auto leftBuffer = absl::MakeSpan(left); const auto leftBuffer = absl::MakeSpan(left);
const auto rightBuffer = absl::MakeSpan(right); const auto rightBuffer = absl::MakeSpan(right);
for (auto _ : state) for (auto _ : state)
{ {
const auto leftBufferCopy = span2; sfz::width<float, false>(width, leftBuffer, rightBuffer);
sfz::copy<float>(left, leftBufferCopy); sfz::pan<float, false>(position, leftBuffer, rightBuffer);
const auto midBuffer = leftBuffer;
sfz::add<float>(rightBuffer, midBuffer);
const auto sideBuffer = rightBuffer;
sfz::applyGain<float>(-1.0f, sideBuffer);
sfz::add<float>(leftBufferCopy, sideBuffer);
sfz::applyGain<float>(sqrtTwoInv<float>, midBuffer);
sfz::applyGain<float>(sqrtTwoInv<float>, sideBuffer);
// Apply the width process
sfz::width<float>(width, midBuffer, sideBuffer);
// Copy the mid channel into another span
const auto midBufferCopy = span3;
sfz::copy<float>(midBuffer, midBufferCopy);
sfz::pan<float>(position, midBuffer, midBufferCopy);
// Rebuild left/right
// Recall that midBuffer and leftBuffer point to the same buffer
sfz::add<float>(sideBuffer, leftBuffer);
sfz::applyGain(sqrtTwoInv<float>, leftBuffer);
// Recall that sideBuffer and rightBuffer point to the same buffer
sfz::applyGain<float>(-1.0f, sideBuffer);
sfz::add<float>(midBufferCopy, sideBuffer);
sfz::applyGain(sqrtTwoInv<float>, rightBuffer);
} }
} }
BENCHMARK_REGISTER_F(WidthPosArray, Scalar)->RangeMultiplier(4)->Range(1 << 2, 1 << 12); BENCHMARK_REGISTER_F(WidthPosArray, Scalar)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
BENCHMARK_REGISTER_F(WidthPosArray, BlockOps)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
BENCHMARK_MAIN(); BENCHMARK_MAIN();

View file

@ -760,12 +760,16 @@ namespace _internals {
} }
template <class T> template <class T>
inline void snippetWidth(const T& width, T& mid, T& side) inline void snippetWidth(T width, T& left, T& right)
{ {
T w = std::abs(width) * T{0.5}; T w = (width + T{1.0}) * T{0.5};
w = clamp<T>(w, 0, 1); w = clamp<T>(w, 0, 1);
mid *= panLookup(w); const auto coeff1 = panLookup(w);
side *= width > 0 ? panLookup(1 - w) : -panLookup(1 - w); const auto coeff2 = panLookup(1 - w);
const auto l = left;
const auto r = right;
left = l * coeff2 + r * coeff1;
right = l * coeff1 + r * coeff2;
} }
} }
@ -799,17 +803,17 @@ template <>
void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept; void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept;
template <class T, bool SIMD = SIMDConfig::pan> template <class T, bool SIMD = SIMDConfig::pan>
void width(absl::Span<const T> widthEnvelope, absl::Span<T> midBuffer, absl::Span<T> sideBuffer) noexcept void width(absl::Span<const T> widthEnvelope, absl::Span<T> leftBuffer, absl::Span<T> rightBuffer) noexcept
{ {
ASSERT(midBuffer.size() >= widthEnvelope.size()); ASSERT(leftBuffer.size() >= widthEnvelope.size());
ASSERT(sideBuffer.size() >= widthEnvelope.size()); ASSERT(rightBuffer.size() >= widthEnvelope.size());
auto* width = widthEnvelope.begin(); auto* width = widthEnvelope.begin();
auto* mid = midBuffer.begin(); auto* left = leftBuffer.begin();
auto* side = sideBuffer.begin(); auto* right = rightBuffer.begin();
auto* sentinel = width + min(widthEnvelope.size(), midBuffer.size(), sideBuffer.size()); auto* sentinel = width + min(widthEnvelope.size(), leftBuffer.size(), rightBuffer.size());
while (width < sentinel) { while (width < sentinel) {
_internals::snippetWidth(*width, *mid, *side); _internals::snippetWidth(*width, *left, *right);
incrementAll(width, mid, side); incrementAll(width, left, right);
} }
} }

View file

@ -788,29 +788,29 @@ TEST_CASE("[Helpers] Pan Scalar")
TEST_CASE("[Helpers] Width Scalar") TEST_CASE("[Helpers] Width Scalar")
{ {
std::array<float, 1> midValue { 1.0f }; std::array<float, 1> leftValue { 1.0f };
std::array<float, 1> sideValue { 1.0f }; std::array<float, 1> rightValue { 1.0f };
auto mid = absl::MakeSpan(midValue); auto left = absl::MakeSpan(leftValue);
auto side = absl::MakeSpan(sideValue); auto right = absl::MakeSpan(rightValue);
SECTION("width = 1") SECTION("width = 1")
{ {
std::array<float, 1> width { 1.0f }; std::array<float, 1> width { 1.0f };
sfz::width<float, false>(width, mid, side); sfz::width<float, false>(width, left, right);
REQUIRE(mid[0] == Approx(0.70711f).margin(0.001f)); REQUIRE(left[0] == Approx(1.0f).margin(0.001f));
REQUIRE(side[0] == Approx(0.70711f).margin(0.001f)); REQUIRE(right[0] == Approx(1.0f).margin(0.001f));
} }
SECTION("width = 0") SECTION("width = 0")
{ {
std::array<float, 1> width { 0.0f }; std::array<float, 1> width { 0.0f };
sfz::width<float, false>(width, mid, side); sfz::width<float, false>(width, left, right);
REQUIRE(mid[0] == Approx(1.0f).margin(0.001f)); REQUIRE(left[0] == Approx(1.414f).margin(0.001f));
REQUIRE(side[0] == Approx(0.0f).margin(0.001f)); REQUIRE(right[0] == Approx(1.414f).margin(0.001f));
} }
SECTION("width = -1") SECTION("width = -1")
{ {
std::array<float, 1> width { -1.0f }; std::array<float, 1> width { -1.0f };
sfz::width<float, false>(width, mid, side); sfz::width<float, false>(width, left, right);
REQUIRE(mid[0] == Approx(0.70711f).margin(0.001f)); REQUIRE(left[0] == Approx(1.0f).margin(0.001f));
REQUIRE(side[0] == Approx(-0.70711f).margin(0.001f)); REQUIRE(right[0] == Approx(1.0f).margin(0.001f));
} }
} }