Resample one-coeff only

This commit is contained in:
Jean Pierre Cimalando 2020-05-15 17:58:28 +02:00
parent 420237e8dc
commit ff1cbb6c49
7 changed files with 43 additions and 55 deletions

View file

@ -22,8 +22,7 @@ public:
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 0, maxJump };
jumps = std::vector<int>(state.range(0));
leftCoeffs = std::vector<float>(state.range(0));
rightCoeffs = std::vector<float>(state.range(0));
coeffs = std::vector<float>(state.range(0));
floatJumps = std::vector<float>(state.range(0));
absl::c_generate(floatJumps, [&]() { return dist(gen); });
}
@ -33,8 +32,7 @@ public:
}
std::vector<int> jumps;
std::vector<float> leftCoeffs;
std::vector<float> rightCoeffs;
std::vector<float> coeffs;
std::vector<float> floatJumps;
};
@ -42,28 +40,28 @@ public:
BENCHMARK_DEFINE_F(InterpolationCast, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::sfzInterpolationCast<float, false>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs));
sfz::sfzInterpolationCast<float, false>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(coeffs));
}
}
BENCHMARK_DEFINE_F(InterpolationCast, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::sfzInterpolationCast<float, true>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs));
sfz::sfzInterpolationCast<float, true>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(coeffs));
}
}
BENCHMARK_DEFINE_F(InterpolationCast, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::sfzInterpolationCast<float, false>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1));
sfz::sfzInterpolationCast<float, false>(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<float, true>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1));
sfz::sfzInterpolationCast<float, true>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(coeffs).subspan(1));
}
}

View file

@ -156,9 +156,9 @@ inline CXX14_CONSTEXPR void incrementAll(T& first, Args&... rest)
}
template <class ValueType>
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<ValueType>(1.0) - coeff) + right * coeff;
}
template <class Type>

View file

@ -163,9 +163,9 @@ void sfz::cumsum<float, true>(absl::Span<const float> input, absl::Span<float> o
}
template<>
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> coeffs) noexcept
{
sfzInterpolationCast<float, false>(floatJumps, jumps, leftCoeffs, rightCoeffs);
sfzInterpolationCast<float, false>(floatJumps, jumps, coeffs);
}
template <>

View file

@ -939,12 +939,11 @@ void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output
namespace _internals {
template <class T>
void snippetSFZInterpolationCast(const T*& floatJump, int*& jump, T*& leftCoeff, T*& rightCoeff)
void snippetSFZInterpolationCast(const T*& floatJump, int*& jump, T*& coeff)
{
*jump = static_cast<int>(*floatJump);
*rightCoeff = *floatJump - static_cast<float>(*jump);
*leftCoeff = static_cast<T>(1.0) - *rightCoeff;
incrementAll(floatJump, leftCoeff, rightCoeff, jump);
*coeff = *floatJump - static_cast<float>(*jump);
incrementAll(floatJump, coeff, jump);
}
}
@ -960,24 +959,22 @@ namespace _internals {
* @param rightCoeffs the right interpolation coefficients
*/
template <class T, bool SIMD = SIMDConfig::sfzInterpolationCast>
void sfzInterpolationCast(absl::Span<const T> floatJumps, absl::Span<int> jumps, absl::Span<T> leftCoeffs, absl::Span<T> rightCoeffs) noexcept
void sfzInterpolationCast(absl::Span<const T> floatJumps, absl::Span<int> jumps, absl::Span<T> 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<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept;
void sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> coeffs) noexcept;
namespace _internals {
template <class T>

View file

@ -227,9 +227,9 @@ void sfz::cumsum<float, true>(absl::Span<const float> input, absl::Span<float> o
}
template<>
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> coeffs) noexcept
{
sfzInterpolationCast<float, false>(floatJumps, jumps, leftCoeffs, rightCoeffs);
sfzInterpolationCast<float, false>(floatJumps, jumps, coeffs);
}
template <>

View file

@ -786,37 +786,33 @@ void sfz::cumsum<float, true>(absl::Span<const float> input, absl::Span<float> o
}
template <>
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept
void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> coeffs) noexcept
{
sfz::sfzInterpolationCast<float, false>(floatJumps, jumps, leftCoeffs, rightCoeffs);
sfz::sfzInterpolationCast<float, false>(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<float*>(jump), leftCoeff, rightCoeff) && floatJump < lastAligned)
// _internals::snippetSFZInterpolationCast(floatJump, jump, leftCoeff, rightCoeff);
// while (unaligned(floatJump, reinterpret_cast<float*>(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<TypeAlignment>(floatJump, jump, leftCoeff, rightCoeff);
// auto mmCoeff = _mm_sub_ps(mmFloatJumps, _mm_cvtepi32_ps(mmIndices));
// _mm_store_ps(coeff, mmCoeff);
// incrementAll<TypeAlignment>(floatJump, jump, coeff);
// }
// while(floatJump < sentinel)
// _internals::snippetSFZInterpolationCast(floatJump, jump, leftCoeff, rightCoeff);
// _internals::snippetSFZInterpolationCast(floatJump, jump, coeff);
}
template <>

View file

@ -443,10 +443,9 @@ void sfz::Voice::fillWithData(AudioSpan<float> 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<float>(*jumps, pitchRatio * speedRatio);
@ -470,7 +469,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
jumps->front() += floatPositionOffset;
cumsum<float>(*jumps, *jumps);
sfzInterpolationCast<float>(*jumps, *indices, *leftCoeffs, *rightCoeffs);
sfzInterpolationCast<float>(*jumps, *indices, *coeffs);
add<int>(sourcePosition, *indices);
if (region->shouldLoop() && region->loopEnd(currentPromise->oversamplingFactor) <= source.getNumFrames()) {
@ -500,35 +499,33 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
#endif
egEnvelope.startRelease(i, true);
fill<int>(indices->subspan(i), sampleEnd);
fill<float>(leftCoeffs->subspan(i), 0.0f);
fill<float>(rightCoeffs->subspan(i), 1.0f);
fill<float>(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)));