| @@ -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" | ||||