rework crap_tube to use templates

i'm so sorry
This commit is contained in:
Connor Olding 2015-06-06 16:45:09 -07:00
parent ad4551af16
commit e2b74d736c
6 changed files with 219 additions and 84 deletions

View File

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

View File

@ -22,7 +22,7 @@ typedef struct {
} smoothval;
typedef struct {
halfband_t hb_up, hb_down;
halfband_t<v2df> 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<T>(x*drive)/drive*T(0.79) - x)*wet + x;
}
template<typename T>
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<v2df>));
memset(&data->hb_down, 0, sizeof(halfband_t<v2df>));
}
INNER void

86
include/Dumber.hpp Normal file
View File

@ -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<T> {
inline
Dumber()
{}
inline
Dumber(DumberBase<T> v2) : DumberBase<T>(v2)
{}
};

View File

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

View File

@ -6,27 +6,20 @@
#include <emmintrin.h>
#endif
#define TEMPLATE template<typename T>
#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"

56
include/vectors.hpp Normal file
View File

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