diff --git a/crap/delay_test.hpp b/crap/delay_test.hpp index 5ba2fe4..f5efc9d 100644 --- a/crap/delay_test.hpp +++ b/crap/delay_test.hpp @@ -1,7 +1,3 @@ -#include "util.hpp" - -typedef unsigned long ulong; - #define ID 0xDEDEDEDE #define LABEL "crap_delay_test" #define NAME "crap sample delay test" @@ -10,6 +6,9 @@ typedef unsigned long ulong; #define PARAMETERS 0 #define DELAY +#include "util.hpp" +#include "biquad.hpp" + static ulong global_delay = 2; static double oversample = 4; diff --git a/crap/eq.hpp b/crap/eq.hpp index 36a8678..e3b1777 100644 --- a/crap/eq.hpp +++ b/crap/eq.hpp @@ -14,14 +14,14 @@ #include "util.hpp" #include "param.hpp" +#include "biquad.hpp" typedef struct { biquad filters[2][BANDS]; float fs; } personal; -template -static void +TEMPLATE static void process(personal *data, T *in_L, T *in_R, T *out_L, T *out_R, diff --git a/crap/eq_const.hpp b/crap/eq_const.hpp index a9fe812..22c2323 100644 --- a/crap/eq_const.hpp +++ b/crap/eq_const.hpp @@ -10,14 +10,14 @@ #define BLOCK_SIZE 256 #include "util.hpp" +#include "biquad.hpp" #define BANDS 12 typedef struct { biquad filters[2][BANDS]; } personal; -template -static void +TEMPLATE static void process(personal *data, T *in_L, T *in_R, T *out_L, T *out_R, diff --git a/crap/eq_const_T420.hpp b/crap/eq_const_T420.hpp index 7ea4f57..a0b989a 100644 --- a/crap/eq_const_T420.hpp +++ b/crap/eq_const_T420.hpp @@ -10,14 +10,14 @@ #define BLOCK_SIZE 256 #include "util.hpp" +#include "biquad.hpp" #define BANDS 16 typedef struct { biquad filters[2][BANDS]; } personal; -template -static void +TEMPLATE static void process(personal *data, T *in_L, T *in_R, T *out_L, T *out_R, diff --git a/crap/eq_const_T420_svf.hpp b/crap/eq_const_T420_svf.hpp index 9ebfea4..f3fee98 100644 --- a/crap/eq_const_T420_svf.hpp +++ b/crap/eq_const_T420_svf.hpp @@ -12,14 +12,14 @@ #define BLOCK_SIZE 256 #include "util.hpp" +#include "svf.hpp" #define BANDS 16 typedef struct { - svf_matrix filters[2][BANDS]; + svf_matrix filters[2][BANDS]; } personal; -template -static void +TEMPLATE static void process(personal *data, T *in_L, T *in_R, T *out_L, T *out_R, @@ -32,7 +32,7 @@ process(personal *data, v4sf buf_L[BLOCK_SIZE/2]; v4sf buf_R[BLOCK_SIZE/2]; - svf_matrix *f0, *f1; + svf_matrix *f0, *f1; for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { ulong rem = BLOCK_SIZE; @@ -82,12 +82,10 @@ destruct(personal *data) INNER void resume(personal *data) { - svf_matrix *filters = data->filters[0]; - for (int i = 0; i < BANDS; i++) { - filters[i].memory[0] = 0; - filters[i].memory[1] = 0; - } - memcpy(data->filters[1], filters, BANDS*sizeof(svf_matrix)); + svf_matrix *filters = data->filters[0]; + for (int i = 0; i < BANDS; i++) + filters[i].memory = v4sf(0); + memcpy(data->filters[1], filters, BANDS*sizeof(svf_matrix)); } INNER void @@ -97,21 +95,21 @@ pause(personal *data) INNER void adjust(personal *data, ulong fs) { - svf_matrix *filters = data->filters[0]; - filters[ 0] = svf_gen_matrix(svf_gen(FILT_PEAKING, 180., 11., 1.40, fs)); - filters[ 1] = svf_gen_matrix(svf_gen(FILT_PEAKING, 740., 5.5, 0.70, fs)); - filters[ 2] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1220, -12., 0.70, fs)); - filters[ 3] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1580, 7.0, 0.25, fs)); - filters[ 4] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2080, -2.5, 0.30, fs)); - filters[ 5] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2270, 6.0, 0.20, fs)); - filters[ 6] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2470, -2.0, 0.18, fs)); - filters[ 7] = svf_gen_matrix(svf_gen(FILT_PEAKING, 3700, -5.0, 0.32, fs)); - filters[ 8] = svf_gen_matrix(svf_gen(FILT_PEAKING, 6200, -3.5, 0.25, fs)); - filters[ 9] = svf_gen_matrix(svf_gen(FILT_PEAKING, 6000, -11., 3.66, fs)); - filters[10] = svf_gen_matrix(svf_gen(FILT_HIGHSHELF, 11500, 4.0, 0.40, fs)); - filters[11] = svf_gen_matrix(svf_gen(FILT_HIGHPASS, 150, 0.0, 1.00, fs)); - filters[12] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1775, -2.0, 0.18, fs)); - filters[13] = svf_gen_matrix(svf_gen(FILT_PEAKING, 490, -1.5, 0.23, fs)); - filters[14] = svf_gen_matrix(svf_gen(FILT_PEAKING, 3100, 5.0, 0.33, fs)); - filters[15] = svf_gen_matrix(svf_gen(FILT_LOWPASS, 14000, 0.0, 0.40, fs)); + svf_matrix *filters = data->filters[0]; + filters[ 0] = svf_gen_matrix(svf_gen(FILT_PEAKING, 180., 11., 1.40, fs)); + filters[ 1] = svf_gen_matrix(svf_gen(FILT_PEAKING, 740., 5.5, 0.70, fs)); + filters[ 2] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1220, -12., 0.70, fs)); + filters[ 3] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1580, 7.0, 0.25, fs)); + filters[ 4] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2080, -2.5, 0.30, fs)); + filters[ 5] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2270, 6.0, 0.20, fs)); + filters[ 6] = svf_gen_matrix(svf_gen(FILT_PEAKING, 2470, -2.0, 0.18, fs)); + filters[ 7] = svf_gen_matrix(svf_gen(FILT_PEAKING, 3700, -5.0, 0.32, fs)); + filters[ 8] = svf_gen_matrix(svf_gen(FILT_PEAKING, 6200, -3.5, 0.25, fs)); + filters[ 9] = svf_gen_matrix(svf_gen(FILT_PEAKING, 6000, -11., 3.66, fs)); + filters[10] = svf_gen_matrix(svf_gen(FILT_HIGHSHELF, 11500, 4.0, 0.40, fs)); + filters[11] = svf_gen_matrix(svf_gen(FILT_HIGHPASS, 150, 0.0, 1.00, fs)); + filters[12] = svf_gen_matrix(svf_gen(FILT_PEAKING, 1775, -2.0, 0.18, fs)); + filters[13] = svf_gen_matrix(svf_gen(FILT_PEAKING, 490, -1.5, 0.23, fs)); + filters[14] = svf_gen_matrix(svf_gen(FILT_PEAKING, 3100, 5.0, 0.33, fs)); + filters[15] = svf_gen_matrix(svf_gen(FILT_LOWPASS, 14000, 0.0, 0.40, fs)); } diff --git a/crap/mugi4.hpp b/crap/mugi4.hpp index f3fa9e1..22a8a80 100644 --- a/crap/mugi4.hpp +++ b/crap/mugi4.hpp @@ -27,7 +27,7 @@ https://aaltodoc.aalto.fi/bitstream/handle/123456789/14420/article6.pdf #define VT 0.026 #define N 4 -#define VT2 V(2.*VT) +#define VT2 T(2.*VT) typedef struct { v2df sum, sumback, dout; @@ -45,55 +45,55 @@ typedef struct { typedef struct { ulong fs; - halfband_t hb_up, hb_down; + halfband_t hb_up, hb_down; freqdata fd; stage s1, s2, s3, s4; v2df sumback1, sumback2, sumback3, sumback4; v2df drive, feedback; } personal; -INNER PURE v2df -tanh2(v2df x) +TEMPLATE INNER PURE T +tanh2(T x) { - //return (v2df){tanh(x[0]), tanh(x[1])}; - v2df xx = x*x; - v2df a = ((xx + V(378.))*xx + V(17325.))*xx + V(135135.); - v2df b = ((V(28.)*xx + V(3150.))*xx + V(62370.))*xx + V(135135.); + //return T(tanh(x[0]), tanh(x[1])); + T xx = x*x; + T a = ((xx + T(378))*xx + T(17325))*xx + T(135135); + T b = ((T(28)*xx + T(3150))*xx + T(62370))*xx + T(135135); return x*a/b; } -INNER v2df -process_stage(stage *s, freqdata fd, v2df in) +TEMPLATE INNER T +process_stage(stage *s, freqdata fd, T in) { - v2df temp = (in + s->sumback)*VT2*fd.L_p0*fd.g; - v2df out = temp + s->sum; - s->sum += V(2.)*temp; - s->dout = tanh2(out/VT2); + T temp = (in + s->sumback)*VT2*fd.L_p0*fd.g; + T out = temp + s->sum; + s->sum += T(2)*temp; + s->dout = tanh2(out/VT2); s->sumback = in*fd.L_r1 - s->dout*fd.L_q0; return out; } -INNER v2df -process_one(v2df in, personal *data) +TEMPLATE INNER T +process_one(T in, personal *data) { - const freqdata fd = data->fd; + freqdata fd = data->fd; in *= data->drive; - v2df sum = in + data->sumback1; - v2df pre = -fd.p0*sum; - process_stage(&data->s1, fd, tanh2(pre/VT2)); - process_stage(&data->s2, fd, data->s1.dout); - process_stage(&data->s3, fd, data->s2.dout); - v2df out = process_stage(&data->s4, fd, data->s3.dout); + T sum = in + data->sumback1; + T pre = -fd.p0*sum; + process_stage(&data->s1, fd, tanh2(pre/VT2)); + process_stage(&data->s2, fd, data->s1.dout); + process_stage(&data->s3, fd, data->s2.dout); + T out = process_stage(&data->s4, fd, data->s3.dout); - v2df back = data->feedback*out; + T back = data->feedback*out; data->sumback1 = fd.r1*in + fd.q0*back + data->sumback2; data->sumback2 = fd.r2*in + fd.q1*back + data->sumback3; data->sumback3 = fd.r3*in + fd.q2*back + data->sumback4; data->sumback4 = fd.r4*in + fd.q3*back; - v2df compensate = -(data->feedback + V(1.)); + T compensate = -(data->feedback + T(1)); return out/data->drive*compensate; } @@ -108,8 +108,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; + halfband_t *hb_up = &data->hb_up; + halfband_t *hb_down = &data->hb_down; for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { ulong rem = BLOCK_SIZE; @@ -188,8 +188,8 @@ destruct(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/crap/tube.hpp b/crap/tube.hpp index b7f7fcc..090247c 100644 --- a/crap/tube.hpp +++ b/crap/tube.hpp @@ -90,8 +90,8 @@ process(personal *data, } for (ulong i = 0; i < rem; i++) { - buf[i].v[0] = in_L[i]; - buf[i].v[1] = in_R[i]; + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; } for (ulong i = 0; i < rem; i++) { @@ -109,8 +109,8 @@ process(personal *data, } for (ulong i = 0; i < rem; i++) { - out_L[i] = buf[i].v[0]; - out_R[i] = buf[i].v[1]; + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; } in_L += BLOCK_SIZE; diff --git a/include/Dumber.hpp b/include/Dumber.hpp index 6ac7ca6..ed78cea 100644 --- a/include/Dumber.hpp +++ b/include/Dumber.hpp @@ -24,25 +24,25 @@ struct DumberBase { return *this; } + inline DumberBase + operator-() + { return -v; } + inline DumberBase operator+(const DumberBase &v2) - { return DumberBase(v + v2.v); } + { return v + v2.v; } inline DumberBase operator-(const DumberBase &v2) - { return DumberBase(v - v2.v); } - - inline DumberBase - operator-() - { return DumberBase(-v); } + { return v - v2.v; } inline DumberBase operator*(const DumberBase &v2) - { return DumberBase(v * v2.v); } + { return v*v2.v; } inline DumberBase operator/(const DumberBase &v2) - { return DumberBase(v / v2.v); } + { return v/v2.v; } inline DumberBase& operator+=(const DumberBase &v2) @@ -61,14 +61,14 @@ struct DumberBase { inline DumberBase& operator*=(const DumberBase &v2) { - v = v * v2.v; + v = v*v2.v; return *this; } inline DumberBase& operator/=(const DumberBase &v2) { - v = v / v2.v; + v = v/v2.v; return *this; } }; diff --git a/include/biquad.hpp b/include/biquad.hpp index 3db87e4..e741825 100644 --- a/include/biquad.hpp +++ b/include/biquad.hpp @@ -84,26 +84,26 @@ biquad_run(biquad *bq, double x) return y; } -INNER void +TEMPLATE INNER void biquad_run_block_stereo(biquad *bq_L, biquad *bq_R, - v2df *buf, ulong count) + T *buf, ulong count) { - v2df b0, b1, b2, a1, a2, x1, x2, y1, y2; + T b0, b1, b2, a1, a2, x1, x2, y1, y2; - b0 = V(bq_L->b0); - b1 = V(bq_L->b1); - b2 = V(bq_L->b2); - a1 = V(bq_L->a1); - a2 = V(bq_L->a2); + b0 = T(bq_L->b0); + b1 = T(bq_L->b1); + b2 = T(bq_L->b2); + a1 = T(bq_L->a1); + a2 = T(bq_L->a2); - x1 = V2(bq_L->x1, bq_R->x1); - x2 = V2(bq_L->x2, bq_R->x2); - y1 = V2(bq_L->y1, bq_R->y1); - y2 = V2(bq_L->y2, bq_R->y2); + x1 = T(bq_L->x1, bq_R->x1); + x2 = T(bq_L->x2, bq_R->x2); + y1 = T(bq_L->y1, bq_R->y1); + y2 = T(bq_L->y2, bq_R->y2); for (ulong i = 0; i < count; i++) { - v2df x = buf[i]; - v2df y = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2; + T x = buf[i]; + T y = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2; x2 = x1; y2 = y1; x1 = x; diff --git a/include/os2piir_stereo.hpp b/include/os2piir_stereo.hpp index 6879cb7..9a76d85 100644 --- a/include/os2piir_stereo.hpp +++ b/include/os2piir_stereo.hpp @@ -7,7 +7,6 @@ */ #define copy(dst, src) memcpy(dst, src, sizeof(T)*8) -//#define copy(dst, src) _copy(dst, src) // all should be initialized to 0 TEMPLATE diff --git a/include/svf.hpp b/include/svf.hpp index c91e04a..6d19ade 100644 --- a/include/svf.hpp +++ b/include/svf.hpp @@ -8,9 +8,10 @@ typedef struct { double A0[2], A1[2], B[2], C[3]; } svf_interim; -typedef struct { - v4sf a, b, c, d, memory; -} svf_matrix; +TEMPLATE +struct svf_matrix { + T a, b, c, d, memory; +}; static svf_interim svf_design(double w0, double Q, double c0, double c1, double c2, double gc) @@ -92,7 +93,7 @@ svf_run(svf *s, float x) return y; } -static svf_matrix +TEMPLATE static svf_matrix svf_gen_matrix(svf s) { float AA0[2], AA1[2], AB[2], CA[2], cb; @@ -107,20 +108,20 @@ svf_gen_matrix(svf s) cb = s.C[1]*s.B[0] + s.C[2]*s.B[1]; - svf_matrix mat; - mat.memory = (v4sf){0, 0, 0, 0}; - mat.a = (v4sf){s.C[0], 0, s.C[1], s.C[2]}; - mat.b = (v4sf){ cb, s.C[0], CA[0], CA[1]}; - mat.c = (v4sf){ AB[0], s.B[0], AA0[0], AA0[1]}; - mat.d = (v4sf){ AB[1], s.B[1], AA1[0], AA1[1]}; + svf_matrix mat; + mat.memory = T(0, 0, 0, 0); + mat.a = T(s.C[0], 0, s.C[1], s.C[2]); + mat.b = T( cb, s.C[0], CA[0], CA[1]); + mat.c = T( AB[0], s.B[0], AA0[0], AA0[1]); + mat.d = T( AB[1], s.B[1], AA1[0], AA1[1]); return mat; } -INNER void -svf_run_block_mat(svf_matrix *RESTRICT mat, v4sf *RESTRICT buf, ulong count) +TEMPLATE INNER void +svf_run_block_mat(svf_matrix *RESTRICT mat, T *RESTRICT buf, ulong count) { - v4sf t1, t2, t3, t4; - v4sf memory = mat->memory; + T t1, t2, t3, t4; + T memory = mat->memory; for (ulong i = 0; i < count/2; i++) { memory[0] = buf[i][0]; memory[1] = buf[i][1]; diff --git a/include/util.hpp b/include/util.hpp index 66ce4dc..d2bd72a 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -63,7 +63,3 @@ typedef enum { FILT_NOTCH, FILT_GAIN } filter_t; - -// TODO: don't include these here -//#include "biquad.hpp" -//#include "svf.hpp" diff --git a/include/vectors.hpp b/include/vectors.hpp index 8b35936..4ea63bc 100644 --- a/include/vectors.hpp +++ b/include/vectors.hpp @@ -10,13 +10,24 @@ struct Dumber<_v2df> : public DumberBase<_v2df> { inline Dumber() {} inline Dumber(DumberBase<_v2df> v2) : DumberBase<_v2df>(v2) {} - TEMPLATE inline - Dumber(T x, T y) + template + inline + Dumber(T1 x, T2 y) { v = (_v2df){double(x), double(y)}; } TEMPLATE inline Dumber(T x) { v = (_v2df){double(x), double(x)}; } + + inline double & + operator[](int index) { + return ((double *)&v)[index]; + } + + inline const double & + operator[](int index) const { + return ((double *)&v)[index]; + } }; template<> @@ -24,13 +35,24 @@ struct Dumber<_v2sf> : public DumberBase<_v2sf> { inline Dumber() {} inline Dumber(DumberBase<_v2sf> v2) : DumberBase<_v2sf>(v2) {} - TEMPLATE inline - Dumber(T x, T y) + template + inline + Dumber(T1 x, T2 y) { v = (_v2sf){float(x), float(y)}; } TEMPLATE inline Dumber(T x) { v = (_v2sf){float(x), float(x)}; } + + inline float & + operator[](int index) { + return ((float *)&v)[index]; + } + + inline const float & + operator[](int index) const { + return ((float *)&v)[index]; + } }; template<> @@ -38,17 +60,29 @@ 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) + template + inline + Dumber(T1 x, T2 y, T3 z, T4 w) { v = (_v4sf){float(x), float(y), float(z), float(w)}; } - TEMPLATE inline - Dumber(T x, T y) + template + inline + Dumber(T1 x, T2 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)}; } + + inline float & + operator[](int index) { + return ((float *)&v)[index]; + } + + inline const float & + operator[](int index) const { + return ((float *)&v)[index]; + } }; typedef Dumber<_v2df> v2df; diff --git a/util/bench.cpp b/util/bench.cpp index f50ee0f..8a881a1 100644 --- a/util/bench.cpp +++ b/util/bench.cpp @@ -30,7 +30,7 @@ load_ladspa(char *path) atexit(cleanup); LADSPA_Descriptor_Function df; - df = (typeof(df)) dlsym(plug, "ladspa_descriptor"); + df = (decltype(df)) dlsym(plug, "ladspa_descriptor"); assert(df); const LADSPA_Descriptor *d = df(0); @@ -100,7 +100,7 @@ main(int argc, char **argv) if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[i])) audio_count++; - audio_buffer = (typeof(audio_buffer)) calloc(audio_count*BLOCK_SIZE, sizeof(float)); + audio_buffer = (decltype(audio_buffer)) calloc(audio_count*BLOCK_SIZE, sizeof(float)); int a = 0; for (int i = 0; i < d->PortCount; i++) { @@ -108,7 +108,7 @@ main(int argc, char **argv) d->connect_port(h, i, audio_buffer + a++*BLOCK_SIZE); } else { float *x; - x = (typeof(x)) alloca(sizeof(float)); + x = (decltype(x)) alloca(sizeof(float)); *x = get_default(d->PortRangeHints[i]); d->connect_port(h, i, x); }