Interpolators with simde
This commit is contained in:
parent
a338ec7368
commit
d7b9dc2285
4 changed files with 68 additions and 60 deletions
|
|
@ -252,7 +252,7 @@ add_library(sfizz::internal ALIAS sfizz_internal)
|
|||
target_sources(sfizz_internal PRIVATE ${SFIZZ_HEADERS} ${SFIZZ_SOURCES} ${FAUST_FILES})
|
||||
target_include_directories(sfizz_internal PUBLIC "." "sfizz")
|
||||
target_link_libraries(sfizz_internal
|
||||
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex
|
||||
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex sfizz::simde
|
||||
PRIVATE sfizz::parser sfizz::messaging absl::flat_hash_map Threads::Threads st_audiofile sfizz::pugixml sfizz::spline sfizz::tunings sfizz::hiir sfizz::kissfft sfizz::cephes sfizz::cpuid sfizz::threadpool sfizz::jsl sfizz::atomic)
|
||||
if(SFIZZ_USE_SNDFILE)
|
||||
target_compile_definitions(sfizz_internal PUBLIC "SFIZZ_USE_SNDFILE=1")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
#include "WindowedSinc.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "SIMDConfig.h"
|
||||
#include <simde/simde-features.h>
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
#include <simde/x86/sse.h>
|
||||
#endif
|
||||
|
||||
namespace sfz {
|
||||
|
||||
|
|
@ -49,25 +53,25 @@ public:
|
|||
//------------------------------------------------------------------------------
|
||||
// Hermite 3rd order, SSE specialization
|
||||
|
||||
#if SFIZZ_HAVE_SSE
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
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 - 1));
|
||||
simde__m128 x = simde_mm_sub_ps(simde_mm_setr_ps(-1, 0, 1, 2), simde_mm_set1_ps(coeff));
|
||||
simde__m128 h = hermite3x4(x);
|
||||
simde__m128 y = simde_mm_mul_ps(h, simde_mm_loadu_ps(values - 1));
|
||||
// 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);
|
||||
simde__m128 xmm0 = y;
|
||||
simde__m128 xmm1 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
||||
simde__m128 xmm2 = simde_mm_movehl_ps(xmm0, xmm0);
|
||||
xmm1 = simde_mm_add_ss(xmm1, xmm0);
|
||||
xmm0 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
||||
xmm2 = simde_mm_add_ss(xmm2, xmm1);
|
||||
xmm0 = simde_mm_add_ss(xmm0, xmm2);
|
||||
return simde_mm_cvtss_f32(xmm0);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
@ -93,25 +97,25 @@ public:
|
|||
//------------------------------------------------------------------------------
|
||||
// B-spline 3rd order, SSE specialization
|
||||
|
||||
#if SFIZZ_HAVE_SSE
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
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 - 1));
|
||||
simde__m128 x = simde_mm_sub_ps(simde_mm_setr_ps(-1, 0, 1, 2), simde_mm_set1_ps(coeff));
|
||||
simde__m128 h = bspline3x4(x);
|
||||
simde__m128 y = simde_mm_mul_ps(h, simde_mm_loadu_ps(values - 1));
|
||||
// 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);
|
||||
simde__m128 xmm0 = y;
|
||||
simde__m128 xmm1 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
||||
simde__m128 xmm2 = simde_mm_movehl_ps(xmm0, xmm0);
|
||||
xmm1 = simde_mm_add_ss(xmm1, xmm0);
|
||||
xmm0 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
||||
xmm2 = simde_mm_add_ss(xmm2, xmm1);
|
||||
xmm0 = simde_mm_add_ss(xmm0, xmm2);
|
||||
return simde_mm_cvtss_f32(xmm0);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
@ -190,7 +194,7 @@ class SincInterpolator;
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
// Windowed sinc any order, SSE specialization
|
||||
#if SFIZZ_HAVE_SSE2
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
template <size_t Points>
|
||||
class SincInterpolator<float, Points>
|
||||
{
|
||||
|
|
@ -204,25 +208,25 @@ public:
|
|||
constexpr int j0 = 1 - int(Points) / 2;
|
||||
float x0 = j0 - coeff;
|
||||
|
||||
__m128 y = _mm_set1_ps(0.0f);
|
||||
__m128 x = _mm_add_ps(_mm_set1_ps(x0), _mm_setr_ps(0, 1, 2, 3));
|
||||
simde__m128 y = simde_mm_set1_ps(0.0f);
|
||||
simde__m128 x = simde_mm_add_ps(simde_mm_set1_ps(x0), simde_mm_setr_ps(0, 1, 2, 3));
|
||||
size_t i = 0;
|
||||
do {
|
||||
__m128 h = ws.getUncheckedX4(x);
|
||||
y = _mm_add_ps(y, _mm_mul_ps(h, _mm_loadu_ps(&values[j0 + i])));
|
||||
x = _mm_add_ps(x, _mm_set1_ps(4.0f));
|
||||
simde__m128 h = ws.getUncheckedX4(x);
|
||||
y = simde_mm_add_ps(y, simde_mm_mul_ps(h, simde_mm_loadu_ps(&values[j0 + i])));
|
||||
x = simde_mm_add_ps(x, simde_mm_set1_ps(4.0f));
|
||||
i += 4;
|
||||
} while (i < Points);
|
||||
|
||||
// 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);
|
||||
simde__m128 xmm0 = y;
|
||||
simde__m128 xmm1 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe5);
|
||||
simde__m128 xmm2 = simde_mm_movehl_ps(xmm0, xmm0);
|
||||
xmm1 = simde_mm_add_ss(xmm1, xmm0);
|
||||
xmm0 = simde_mm_shuffle_ps(xmm0, xmm0, 0xe7);
|
||||
xmm2 = simde_mm_add_ss(xmm2, xmm1);
|
||||
xmm0 = simde_mm_add_ss(xmm0, xmm2);
|
||||
return simde_mm_cvtss_f32(xmm0);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
#include "SIMDConfig.h"
|
||||
#include <absl/types/span.h>
|
||||
#include <memory>
|
||||
#if SFIZZ_HAVE_SSE2
|
||||
#include <xmmintrin.h>
|
||||
#include <simde/simde-features.h>
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
#include <simde/x86/sse.h>
|
||||
#endif
|
||||
|
||||
namespace sfz {
|
||||
|
|
@ -30,9 +31,9 @@ public:
|
|||
// interpolate f(x), where x must be in domain [-Points/2:+Points/2]
|
||||
float getUnchecked(float x) const noexcept;
|
||||
|
||||
#if SFIZZ_HAVE_SSE2
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
// interpolate f(x), 4 values at once
|
||||
__m128 getUncheckedX4(__m128 x) const noexcept;
|
||||
simde__m128 getUncheckedX4(simde__m128 x) const noexcept;
|
||||
#endif
|
||||
|
||||
// calculate exact f(x), where x must be in domain [-Points/2:+Points/2]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
#pragma once
|
||||
#include "WindowedSinc.h"
|
||||
#include <cstdint>
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
#include <simde/x86/sse2.h>
|
||||
#endif
|
||||
|
||||
namespace sfz {
|
||||
|
||||
|
|
@ -36,33 +39,33 @@ inline float AbstractWindowedSinc<T>::getUnchecked(float x) const noexcept
|
|||
return y0 + mu * dy;
|
||||
}
|
||||
|
||||
#if SFIZZ_HAVE_SSE2
|
||||
#if SIMDE_NATURAL_VECTOR_SIZE_GE(128)
|
||||
template <class T>
|
||||
inline __m128 AbstractWindowedSinc<T>::getUncheckedX4(__m128 x) const noexcept
|
||||
inline simde__m128 AbstractWindowedSinc<T>::getUncheckedX4(simde__m128 x) const noexcept
|
||||
{
|
||||
const float* table = static_cast<const T*>(this)->getTablePointer();
|
||||
size_t points = static_cast<const T*>(this)->getNumPoints();
|
||||
size_t tableSize = static_cast<const T*>(this)->getTableSize();
|
||||
|
||||
__m128 ix = _mm_mul_ps(
|
||||
_mm_add_ps(x, _mm_set1_ps(points / 2.0f)),
|
||||
_mm_set1_ps((tableSize - 1) / points));
|
||||
alignas(__m128i) int j0[4];
|
||||
__m128i i0 = _mm_cvttps_epi32(ix);
|
||||
_mm_store_si128((__m128i*)j0, i0);
|
||||
__m128 mu = _mm_sub_ps(ix, _mm_cvtepi32_ps(i0));
|
||||
simde__m128 ix = simde_mm_mul_ps(
|
||||
simde_mm_add_ps(x, simde_mm_set1_ps(points / 2.0f)),
|
||||
simde_mm_set1_ps((tableSize - 1) / points));
|
||||
alignas(simde__m128i) int j0[4];
|
||||
simde__m128i i0 = simde_mm_cvttps_epi32(ix);
|
||||
simde_mm_store_si128((simde__m128i*)j0, i0);
|
||||
simde__m128 mu = simde_mm_sub_ps(ix, simde_mm_cvtepi32_ps(i0));
|
||||
|
||||
// reference: Interpolated table lookups using SSE2 [2/2]
|
||||
// https://rawstudio.org/blog/?p=482
|
||||
__m128 p0p1 = _mm_castsi128_ps(_mm_loadl_epi64((__m128i*)&table[j0[0]]));
|
||||
__m128 p2p3 = _mm_castsi128_ps(_mm_loadl_epi64((__m128i*)&table[j0[2]]));
|
||||
p0p1 = _mm_loadh_pi(p0p1, (__m64*)&table[j0[1]]);
|
||||
p2p3 = _mm_loadh_pi(p2p3, (__m64*)&table[j0[3]]);
|
||||
__m128 y0 = _mm_shuffle_ps(p0p1, p2p3, _MM_SHUFFLE(2, 0, 2, 0));
|
||||
__m128 y1 = _mm_shuffle_ps(p0p1, p2p3, _MM_SHUFFLE(3, 1, 3, 1));
|
||||
simde__m128 p0p1 = simde_mm_castsi128_ps(simde_mm_loadl_epi64((simde__m128i*)&table[j0[0]]));
|
||||
simde__m128 p2p3 = simde_mm_castsi128_ps(simde_mm_loadl_epi64((simde__m128i*)&table[j0[2]]));
|
||||
p0p1 = simde_mm_loadh_pi(p0p1, (simde__m64*)&table[j0[1]]);
|
||||
p2p3 = simde_mm_loadh_pi(p2p3, (simde__m64*)&table[j0[3]]);
|
||||
simde__m128 y0 = simde_mm_shuffle_ps(p0p1, p2p3, SIMDE_MM_SHUFFLE(2, 0, 2, 0));
|
||||
simde__m128 y1 = simde_mm_shuffle_ps(p0p1, p2p3, SIMDE_MM_SHUFFLE(3, 1, 3, 1));
|
||||
|
||||
__m128 dy = _mm_sub_ps(y1, y0);
|
||||
return _mm_add_ps(y0, _mm_mul_ps(mu, dy));
|
||||
simde__m128 dy = simde_mm_sub_ps(y1, y0);
|
||||
return simde_mm_add_ps(y0, simde_mm_mul_ps(mu, dy));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue