Moved interpolators to their own file
This commit is contained in:
parent
626e92f1a3
commit
51502eaed3
4 changed files with 152 additions and 75 deletions
25
src/sfizz/Interpolators.h
Normal file
25
src/sfizz/Interpolators.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace sfz {
|
||||||
|
|
||||||
|
enum InterpolatorModel : int {
|
||||||
|
// a linear interpolator
|
||||||
|
kInterpolatorLinear,
|
||||||
|
// a Hermite 3rd order interpolator
|
||||||
|
kInterpolatorHermite3,
|
||||||
|
// a B-spline 3rd order interpolator
|
||||||
|
kInterpolatorBspline3,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <InterpolatorModel M, class R>
|
||||||
|
R interpolate(const R* values, R coeff);
|
||||||
|
|
||||||
|
} // namespace sfz
|
||||||
|
|
||||||
|
#include "Interpolators.hpp"
|
||||||
123
src/sfizz/Interpolators.hpp
Normal file
123
src/sfizz/Interpolators.hpp
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "Interpolators.h"
|
||||||
|
#include "MathHelpers.h"
|
||||||
|
#include "SIMDConfig.h"
|
||||||
|
|
||||||
|
namespace sfz {
|
||||||
|
|
||||||
|
template <InterpolatorModel M, class R>
|
||||||
|
class Interpolator;
|
||||||
|
|
||||||
|
template <InterpolatorModel M, class R>
|
||||||
|
inline R interpolate(const R* values, R coeff)
|
||||||
|
{
|
||||||
|
return Interpolator<M, R>::process(values, coeff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Linear
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class Interpolator<kInterpolatorLinear, R>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline R process(const R* values, R coeff)
|
||||||
|
{
|
||||||
|
return values[0] * (static_cast<R>(1.0) - coeff) + values[1] * coeff;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Hermite 3rd order, SSE specialization
|
||||||
|
|
||||||
|
#if SFIZZ_HAVE_SSE
|
||||||
|
template <>
|
||||||
|
class Interpolator<kInterpolatorHermite3, float>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline float process(const float* values, float coeff)
|
||||||
|
{
|
||||||
|
__m128 x = _mm_sub_ps(_mm_setr_ps(-1, 0, 1, 2), _mm_set1_ps(coeff));
|
||||||
|
__m128 h = hermite3x4(x);
|
||||||
|
__m128 y = _mm_mul_ps(h, _mm_loadu_ps(values));
|
||||||
|
// sum 4 to 1
|
||||||
|
__m128 xmm0 = y;
|
||||||
|
__m128 xmm1 = _mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
||||||
|
__m128 xmm2 = _mm_movehl_ps(xmm0, xmm0);
|
||||||
|
xmm1 = _mm_add_ss(xmm1, xmm0);
|
||||||
|
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
||||||
|
xmm2 = _mm_add_ss(xmm2, xmm1);
|
||||||
|
xmm0 = _mm_add_ss(xmm0, xmm2);
|
||||||
|
return _mm_cvtss_f32(xmm0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Hermite 3rd order, generic
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class Interpolator<kInterpolatorHermite3, R>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline R process(const R* values, R coeff)
|
||||||
|
{
|
||||||
|
R y = 0;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
R h = hermite3<R>(i - 1 - coeff);
|
||||||
|
y += h * values[i];
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// B-spline 3rd order, SSE specialization
|
||||||
|
|
||||||
|
#if SFIZZ_HAVE_SSE
|
||||||
|
template <>
|
||||||
|
class Interpolator<kInterpolatorBspline3, float>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline float process(const float* values, float coeff)
|
||||||
|
{
|
||||||
|
__m128 x = _mm_sub_ps(_mm_setr_ps(-1, 0, 1, 2), _mm_set1_ps(coeff));
|
||||||
|
__m128 h = bspline3x4(x);
|
||||||
|
__m128 y = _mm_mul_ps(h, _mm_loadu_ps(values));
|
||||||
|
// sum 4 to 1
|
||||||
|
__m128 xmm0 = y;
|
||||||
|
__m128 xmm1 = _mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
||||||
|
__m128 xmm2 = _mm_movehl_ps(xmm0, xmm0);
|
||||||
|
xmm1 = _mm_add_ss(xmm1, xmm0);
|
||||||
|
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
||||||
|
xmm2 = _mm_add_ss(xmm2, xmm1);
|
||||||
|
xmm0 = _mm_add_ss(xmm0, xmm2);
|
||||||
|
return _mm_cvtss_f32(xmm0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// B-spline 3rd order, generic
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class Interpolator<kInterpolatorBspline3, R>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline R process(const R* values, R coeff)
|
||||||
|
{
|
||||||
|
R y = 0;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
R h = bspline3<R>(i - 1 - coeff);
|
||||||
|
y += h * values[i];
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sfz
|
||||||
|
|
@ -159,12 +159,6 @@ inline CXX14_CONSTEXPR void incrementAll(T& first, Args&... rest)
|
||||||
incrementAll<Increment>(rest...);
|
incrementAll<Increment>(rest...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
constexpr ValueType linearInterpolation(const ValueType values[2], ValueType coeff)
|
|
||||||
{
|
|
||||||
return values[0] * (static_cast<ValueType>(1.0) - coeff) + values[1] * coeff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compute the 3rd-order Hermite interpolation polynomial.
|
* @brief Compute the 3rd-order Hermite interpolation polynomial.
|
||||||
*
|
*
|
||||||
|
|
@ -211,39 +205,6 @@ inline __m128 hermite3x4(__m128 x)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
ValueType hermite3Interpolation(const ValueType values[4], ValueType coeff);
|
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE
|
|
||||||
template <>
|
|
||||||
inline float hermite3Interpolation<float>(const float values[4], float coeff)
|
|
||||||
{
|
|
||||||
__m128 x = _mm_sub_ps(_mm_setr_ps(-1, 0, 1, 2), _mm_set1_ps(coeff));
|
|
||||||
__m128 h = hermite3x4(x);
|
|
||||||
__m128 y = _mm_mul_ps(h, _mm_loadu_ps(values));
|
|
||||||
// sum 4 to 1
|
|
||||||
__m128 xmm0 = y;
|
|
||||||
__m128 xmm1 = _mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
|
||||||
__m128 xmm2 = _mm_movehl_ps(xmm0, xmm0);
|
|
||||||
xmm1 = _mm_add_ss(xmm1, xmm0);
|
|
||||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
|
||||||
xmm2 = _mm_add_ss(xmm2, xmm1);
|
|
||||||
xmm0 = _mm_add_ss(xmm0, xmm2);
|
|
||||||
return _mm_cvtss_f32(xmm0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
ValueType hermite3Interpolation(const ValueType values[4], ValueType coeff)
|
|
||||||
{
|
|
||||||
ValueType y = 0;
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
ValueType h = hermite3<ValueType>(i - 1 - coeff);
|
|
||||||
y += h * values[i];
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compute the 3rd-order B-spline interpolation polynomial.
|
* @brief Compute the 3rd-order B-spline interpolation polynomial.
|
||||||
*
|
*
|
||||||
|
|
@ -288,39 +249,6 @@ inline __m128 bspline3x4(__m128 x)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
ValueType bspline3Interpolation(const ValueType values[4], ValueType coeff);
|
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE
|
|
||||||
template <>
|
|
||||||
inline float bspline3Interpolation<float>(const float values[4], float coeff)
|
|
||||||
{
|
|
||||||
__m128 x = _mm_sub_ps(_mm_setr_ps(-1, 0, 1, 2), _mm_set1_ps(coeff));
|
|
||||||
__m128 h = bspline3x4(x);
|
|
||||||
__m128 y = _mm_mul_ps(h, _mm_loadu_ps(values));
|
|
||||||
// sum 4 to 1
|
|
||||||
__m128 xmm0 = y;
|
|
||||||
__m128 xmm1 = _mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
|
||||||
__m128 xmm2 = _mm_movehl_ps(xmm0, xmm0);
|
|
||||||
xmm1 = _mm_add_ss(xmm1, xmm0);
|
|
||||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
|
||||||
xmm2 = _mm_add_ss(xmm2, xmm1);
|
|
||||||
xmm0 = _mm_add_ss(xmm0, xmm2);
|
|
||||||
return _mm_cvtss_f32(xmm0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
ValueType bspline3Interpolation(const ValueType values[4], ValueType coeff)
|
|
||||||
{
|
|
||||||
ValueType y = 0;
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
ValueType h = bspline3<ValueType>(i - 1 - coeff);
|
|
||||||
y += h * values[i];
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Type>
|
template <class Type>
|
||||||
constexpr Type pi() { return static_cast<Type>(3.141592653589793238462643383279502884); };
|
constexpr Type pi() { return static_cast<Type>(3.141592653589793238462643383279502884); };
|
||||||
template <class Type>
|
template <class Type>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "MathHelpers.h"
|
#include "MathHelpers.h"
|
||||||
#include "SIMDHelpers.h"
|
#include "SIMDHelpers.h"
|
||||||
#include "SfzHelpers.h"
|
#include "SfzHelpers.h"
|
||||||
|
#include "Interpolators.h"
|
||||||
#include "absl/algorithm/container.h"
|
#include "absl/algorithm/container.h"
|
||||||
|
|
||||||
sfz::Voice::Voice(sfz::Resources& resources)
|
sfz::Voice::Voice(sfz::Resources& resources)
|
||||||
|
|
@ -511,15 +512,15 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
|
||||||
auto left = buffer.getChannel(0);
|
auto left = buffer.getChannel(0);
|
||||||
if (source.getNumChannels() == 1) {
|
if (source.getNumChannels() == 1) {
|
||||||
while (ind < indices->end()) {
|
while (ind < indices->end()) {
|
||||||
*left = bspline3Interpolation(&leftSource[*ind], *coeff);
|
*left = interpolate<kInterpolatorBspline3>(&leftSource[*ind], *coeff);
|
||||||
incrementAll(ind, left, coeff);
|
incrementAll(ind, left, coeff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto right = buffer.getChannel(1);
|
auto right = buffer.getChannel(1);
|
||||||
auto rightSource = source.getConstSpan(1);
|
auto rightSource = source.getConstSpan(1);
|
||||||
while (ind < indices->end()) {
|
while (ind < indices->end()) {
|
||||||
*left = bspline3Interpolation(&leftSource[*ind], *coeff);
|
*left = interpolate<kInterpolatorBspline3>(&leftSource[*ind], *coeff);
|
||||||
*right = bspline3Interpolation(&rightSource[*ind], *coeff);
|
*right = interpolate<kInterpolatorBspline3>(&rightSource[*ind], *coeff);
|
||||||
incrementAll(ind, left, right, coeff);
|
incrementAll(ind, left, right, coeff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue