| @@ -134,8 +134,8 @@ inline float chop(float x, float epsilon = 1e-6f) { | |||
| return isNear(x, 0.f, epsilon) ? 0.f : x; | |||
| } | |||
| inline float rescale(float x, float a, float b, float yMin, float yMax) { | |||
| return yMin + (x - a) / (b - a) * (yMax - yMin); | |||
| inline float rescale(float x, float xMin, float xMax, float yMin, float yMax) { | |||
| return yMin + (x - xMin) / (xMax - xMin) * (yMax - yMin); | |||
| } | |||
| inline float crossfade(float a, float b, float p) { | |||
| @@ -80,7 +80,6 @@ | |||
| #include "plugin/callbacks.hpp" | |||
| #include "dsp/common.hpp" | |||
| #include "dsp/simd.hpp" | |||
| #include "dsp/digital.hpp" | |||
| #include "dsp/fft.hpp" | |||
| #include "dsp/filter.hpp" | |||
| @@ -93,6 +92,9 @@ | |||
| #include "dsp/vumeter.hpp" | |||
| #include "dsp/window.hpp" | |||
| #include "simd/vector.hpp" | |||
| #include "simd/functions.hpp" | |||
| namespace rack { | |||
| @@ -0,0 +1,145 @@ | |||
| #pragma once | |||
| #include "vector.hpp" | |||
| #include "sse_mathfun.h" | |||
| #include "math.hpp" | |||
| #include <cmath> | |||
| namespace rack { | |||
| namespace simd { | |||
| // Standard math functions from std:: | |||
| /* Import std:: math functions into the simd namespace so you can use `sin(T)` etc in templated functions and get both the scalar and vector versions. | |||
| Example: | |||
| template <typename T> | |||
| T sin_plus_cos(T x) { | |||
| using namespace simd; | |||
| return sin(x) + cos(x); | |||
| } | |||
| */ | |||
| using std::fmax; | |||
| inline f32_4 fmax(f32_4 x, f32_4 b) { | |||
| return f32_4(_mm_max_ps(x.v, b.v)); | |||
| } | |||
| using std::fmin; | |||
| inline f32_4 fmin(f32_4 x, f32_4 b) { | |||
| return f32_4(_mm_min_ps(x.v, b.v)); | |||
| } | |||
| using std::sqrt; | |||
| inline f32_4 sqrt(f32_4 x) { | |||
| return f32_4(_mm_sqrt_ps(x.v)); | |||
| } | |||
| using std::log; | |||
| inline f32_4 log(f32_4 x) { | |||
| return f32_4(sse_mathfun_log_ps(x.v)); | |||
| } | |||
| using std::exp; | |||
| inline f32_4 exp(f32_4 x) { | |||
| return f32_4(sse_mathfun_exp_ps(x.v)); | |||
| } | |||
| using std::sin; | |||
| inline f32_4 sin(f32_4 x) { | |||
| return f32_4(sse_mathfun_sin_ps(x.v)); | |||
| } | |||
| using std::cos; | |||
| inline f32_4 cos(f32_4 x) { | |||
| return f32_4(sse_mathfun_cos_ps(x.v)); | |||
| } | |||
| using std::floor; | |||
| inline f32_4 floor(f32_4 a) { | |||
| return f32_4(sse_mathfun_floor_ps(a.v)); | |||
| } | |||
| using std::ceil; | |||
| inline f32_4 ceil(f32_4 a) { | |||
| return f32_4(sse_mathfun_ceil_ps(a.v)); | |||
| } | |||
| using std::round; | |||
| inline f32_4 round(f32_4 a) { | |||
| return f32_4(sse_mathfun_round_ps(a.v)); | |||
| } | |||
| using std::fmod; | |||
| inline f32_4 fmod(f32_4 a, f32_4 b) { | |||
| return f32_4(sse_mathfun_fmod_ps(a.v, b.v)); | |||
| } | |||
| using std::fabs; | |||
| inline f32_4 fabs(f32_4 a) { | |||
| return f32_4(sse_mathfun_fabs_ps(a.v)); | |||
| } | |||
| using std::trunc; | |||
| inline f32_4 trunc(f32_4 a) { | |||
| return f32_4(sse_mathfun_trunc_ps(a.v)); | |||
| } | |||
| using std::pow; | |||
| inline f32_4 pow(f32_4 a, f32_4 b) { | |||
| return exp(b * log(a)); | |||
| } | |||
| inline f32_4 pow(float a, f32_4 b) { | |||
| return exp(b * std::log(a)); | |||
| } | |||
| // Nonstandard functions | |||
| /** Returns the approximate reciprocal square root. | |||
| Much faster than `1/sqrt(x)`. | |||
| */ | |||
| inline f32_4 rsqrt(f32_4 x) { | |||
| return f32_4(_mm_rsqrt_ps(x.v)); | |||
| } | |||
| /** Returns the approximate reciprocal. | |||
| Much faster than `1/x`. | |||
| */ | |||
| inline f32_4 rcp(f32_4 x) { | |||
| return f32_4(_mm_rcp_ps(x.v)); | |||
| } | |||
| // From math.hpp | |||
| using math::clamp; | |||
| inline f32_4 clamp(f32_4 x, f32_4 a, f32_4 b) { | |||
| return fmin(fmax(x, a), b); | |||
| } | |||
| using math::rescale; | |||
| inline f32_4 rescale(f32_4 x, f32_4 xMin, f32_4 xMax, f32_4 yMin, f32_4 yMax) { | |||
| return yMin + (x - xMin) / (xMax - xMin) * (yMax - yMin); | |||
| } | |||
| } // namespace simd | |||
| } // namespace rack | |||
| @@ -1,3 +1,4 @@ | |||
| #pragma once | |||
| /* Modified version of http://gruntthepeon.free.fr/ssemath/ for VCV Rack. | |||
| The following changes were made. | |||
| @@ -1,11 +1,10 @@ | |||
| #include "sse_mathfun.h" | |||
| #pragma once | |||
| #include <cstring> | |||
| #include <cmath> | |||
| #include <x86intrin.h> | |||
| #include <emmintrin.h> | |||
| namespace rack { | |||
| namespace dsp { | |||
| namespace simd { | |||
| /** Casts the literal bits of FROM to TO without type conversion. | |||
| @@ -176,83 +175,5 @@ DECLARE_F32_4_OPERATOR_INFIX(operator<, _mm_cmplt_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator!=, _mm_cmpneq_ps) | |||
| // Math functions | |||
| inline f32_4 fmax(f32_4 x, f32_4 b) { | |||
| return f32_4(_mm_max_ps(x.v, b.v)); | |||
| } | |||
| inline f32_4 fmin(f32_4 x, f32_4 b) { | |||
| return f32_4(_mm_min_ps(x.v, b.v)); | |||
| } | |||
| inline f32_4 sqrt(f32_4 x) { | |||
| return f32_4(_mm_sqrt_ps(x.v)); | |||
| } | |||
| /** Returns the approximate reciprocal square root. | |||
| Much faster than `1/sqrt(x)`. | |||
| */ | |||
| inline f32_4 rsqrt(f32_4 x) { | |||
| return f32_4(_mm_rsqrt_ps(x.v)); | |||
| } | |||
| /** Returns the approximate reciprocal. | |||
| Much faster than `1/x`. | |||
| */ | |||
| inline f32_4 rcp(f32_4 x) { | |||
| return f32_4(_mm_rcp_ps(x.v)); | |||
| } | |||
| inline f32_4 log(f32_4 x) { | |||
| return f32_4(sse_mathfun_log_ps(x.v)); | |||
| } | |||
| inline f32_4 exp(f32_4 x) { | |||
| return f32_4(sse_mathfun_exp_ps(x.v)); | |||
| } | |||
| inline f32_4 sin(f32_4 x) { | |||
| return f32_4(sse_mathfun_sin_ps(x.v)); | |||
| } | |||
| inline f32_4 cos(f32_4 x) { | |||
| return f32_4(sse_mathfun_cos_ps(x.v)); | |||
| } | |||
| inline f32_4 floor(f32_4 a) { | |||
| return f32_4(sse_mathfun_floor_ps(a.v)); | |||
| } | |||
| inline f32_4 ceil(f32_4 a) { | |||
| return f32_4(sse_mathfun_ceil_ps(a.v)); | |||
| } | |||
| inline f32_4 round(f32_4 a) { | |||
| return f32_4(sse_mathfun_round_ps(a.v)); | |||
| } | |||
| inline f32_4 fmod(f32_4 a, f32_4 b) { | |||
| return f32_4(sse_mathfun_fmod_ps(a.v, b.v)); | |||
| } | |||
| inline f32_4 fabs(f32_4 a) { | |||
| return f32_4(sse_mathfun_fabs_ps(a.v)); | |||
| } | |||
| inline f32_4 trunc(f32_4 a) { | |||
| return f32_4(sse_mathfun_trunc_ps(a.v)); | |||
| } | |||
| inline f32_4 pow(f32_4 a, f32_4 b) { | |||
| return exp(b * log(a)); | |||
| } | |||
| inline f32_4 pow(float a, f32_4 b) { | |||
| return exp(b * std::log(a)); | |||
| } | |||
| } // namespace dsp | |||
| } // namespace simd | |||
| } // namespace rack | |||