@@ -1,27 +1,27 @@ | |||||
#include "sse_mathfun.h" | #include "sse_mathfun.h" | ||||
#include <cstring> | #include <cstring> | ||||
#include <cmath> | #include <cmath> | ||||
#include <emmintrin.h> | |||||
#include <x86intrin.h> | |||||
namespace rack { | namespace rack { | ||||
namespace dsp { | namespace dsp { | ||||
/** Casts an int to float, bitwise without conversion. */ | |||||
inline float cast_i32_f32(int i) { | |||||
static_assert(sizeof(int) == sizeof(float), "int and float must be the same size"); | |||||
// Should be optimized to two `mov` instructions | |||||
float f; | |||||
std::memcpy(&f, &i, sizeof(f)); | |||||
return f; | |||||
} | |||||
/** Casts the literal bits of FROM to TO without type conversion. | |||||
API copied from C++20. | |||||
Usage example: | |||||
inline int cast_f32_i32(float f) { | |||||
float i; | |||||
std::memcpy(&i, &f, sizeof(i)); | |||||
return i; | |||||
printf("%08x\n", bit_cast<int>(1.f)); // Prints 3f800000 | |||||
*/ | |||||
template <typename TO, typename FROM> | |||||
TO bit_cast(const FROM &x) { | |||||
static_assert(sizeof(FROM) == sizeof(TO), "types must have equal size"); | |||||
// Should be optimized to two `mov` instructions | |||||
TO y; | |||||
std::memcpy(&y, &x, sizeof(x)); | |||||
return y; | |||||
} | } | ||||
@@ -30,6 +30,7 @@ inline int cast_f32_i32(float f) { | |||||
This class is designed to be used just like `float` scalars, with extra features for handling bitwise logic, conditions, loading, and storing. | This class is designed to be used just like `float` scalars, with extra features for handling bitwise logic, conditions, loading, and storing. | ||||
Usage example: | Usage example: | ||||
float a[4], b[4]; | float a[4], b[4]; | ||||
f32_4 a = f32_4::load(in); | f32_4 a = f32_4::load(in); | ||||
f32_4 b = 2.f * a / (1 - a); | f32_4 b = 2.f * a / (1 - a); | ||||
@@ -117,9 +118,11 @@ DECLARE_F32_4_OPERATOR_INFIX(operator/, _mm_div_ps) | |||||
/** | /** | ||||
Use these to apply logic, bit masks, and conditions to elements. | Use these to apply logic, bit masks, and conditions to elements. | ||||
Examples: | Examples: | ||||
Subtract 1 from value if greater than or equal to 1. | Subtract 1 from value if greater than or equal to 1. | ||||
x -= (x >= 1.f) & 1.f; | x -= (x >= 1.f) & 1.f; | ||||
*/ | */ | ||||
DECLARE_F32_4_OPERATOR_INFIX(operator^, _mm_xor_ps) | DECLARE_F32_4_OPERATOR_INFIX(operator^, _mm_xor_ps) | ||||
@@ -6,7 +6,7 @@ namespace rack { | |||||
namespace dsp { | namespace dsp { | ||||
/** Hann window function | |||||
/** Hann window function. | |||||
p: proportion from [0, 1], usually `i / (len - 1)` | p: proportion from [0, 1], usually `i / (len - 1)` | ||||
https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows | https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows | ||||
*/ | */ | ||||
@@ -14,14 +14,14 @@ inline float hann(float p) { | |||||
return 0.5f * (1.f - std::cos(2*M_PI * p)); | return 0.5f * (1.f - std::cos(2*M_PI * p)); | ||||
} | } | ||||
/** Applies the Hann window to a signal `x` */ | |||||
/** Applies the Hann window to a signal `x`. */ | |||||
inline void hannWindow(float *x, int len) { | inline void hannWindow(float *x, int len) { | ||||
for (int i = 0; i < len; i++) { | for (int i = 0; i < len; i++) { | ||||
x[i] *= hann((float) i / (len - 1)); | x[i] *= hann((float) i / (len - 1)); | ||||
} | } | ||||
} | } | ||||
/** Blackman window function | |||||
/** Blackman window function. | |||||
https://en.wikipedia.org/wiki/Window_function#Blackman_window | https://en.wikipedia.org/wiki/Window_function#Blackman_window | ||||
A typical alpha value is 0.16. | A typical alpha value is 0.16. | ||||
*/ | */ | ||||
@@ -39,7 +39,7 @@ inline void blackmanWindow(float alpha, float *x, int len) { | |||||
} | } | ||||
/** Blackman-Nuttall window function | |||||
/** Blackman-Nuttall window function. | |||||
https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window | https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window | ||||
*/ | */ | ||||
inline float blackmanNuttall(float p) { | inline float blackmanNuttall(float p) { | ||||
@@ -56,7 +56,7 @@ inline void blackmanNuttallWindow(float *x, int len) { | |||||
} | } | ||||
} | } | ||||
/** Blackman-Harris window function | |||||
/** Blackman-Harris window function. | |||||
https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window | https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window | ||||
*/ | */ | ||||
inline float blackmanHarris(float p) { | inline float blackmanHarris(float p) { | ||||
@@ -43,7 +43,7 @@ struct alignas(32) Port { | |||||
/** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */ | /** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */ | ||||
float getPolyVoltage(int channel) { | float getPolyVoltage(int channel) { | ||||
return (channels > 1) ? getVoltage(channel) : getVoltage(0); | |||||
return (channels == 1) ? getVoltage(0) : getVoltage(channel); | |||||
} | } | ||||
/** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */ | /** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */ | ||||
@@ -80,6 +80,7 @@ | |||||
#include "plugin/callbacks.hpp" | #include "plugin/callbacks.hpp" | ||||
#include "dsp/common.hpp" | #include "dsp/common.hpp" | ||||
#include "dsp/simd.hpp" | |||||
#include "dsp/digital.hpp" | #include "dsp/digital.hpp" | ||||
#include "dsp/fft.hpp" | #include "dsp/fft.hpp" | ||||
#include "dsp/filter.hpp" | #include "dsp/filter.hpp" | ||||