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