From e2b74d736c7b681865f29d96036534e27d5278d5 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sat, 6 Jun 2015 16:45:09 -0700 Subject: [PATCH] rework crap_tube to use templates i'm so sorry --- Makefile | 3 +- crap/tube.hpp | 37 ++++++++-------- include/Dumber.hpp | 86 ++++++++++++++++++++++++++++++++++++ include/os2piir_stereo.hpp | 89 +++++++++++++++++++------------------- include/util.hpp | 32 ++++++-------- include/vectors.hpp | 56 ++++++++++++++++++++++++ 6 files changed, 219 insertions(+), 84 deletions(-) create mode 100644 include/Dumber.hpp create mode 100644 include/vectors.hpp diff --git a/Makefile b/Makefile index b3cfe85..b41fa7e 100644 --- a/Makefile +++ b/Makefile @@ -34,8 +34,7 @@ VST_SRC = ${VST_CPP:%=$(VST_CPP_DIR)/%} VST_OBJ = ${VST_CPP:%.cpp=$(BIN)/%.o} VST_DEF = $(VST_SDK_DIR)/public.sdk/samples/vst2.x/win/vstplug.def -INLINE_FLAGS = -Winline -GENERAL_FLAGS = -Wall -Wno-unused-function -Wno-sign-compare -I include $(INLINE_FLAGS) +GENERAL_FLAGS = -Wall -Winline -Wno-unused-function -Wno-sign-compare -I include ALL_CXXFLAGS = $(GENERAL_FLAGS) -std=gnu++11 $(CXXFLAGS) ALL_LDFLAGS = -lm $(LDFLAGS) diff --git a/crap/tube.hpp b/crap/tube.hpp index d9594f8..b7f7fcc 100644 --- a/crap/tube.hpp +++ b/crap/tube.hpp @@ -22,7 +22,7 @@ typedef struct { } smoothval; typedef struct { - halfband_t hb_up, hb_down; + halfband_t hb_up, hb_down; smoothval drive, wet; } personal; @@ -46,20 +46,19 @@ smooth(smoothval *val) return a; } -INNER CONST v2df -distort(v2df x) +TEMPLATE INNER CONST T +distort(T x) { - return (V(27.)*x + V(9.)) / (V(9.)*x*x + V(6.)*x + V(19.)) - V(9./19.); + return (T(27.)*x + T(9.)) / (T(9.)*x*x + T(6.)*x + T(19.)) - T(9./19.); } -INNER CONST v2df -process_one(v2df x, v2df drive, v2df wet) +TEMPLATE INNER CONST T +process_one(T x, T drive, T wet) { - return (distort(x*drive)/drive*V(0.79) - x)*wet + x; + return (distort(x*drive)/drive*T(0.79) - x)*wet + x; } -template -static void +TEMPLATE static void process(personal *data, T *in_L, T *in_R, T *out_L, T *out_R, @@ -71,8 +70,8 @@ process(personal *data, v2df buf[BLOCK_SIZE]; v2df over[FULL_SIZE]; - halfband_t *hb_up = &data->hb_up; - halfband_t *hb_down = &data->hb_down; + auto *hb_up = &data->hb_up; + auto *hb_down = &data->hb_down; for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { ulong rem = BLOCK_SIZE; @@ -83,16 +82,16 @@ process(personal *data, for (ulong i = 0; i < rem2; i++) { double y = smooth(&data->drive); - drives[i] = V(y); + drives[i] = v2df(y); } for (ulong i = 0; i < rem2; i++) { double y = smooth(&data->wet); - wets[i] = V(y); + wets[i] = v2df(y); } for (ulong i = 0; i < rem; i++) { - buf[i][0] = in_L[i]; - buf[i][1] = in_R[i]; + buf[i].v[0] = in_L[i]; + buf[i].v[1] = in_R[i]; } for (ulong i = 0; i < rem; i++) { @@ -110,8 +109,8 @@ process(personal *data, } for (ulong i = 0; i < rem; i++) { - out_L[i] = buf[i][0]; - out_R[i] = buf[i][1]; + out_L[i] = buf[i].v[0]; + out_R[i] = buf[i].v[1]; } in_L += BLOCK_SIZE; @@ -124,8 +123,8 @@ process(personal *data, INNER void resume(personal *data) { - memset(&data->hb_up, 0, sizeof(halfband_t)); - memset(&data->hb_down, 0, sizeof(halfband_t)); + memset(&data->hb_up, 0, sizeof(halfband_t)); + memset(&data->hb_down, 0, sizeof(halfband_t)); } INNER void diff --git a/include/Dumber.hpp b/include/Dumber.hpp new file mode 100644 index 0000000..6ac7ca6 --- /dev/null +++ b/include/Dumber.hpp @@ -0,0 +1,86 @@ +// Presenting: Dumber, the dumb number +// this is just some C++ bloat-i-mean-boilerplate +// for inheritance in vector types. + +TEMPLATE +struct DumberBase { + T v; + + inline + DumberBase() + {} + + inline + DumberBase(T v2) + { v = v2; } + + inline + DumberBase(const DumberBase &x) + { v = x.v; } + + inline DumberBase& + operator=(const DumberBase& v2) { + v = v2.v; + return *this; + } + + inline DumberBase + operator+(const DumberBase &v2) + { return DumberBase(v + v2.v); } + + inline DumberBase + operator-(const DumberBase &v2) + { return DumberBase(v - v2.v); } + + inline DumberBase + operator-() + { return DumberBase(-v); } + + inline DumberBase + operator*(const DumberBase &v2) + { return DumberBase(v * v2.v); } + + inline DumberBase + operator/(const DumberBase &v2) + { return DumberBase(v / v2.v); } + + inline DumberBase& + operator+=(const DumberBase &v2) + { + v = v + v2.v; + return *this; + } + + inline DumberBase& + operator-=(const DumberBase &v2) + { + v = v - v2.v; + return *this; + } + + inline DumberBase& + operator*=(const DumberBase &v2) + { + v = v * v2.v; + return *this; + } + + inline DumberBase& + operator/=(const DumberBase &v2) + { + v = v / v2.v; + return *this; + } +}; + +TEMPLATE +struct Dumber : public DumberBase { + inline + Dumber() + {} + + inline + Dumber(DumberBase v2) : DumberBase(v2) + {} +}; + diff --git a/include/os2piir_stereo.hpp b/include/os2piir_stereo.hpp index f2a70a6..6879cb7 100644 --- a/include/os2piir_stereo.hpp +++ b/include/os2piir_stereo.hpp @@ -6,46 +6,47 @@ overall delay: ~8 samples */ -#define copy(dst, src) memcpy(dst, src, sizeof(v2df)*8) +#define copy(dst, src) memcpy(dst, src, sizeof(T)*8) //#define copy(dst, src) _copy(dst, src) // all should be initialized to 0 -typedef struct { - v2df ao[8], bo[8]; - v2df at[8], bt[8]; - v2df x1, x2, x3; -} halfband_t; +TEMPLATE +struct halfband_t { + T ao[8], bo[8]; + T at[8], bt[8]; + T x1, x2, x3; +}; -INNER void -halfband_a(v2df a[8], v2df ao[8], v2df x0, v2df x2) +TEMPLATE INNER void +halfband_a(T a[8], T ao[8], T x0, T x2) { - a[0] = x2 + (x0 - ao[0])*V(0.006185967461045014); - a[1] = ao[0] + (a[0] - ao[1])*V(0.054230780876613788); - a[2] = ao[1] + (a[1] - ao[2])*V(0.143280861566087270); - a[3] = ao[2] + (a[2] - ao[3])*V(0.262004358403954640); - a[4] = ao[3] + (a[3] - ao[4])*V(0.398796973552973666); - a[5] = ao[4] + (a[4] - ao[5])*V(0.545323651071132232); - a[6] = ao[5] + (a[5] - ao[6])*V(0.698736833646440347); - a[7] = ao[6] + (a[6] - ao[7])*V(0.862917812650502936); + a[0] = x2 + (x0 - ao[0])*T(0.006185967461045014); + a[1] = ao[0] + (a[0] - ao[1])*T(0.054230780876613788); + a[2] = ao[1] + (a[1] - ao[2])*T(0.143280861566087270); + a[3] = ao[2] + (a[2] - ao[3])*T(0.262004358403954640); + a[4] = ao[3] + (a[3] - ao[4])*T(0.398796973552973666); + a[5] = ao[4] + (a[4] - ao[5])*T(0.545323651071132232); + a[6] = ao[5] + (a[5] - ao[6])*T(0.698736833646440347); + a[7] = ao[6] + (a[6] - ao[7])*T(0.862917812650502936); } -INNER void -halfband_b(v2df b[8], v2df bo[8], v2df x1, v2df x3) +TEMPLATE INNER void +halfband_b(T b[8], T bo[8], T x1, T x3) { - b[0] = x3 + (x1 - bo[0])*V(0.024499027624721819); - b[1] = bo[0] + (b[0] - bo[1])*V(0.094283481125726432); - b[2] = bo[1] + (b[1] - bo[2])*V(0.199699579426327684); - b[3] = bo[2] + (b[2] - bo[3])*V(0.328772348316831664); - b[4] = bo[3] + (b[3] - bo[4])*V(0.471167216679969414); - b[5] = bo[4] + (b[4] - bo[5])*V(0.621096845120503893); - b[6] = bo[5] + (b[5] - bo[6])*V(0.778944517099529166); - b[7] = bo[6] + (b[6] - bo[7])*V(0.952428157718303137); + b[0] = x3 + (x1 - bo[0])*T(0.024499027624721819); + b[1] = bo[0] + (b[0] - bo[1])*T(0.094283481125726432); + b[2] = bo[1] + (b[1] - bo[2])*T(0.199699579426327684); + b[3] = bo[2] + (b[2] - bo[3])*T(0.328772348316831664); + b[4] = bo[3] + (b[3] - bo[4])*T(0.471167216679969414); + b[5] = bo[4] + (b[4] - bo[5])*T(0.621096845120503893); + b[6] = bo[5] + (b[5] - bo[6])*T(0.778944517099529166); + b[7] = bo[6] + (b[6] - bo[7])*T(0.952428157718303137); } -INNER v2df -halfband(halfband_t *h, v2df x0) +TEMPLATE INNER T +halfband(halfband_t *h, T x0) { - v2df a[8], b[8]; + T a[8], b[8]; halfband_a(a, h->ao, x0, h->x2); halfband_b(b, h->bo, h->x1, h->x3); copy(h->ao, h->at); @@ -55,46 +56,46 @@ halfband(halfband_t *h, v2df x0) h->x3 = h->x2; h->x2 = h->x1; h->x1 = x0; - return (a[7] + b[7])*V(0.5); + return (a[7] + b[7])*T(0.5); } -INNER v2df -decimate_a(halfband_t *h, v2df x0) +TEMPLATE INNER T +decimate_a(halfband_t *h, T x0) { - v2df c[8]; + T c[8]; halfband_b(c, h->bo, x0, h->x2); copy(h->bo, c); h->x2 = h->x1; h->x1 = x0; - return V(0); + return T(0); } -INNER v2df -decimate_b(halfband_t *h, v2df x0) +TEMPLATE INNER T +decimate_b(halfband_t *h, T x0) { - v2df c[8]; + T c[8]; halfband_a(c, h->ao, x0, h->x2); copy(h->ao, c); h->x2 = h->x1; h->x1 = x0; - return (c[7] + h->bo[7])*V(0.5); + return (c[7] + h->bo[7])*T(0.5); } // note: do not zero-stuff! send the input each time. -INNER v2df -interpolate_a(halfband_t *h, v2df x0) +TEMPLATE INNER T +interpolate_a(halfband_t *h, T x0) { - v2df c[8]; + T c[8]; halfband_a(c, h->ao, x0, h->x1); copy(h->ao, c); return c[7]; } // note: do not zero-stuff! send the input each time. -INNER v2df -interpolate_b(halfband_t *h, v2df x0) +TEMPLATE INNER T +interpolate_b(halfband_t *h, T x0) { - v2df c[8]; + T c[8]; halfband_b(c, h->bo, x0, h->x1); copy(h->bo, c); h->x1 = x0; diff --git a/include/util.hpp b/include/util.hpp index 19d8ce6..66ce4dc 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -6,27 +6,20 @@ #include #endif +#define TEMPLATE template #define INNER static inline #define PURE __attribute__((pure)) #define CONST __attribute__((const)) #define RESTRICT __restrict__ -typedef double v2df __attribute__((vector_size(16), aligned(16))); -typedef float v2sf __attribute__((vector_size(8), aligned(8))); -typedef float v4sf __attribute__((vector_size(16), aligned(16))); - -#ifdef FORCE_SINGLE -#define v2dt float -#define v2df v2sf -#else -#define v2dt double -#endif - -typedef float v4sf __attribute__((vector_size(16), aligned(16))); typedef unsigned long ulong; // __attribute((aligned(16))); -#define V(x) (v2df){(v2dt) (x), (v2dt) (x)} -#define V2(x, y) (v2df){(v2dt) (x), (v2dt) (y)} +#include "Dumber.hpp" +#include "vectors.hpp" + +#ifdef FORCE_SINGLE +#define v2df v2sf +#endif INNER void disable_denormals() @@ -36,9 +29,6 @@ disable_denormals() #endif } -/* via http://www.rgba.org/articles/sfrand/sfrand.htm */ -static unsigned int mirand = 1; - #define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v))) #define DB2LIN(x) ((x) > -90 ? pow(10, (x) * 0.05) : 0) @@ -46,6 +36,9 @@ static unsigned int mirand = 1; #define ANGULAR(fc, fs) (2 * M_PI / (fs) * (fc)) #define ANGULAR_LIM(fc, fs) (2 * M_PI / (fs) * LIMIT((fc), 1, (fs)/2)) +/* via http://www.rgba.org/articles/sfrand/sfrand.htm */ +static unsigned int mirand = 1; + INNER float whitenoise() { @@ -71,5 +64,6 @@ typedef enum { FILT_GAIN } filter_t; -#include "biquad.hpp" -#include "svf.hpp" +// TODO: don't include these here +//#include "biquad.hpp" +//#include "svf.hpp" diff --git a/include/vectors.hpp b/include/vectors.hpp new file mode 100644 index 0000000..8b35936 --- /dev/null +++ b/include/vectors.hpp @@ -0,0 +1,56 @@ +// all of this is just so i can: +// v2df(0.5) + +typedef double _v2df __attribute__((vector_size(16), aligned(16))); +typedef float _v2sf __attribute__((vector_size(8), aligned(8))); +typedef float _v4sf __attribute__((vector_size(16), aligned(16))); + +template<> +struct Dumber<_v2df> : public DumberBase<_v2df> { + inline Dumber() {} + inline Dumber(DumberBase<_v2df> v2) : DumberBase<_v2df>(v2) {} + + TEMPLATE inline + Dumber(T x, T y) + { v = (_v2df){double(x), double(y)}; } + + TEMPLATE inline + Dumber(T x) + { v = (_v2df){double(x), double(x)}; } +}; + +template<> +struct Dumber<_v2sf> : public DumberBase<_v2sf> { + inline Dumber() {} + inline Dumber(DumberBase<_v2sf> v2) : DumberBase<_v2sf>(v2) {} + + TEMPLATE inline + Dumber(T x, T y) + { v = (_v2sf){float(x), float(y)}; } + + TEMPLATE inline + Dumber(T x) + { v = (_v2sf){float(x), float(x)}; } +}; + +template<> +struct Dumber<_v4sf> : public DumberBase<_v4sf> { + inline Dumber() {} + inline Dumber(DumberBase<_v4sf> v2) : DumberBase<_v4sf>(v2) {} + + TEMPLATE inline + Dumber(T x, T y, T z, T w) + { v = (_v4sf){float(x), float(y), float(z), float(w)}; } + + TEMPLATE inline + Dumber(T x, T y) + { v = (_v4sf){float(x), float(y), float(x), float(y)}; } + + TEMPLATE inline + Dumber(T x) + { v = (_v4sf){float(x), float(x), float(x), float(x)}; } +}; + +typedef Dumber<_v2df> v2df; +typedef Dumber<_v2sf> v2sf; +typedef Dumber<_v4sf> v4sf;