diff --git a/crap/delay_test.hpp b/crap/delay_test.hpp index 74db274..5ba2fe4 100644 --- a/crap/delay_test.hpp +++ b/crap/delay_test.hpp @@ -79,22 +79,11 @@ process_one(channel *c, double s) return s; } +template INNER void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, - ulong count) -{ - for (ulong pos = 0; pos < count; pos++) { - out_L[pos] = process_one(&data->c[0], in_L[pos]); - out_R[pos] = process_one(&data->c[1], in_R[pos]); - } -} - -INNER void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, + T *in_L, T *in_R, + T *out_L, T *out_R, ulong count) { for (ulong pos = 0; pos < count; pos++) { diff --git a/crap/eq.hpp b/crap/eq.hpp index 1ae08c8..36a8678 100644 --- a/crap/eq.hpp +++ b/crap/eq.hpp @@ -20,19 +20,48 @@ typedef struct { float fs; } personal; -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -#include "process_biquads.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, - ulong count) -#include "process_biquads.hpp" + T *in_L, T *in_R, + T *out_L, T *out_R, + unsigned long count) +{ + disable_denormals(); + + v2df buf[BLOCK_SIZE]; + + biquad *f0, *f1; + + for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { + ulong rem = BLOCK_SIZE; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + for (ulong i = 0; i < rem; i++) { + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; + } + + f0 = data->filters[0]; + f1 = data->filters[1]; + for (ulong i = 0; i < BANDS; i++) { + biquad_run_block_stereo(f0, f1, buf, rem); + f0++; + f1++; + } + + for (ulong i = 0; i < rem; i++) { + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void resume(personal *data) diff --git a/crap/eq_const.hpp b/crap/eq_const.hpp index 6f3dff7..a9fe812 100644 --- a/crap/eq_const.hpp +++ b/crap/eq_const.hpp @@ -16,19 +16,48 @@ typedef struct { biquad filters[2][BANDS]; } personal; -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -#include "process_biquads.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, - ulong count) -#include "process_biquads.hpp" + T *in_L, T *in_R, + T *out_L, T *out_R, + unsigned long count) +{ + disable_denormals(); + + v2df buf[BLOCK_SIZE]; + + biquad *f0, *f1; + + for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { + ulong rem = BLOCK_SIZE; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + for (ulong i = 0; i < rem; i++) { + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; + } + + f0 = data->filters[0]; + f1 = data->filters[1]; + for (ulong i = 0; i < BANDS; i++) { + biquad_run_block_stereo(f0, f1, buf, rem); + f0++; + f1++; + } + + for (ulong i = 0; i < rem; i++) { + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void construct(personal *data) diff --git a/crap/eq_const_T420.hpp b/crap/eq_const_T420.hpp index 36cc884..7ea4f57 100644 --- a/crap/eq_const_T420.hpp +++ b/crap/eq_const_T420.hpp @@ -16,19 +16,48 @@ typedef struct { biquad filters[2][BANDS]; } personal; -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -#include "process_biquads.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, + T *in_L, T *in_R, + T *out_L, T *out_R, ulong count) -#include "process_biquads.hpp" +{ + disable_denormals(); + + v2df buf[BLOCK_SIZE]; + + biquad *f0, *f1; + + for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { + ulong rem = BLOCK_SIZE; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + for (ulong i = 0; i < rem; i++) { + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; + } + + f0 = data->filters[0]; + f1 = data->filters[1]; + for (ulong i = 0; i < BANDS; i++) { + biquad_run_block_stereo(f0, f1, buf, rem); + f0++; + f1++; + } + + for (ulong i = 0; i < rem; i++) { + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void construct(personal *data) diff --git a/crap/eq_const_T420_svf.hpp b/crap/eq_const_T420_svf.hpp index f963821..9ebfea4 100644 --- a/crap/eq_const_T420_svf.hpp +++ b/crap/eq_const_T420_svf.hpp @@ -18,19 +18,58 @@ typedef struct { svf_matrix filters[2][BANDS]; } personal; -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -#include "process_svfs.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, - ulong count) -#include "process_svfs.hpp" + T *in_L, T *in_R, + T *out_L, T *out_R, + unsigned long count) +{ + disable_denormals(); + + assert(count % 2 == 0); + + v4sf buf_L[BLOCK_SIZE/2]; + v4sf buf_R[BLOCK_SIZE/2]; + + svf_matrix *f0, *f1; + + for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { + ulong rem = BLOCK_SIZE; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + for (ulong i = 0, j = 0; i < rem; i += 2, j++) { + buf_L[j][0] = in_L[i+0]; + buf_L[j][1] = in_L[i+1]; + buf_R[j][0] = in_R[i+0]; + buf_R[j][1] = in_R[i+1]; + } + + f0 = data->filters[0]; + for (ulong i = 0; i < BANDS; i++) { + svf_run_block_mat(f0, buf_L, rem); + f0++; + } + f1 = data->filters[1]; + for (ulong i = 0; i < BANDS; i++) { + svf_run_block_mat(f1, buf_R, rem); + f1++; + } + + for (ulong i = 0, j = 0; i < rem; i += 2, j++) { + out_L[i+0] = buf_L[j][0]; + out_L[i+1] = buf_L[j][1]; + out_R[i+0] = buf_R[j][0]; + out_R[i+1] = buf_R[j][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void construct(personal *data) diff --git a/crap/mugi4.hpp b/crap/mugi4.hpp index caf896f..f3fa9e1 100644 --- a/crap/mugi4.hpp +++ b/crap/mugi4.hpp @@ -97,19 +97,57 @@ process_one(v2df in, personal *data) return out/data->drive*compensate; } -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -#include "process_mugi4.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, + T *in_L, T *in_R, + T *out_L, T *out_R, ulong count) -#include "process_mugi4.hpp" +{ + disable_denormals(); + v2df buf[BLOCK_SIZE]; + v2df over[FULL_SIZE]; + + 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; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + ulong rem2 = rem*OVERSAMPLING; + + for (ulong i = 0; i < rem; i++) { + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; + } + + for (ulong i = 0; i < rem; i++) { + over[i*2+0] = interpolate_a(hb_up, buf[i]); + over[i*2+1] = interpolate_b(hb_up, buf[i]); + } + + for (ulong i = 0; i < rem2; i++) { + over[i] = process_one(over[i], data); + } + + for (ulong i = 0; i < rem; i++) { + decimate_a(hb_down, over[i*2+0]); + buf[i] = decimate_b(hb_down, over[i*2+1]); + } + + for (ulong i = 0; i < rem; i++) { + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void construct(personal *data) diff --git a/crap/noise.hpp b/crap/noise.hpp index eb7cdc4..3969b4b 100644 --- a/crap/noise.hpp +++ b/crap/noise.hpp @@ -10,10 +10,11 @@ typedef struct { } personal; +template INNER void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, + T *in_L, T *in_R, + T *out_L, T *out_R, unsigned long count) { // TODO: separate and preserve mirand for each channel @@ -23,18 +24,6 @@ process(personal *data, out_R[pos] = whitenoise(); } -INNER void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - unsigned long count) -{ - for (unsigned long pos = 0; pos < count; pos++) - out_L[pos] = whitenoise(); - for (unsigned long pos = 0; pos < count; pos++) - out_R[pos] = whitenoise(); -} - INNER void construct(personal *data) {} diff --git a/crap/tube.hpp b/crap/tube.hpp index 6978bf3..d9594f8 100644 --- a/crap/tube.hpp +++ b/crap/tube.hpp @@ -58,19 +58,68 @@ process_one(v2df x, v2df drive, v2df wet) return (distort(x*drive)/drive*V(0.79) - x)*wet + x; } -static void -process_double(personal *data, - double *in_L, double *in_R, - double *out_L, double *out_R, - ulong count) -#include "process_nonlinear.hpp" - +template static void process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, + T *in_L, T *in_R, + T *out_L, T *out_R, ulong count) -#include "process_nonlinear.hpp" +{ + disable_denormals(); + + v2df drives[FULL_SIZE], wets[FULL_SIZE]; + v2df buf[BLOCK_SIZE]; + v2df over[FULL_SIZE]; + + 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; + if (pos + BLOCK_SIZE > count) + rem = count - pos; + + ulong rem2 = rem*OVERSAMPLING; + + for (ulong i = 0; i < rem2; i++) { + double y = smooth(&data->drive); + drives[i] = V(y); + } + for (ulong i = 0; i < rem2; i++) { + double y = smooth(&data->wet); + wets[i] = V(y); + } + + for (ulong i = 0; i < rem; i++) { + buf[i][0] = in_L[i]; + buf[i][1] = in_R[i]; + } + + for (ulong i = 0; i < rem; i++) { + over[i*2+0] = interpolate_a(hb_up, buf[i]); + over[i*2+1] = interpolate_b(hb_up, buf[i]); + } + + for (ulong i = 0; i < rem2; i++) { + over[i] = process_one(over[i], drives[i], wets[i]); + } + + for (ulong i = 0; i < rem; i++) { + decimate_a(hb_down, over[i*2+0]); + buf[i] = decimate_b(hb_down, over[i*2+1]); + } + + for (ulong i = 0; i < rem; i++) { + out_L[i] = buf[i][0]; + out_R[i] = buf[i][1]; + } + + in_L += BLOCK_SIZE; + in_R += BLOCK_SIZE; + out_L += BLOCK_SIZE; + out_R += BLOCK_SIZE; + } +} INNER void resume(personal *data) diff --git a/include/process.hpp b/include/process.hpp deleted file mode 100644 index bbc2450..0000000 --- a/include/process.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// provides a generic wrapper around process_double - -#ifndef BLOCK_SIZE -#define BLOCK_SIZE 256 -#endif - -static void -process(personal *data, - float *in_L, float *in_R, - float *out_L, float *out_R, - ulong count) -{ - double in_L2[BLOCK_SIZE], in_R2[BLOCK_SIZE]; - double out_L2[BLOCK_SIZE], out_R2[BLOCK_SIZE]; - - for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { - ulong rem = BLOCK_SIZE; - if (pos + BLOCK_SIZE > count) - rem = count - pos; - - for (ulong i = 0; i < rem; i++) - in_L2[i] = in_L[i]; - for (ulong i = 0; i < rem; i++) - in_R2[i] = in_R[i]; - - process_double(data, in_L2, in_R2, out_L2, out_R2, rem); - - for (ulong i = 0; i < rem; i++) - out_L[i] = out_L2[i]; - for (ulong i = 0; i < rem; i++) - out_R[i] = out_R2[i]; - - in_L += BLOCK_SIZE; - in_R += BLOCK_SIZE; - out_L += BLOCK_SIZE; - out_R += BLOCK_SIZE; - } -} diff --git a/include/process_biquads.hpp b/include/process_biquads.hpp deleted file mode 100644 index a277a4d..0000000 --- a/include/process_biquads.hpp +++ /dev/null @@ -1,36 +0,0 @@ -{ - disable_denormals(); - - v2df buf[BLOCK_SIZE]; - - biquad *f0, *f1; - - for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { - ulong rem = BLOCK_SIZE; - if (pos + BLOCK_SIZE > count) - rem = count - pos; - - for (ulong i = 0; i < rem; i++) { - buf[i][0] = in_L[i]; - buf[i][1] = in_R[i]; - } - - f0 = data->filters[0]; - f1 = data->filters[1]; - for (ulong i = 0; i < BANDS; i++) { - biquad_run_block_stereo(f0, f1, buf, rem); - f0++; - f1++; - } - - for (ulong i = 0; i < rem; i++) { - out_L[i] = buf[i][0]; - out_R[i] = buf[i][1]; - } - - in_L += BLOCK_SIZE; - in_R += BLOCK_SIZE; - out_L += BLOCK_SIZE; - out_R += BLOCK_SIZE; - } -} diff --git a/include/process_mugi4.hpp b/include/process_mugi4.hpp deleted file mode 100644 index c7e5490..0000000 --- a/include/process_mugi4.hpp +++ /dev/null @@ -1,45 +0,0 @@ -{ - disable_denormals(); - v2df buf[BLOCK_SIZE]; - v2df over[FULL_SIZE]; - - 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; - if (pos + BLOCK_SIZE > count) - rem = count - pos; - - ulong rem2 = rem*OVERSAMPLING; - - for (ulong i = 0; i < rem; i++) { - buf[i][0] = in_L[i]; - buf[i][1] = in_R[i]; - } - - for (ulong i = 0; i < rem; i++) { - over[i*2+0] = interpolate_a(hb_up, buf[i]); - over[i*2+1] = interpolate_b(hb_up, buf[i]); - } - - for (ulong i = 0; i < rem2; i++) { - over[i] = process_one(over[i], data); - } - - for (ulong i = 0; i < rem; i++) { - decimate_a(hb_down, over[i*2+0]); - buf[i] = decimate_b(hb_down, over[i*2+1]); - } - - for (ulong i = 0; i < rem; i++) { - out_L[i] = buf[i][0]; - out_R[i] = buf[i][1]; - } - - in_L += BLOCK_SIZE; - in_R += BLOCK_SIZE; - out_L += BLOCK_SIZE; - out_R += BLOCK_SIZE; - } -} diff --git a/include/process_nonlinear.hpp b/include/process_nonlinear.hpp deleted file mode 100644 index 5146662..0000000 --- a/include/process_nonlinear.hpp +++ /dev/null @@ -1,56 +0,0 @@ -{ - disable_denormals(); - - v2df drives[FULL_SIZE], wets[FULL_SIZE]; - v2df buf[BLOCK_SIZE]; - v2df over[FULL_SIZE]; - - 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; - if (pos + BLOCK_SIZE > count) - rem = count - pos; - - ulong rem2 = rem*OVERSAMPLING; - - for (ulong i = 0; i < rem2; i++) { - double y = smooth(&data->drive); - drives[i] = V(y); - } - for (ulong i = 0; i < rem2; i++) { - double y = smooth(&data->wet); - wets[i] = V(y); - } - - for (ulong i = 0; i < rem; i++) { - buf[i][0] = in_L[i]; - buf[i][1] = in_R[i]; - } - - for (ulong i = 0; i < rem; i++) { - over[i*2+0] = interpolate_a(hb_up, buf[i]); - over[i*2+1] = interpolate_b(hb_up, buf[i]); - } - - for (ulong i = 0; i < rem2; i++) { - over[i] = process_one(over[i], drives[i], wets[i]); - } - - for (ulong i = 0; i < rem; i++) { - decimate_a(hb_down, over[i*2+0]); - buf[i] = decimate_b(hb_down, over[i*2+1]); - } - - for (ulong i = 0; i < rem; i++) { - out_L[i] = buf[i][0]; - out_R[i] = buf[i][1]; - } - - in_L += BLOCK_SIZE; - in_R += BLOCK_SIZE; - out_L += BLOCK_SIZE; - out_R += BLOCK_SIZE; - } -} diff --git a/include/process_svfs.hpp b/include/process_svfs.hpp deleted file mode 100644 index f634be7..0000000 --- a/include/process_svfs.hpp +++ /dev/null @@ -1,46 +0,0 @@ -{ - disable_denormals(); - - assert(count % 2 == 0); - - v4sf buf_L[BLOCK_SIZE/2]; - v4sf buf_R[BLOCK_SIZE/2]; - - svf_matrix *f0, *f1; - - for (ulong pos = 0; pos < count; pos += BLOCK_SIZE) { - ulong rem = BLOCK_SIZE; - if (pos + BLOCK_SIZE > count) - rem = count - pos; - - for (ulong i = 0, j = 0; i < rem; i += 2, j++) { - buf_L[j][0] = in_L[i+0]; - buf_L[j][1] = in_L[i+1]; - buf_R[j][0] = in_R[i+0]; - buf_R[j][1] = in_R[i+1]; - } - - f0 = data->filters[0]; - for (ulong i = 0; i < BANDS; i++) { - svf_run_block_mat(f0, buf_L, rem); - f0++; - } - f1 = data->filters[1]; - for (ulong i = 0; i < BANDS; i++) { - svf_run_block_mat(f1, buf_R, rem); - f1++; - } - - for (ulong i = 0, j = 0; i < rem; i += 2, j++) { - out_L[i+0] = buf_L[j][0]; - out_L[i+1] = buf_L[j][1]; - out_R[i+0] = buf_R[j][0]; - out_R[i+1] = buf_R[j][1]; - } - - in_L += BLOCK_SIZE; - in_R += BLOCK_SIZE; - out_L += BLOCK_SIZE; - out_R += BLOCK_SIZE; - } -} diff --git a/template/vst.cpp b/template/vst.cpp index 9c7d640..262e96a 100644 --- a/template/vst.cpp +++ b/template/vst.cpp @@ -101,7 +101,7 @@ void plugin::processDoubleReplacing( double **inputs, double **outputs, VstInt32 count) { - ::process_double(&data, + ::process(&data, inputs[0], inputs[1], outputs[0], outputs[1], count);