From 1fa7b123380e8dea288d6f5be3c580c30ff46c65 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Sun, 7 Jul 2019 20:57:25 +1000 Subject: Testing SVF with allpass --- plugins/ZaMultiComp/ZaMultiCompPlugin.cpp | 58 ++++++++++------- plugins/ZaMultiComp/ZaMultiCompPlugin.hpp | 7 ++- plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp | 89 ++++++++++++++++++++------- plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp | 7 ++- 4 files changed, 111 insertions(+), 50 deletions(-) diff --git a/plugins/ZaMultiComp/ZaMultiCompPlugin.cpp b/plugins/ZaMultiComp/ZaMultiCompPlugin.cpp index a9bea86..be6d6bd 100644 --- a/plugins/ZaMultiComp/ZaMultiCompPlugin.cpp +++ b/plugins/ZaMultiComp/ZaMultiCompPlugin.cpp @@ -694,22 +694,30 @@ void ZaMultiCompPlugin::initState(unsigned int, String&, String&) void ZaMultiCompPlugin::activate() { - int i; + int i, j; for (i = 0; i < MAX_COMP; i++) old_yl[i]=old_y1[i]=old_yg[i]=0.f; old_ll=old_l1=0.f; for (i = 0; i < MAX_FILT; i++) { - simper[0][i].k = 0.f; - simper[0][i].g = 0.f; - simper[0][i].s[0] = 0.f; - simper[0][i].s[1] = 0.f; - - simper[1][i].k = 0.f; - simper[1][i].g = 0.f; - simper[1][i].s[0] = 0.f; - simper[1][i].s[1] = 0.f; + for (j = 0; j < 2; j++) { + simper[0][i][j].k = 0.f; + simper[0][i][j].g = 0.f; + simper[0][i][j].m0 = 0.f; + simper[0][i][j].m1 = 0.f; + simper[0][i][j].m2 = 0.f; + simper[0][i][j].s[0] = 0.f; + simper[0][i][j].s[1] = 0.f; + + simper[1][i][j].k = 0.f; + simper[1][i][j].g = 0.f; + simper[1][i][j].m0 = 0.f; + simper[1][i][j].m1 = 0.f; + simper[1][i][j].m2 = 0.f; + simper[1][i][j].s[0] = 0.f; + simper[1][i][j].s[1] = 0.f; + } } max = 0.f; pos[0] = 0; @@ -725,14 +733,16 @@ void ZaMultiCompPlugin::activate() * https://cytomic.com/files/dsp/SvfInputMixing.pdf */ -void ZaMultiCompPlugin::linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance) +void ZaMultiCompPlugin::linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance, bool hp) { double w; - self->k = 2. - 2. * resonance; w = M_PI * cutoff / sample_rate; self->g = tan(w); - + self->k = 1. / resonance; + self->m0 = hp ? 0. : 1.; + self->m1 = 0.; + self->m2 = hp ? 1. : 0.; } void ZaMultiCompPlugin::linear_svf_reset(struct linear_svf *self) @@ -740,7 +750,7 @@ void ZaMultiCompPlugin::linear_svf_reset(struct linear_svf *self) self->s[0] = self->s[1] = 0.f; } -float ZaMultiCompPlugin::run_linear_svf_xover(struct linear_svf *self, float in, float mixlow, float mixhigh) +float ZaMultiCompPlugin::run_linear_svf_xover(struct linear_svf *self, float in) { double v[3]; double g = self->g; @@ -748,9 +758,9 @@ float ZaMultiCompPlugin::run_linear_svf_xover(struct linear_svf *self, float in, double s0 = self->s[0]; double s1 = self->s[1]; double g2 = g*g; - double vhigh = in * mixhigh; - double vband = in * 0.75; - double vlow = in * mixlow; + double vhigh = in * self->m2; + double vband = in * self->m1; + double vlow = in * self->m0; v[0] = in; v[1] = -1. / (1. + g2 + g*k) * (-s0 + g*s1 - g*k*s0 + g2*vband + g*vhigh - g*vlow - g2*k*vlow); @@ -765,14 +775,20 @@ void ZaMultiCompPlugin::calc_lr4(float f, int i) { float srate = getSampleRate(); - linear_svf_set_xover(&simper[0][i], srate, f, 0.25); - linear_svf_set_xover(&simper[1][i], srate, f, 0.25); + linear_svf_set_xover(&simper[0][i][0], srate, f, 0.7071068, false); + linear_svf_set_xover(&simper[1][i][0], srate, f, 0.7071068, true); + linear_svf_set_xover(&simper[0][i][1], srate, f, 0.7071068, false); + linear_svf_set_xover(&simper[1][i][1], srate, f, 0.7071068, true); } void ZaMultiCompPlugin::run_lr4(int i, float in, float *outlo, float *outhi) { - *outlo = run_linear_svf_xover(&simper[0][i], in, 1., 0.); - *outhi = run_linear_svf_xover(&simper[1][i], in, 0., 1.); + float lo, hi; + lo = run_linear_svf_xover(&simper[0][i][0], in); + *outlo = run_linear_svf_xover(&simper[0][i][1], lo); + + hi = run_linear_svf_xover(&simper[1][i][0], in); + *outhi = run_linear_svf_xover(&simper[1][i][1], hi); } void ZaMultiCompPlugin::run_comp(int k, float in, float *out) diff --git a/plugins/ZaMultiComp/ZaMultiCompPlugin.hpp b/plugins/ZaMultiComp/ZaMultiCompPlugin.hpp index 0705100..1a68012 100644 --- a/plugins/ZaMultiComp/ZaMultiCompPlugin.hpp +++ b/plugins/ZaMultiComp/ZaMultiCompPlugin.hpp @@ -171,14 +171,15 @@ protected: struct linear_svf { double k; double g; + double m0, m1, m2; double s[2]; }; - struct linear_svf simper[2][MAX_FILT]; - void linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance); + struct linear_svf simper[2][MAX_FILT][2]; + void linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance, bool hp); void linear_svf_reset(struct linear_svf *self); - float run_linear_svf_xover(struct linear_svf *self, float in, float mixlow, float mixhigh); + float run_linear_svf_xover(struct linear_svf *self, float in); void pushsample(float sample, int k); // ------------------------------------------------------------------- diff --git a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp index 5227dcc..079cfc6 100644 --- a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp +++ b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp @@ -714,7 +714,7 @@ void ZaMultiCompX2Plugin::setParameterValue(uint32_t index, float value) void ZaMultiCompX2Plugin::activate() { - int i,j; + int layer,type,i,j; for (i = 0; i < MAX_COMP; i++) for (j = 0; j < 2; j++) old_yl[j][i]=old_y1[j][i]=old_yg[j][i]=0.f; @@ -722,12 +722,17 @@ void ZaMultiCompX2Plugin::activate() for (j = 0; j < 2; j++) old_ll[j]=old_l1[j]=0.f; - for (j = 0; j < 2; j++) { + for (type = 0; type < 3; type++) { for (i = 0; i < MAX_FILT; i++) { - simper[j][i].k = 0.f; - simper[j][i].g = 0.f; - simper[j][i].s[0] = 0.f; - simper[j][i].s[1] = 0.f; + for (layer = 0; layer < 2; layer++) { + simper[type][i][layer].k = 0.f; + simper[type][i][layer].g = 0.f; + simper[type][i][layer].m0 = 0.f; + simper[type][i][layer].m1 = 0.f; + simper[type][i][layer].m2 = 0.f; + simper[type][i][layer].s[0] = 0.f; + simper[type][i][layer].s[1] = 0.f; + } } } maxL = maxR = 0.f; @@ -744,53 +749,91 @@ void ZaMultiCompX2Plugin::activate() * https://cytomic.com/files/dsp/SvfInputMixing.pdf */ -void ZaMultiCompX2Plugin::linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance) +void ZaMultiCompX2Plugin::linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance, int hp) { double w; - self->k = 2. - 2. * resonance; + self->k = 1. / resonance; w = M_PI * cutoff / sample_rate; self->g = tan(w); + switch (hp) { + case 0: + self->m0 = 1.; + self->m1 = 0.; + self->m2 = 0.; + break; + case 1: + self->m0 = 0.; + self->m1 = 0.; + self->m2 = 1.; + break; + default: + case 2: + self->m0 = 1.; + self->m1 = -self->k; + self->m2 = 1.; + break; + } } + + void ZaMultiCompX2Plugin::linear_svf_reset(struct linear_svf *self) { self->s[0] = self->s[1] = 0.f; } -float ZaMultiCompX2Plugin::run_linear_svf_xover(struct linear_svf *self, float in, float mixlow, float mixhigh) +float ZaMultiCompX2Plugin::run_linear_svf_xover(struct linear_svf *self, float in) { - double v[3]; + double v[2]; double g = self->g; double k = self->k; double s0 = self->s[0]; double s1 = self->s[1]; double g2 = g*g; - double vhigh = in * mixhigh; - double vband = in * 0.75; - double vlow = in * mixlow; + double vhigh = in * self->m2; + double vband = in * self->m1; + double vlow = in * self->m0; - v[0] = in; - v[1] = -1. / (1. + g2 + g*k) * (-s0 + g*s1 - g*k*s0 + g2*vband + g*vhigh - g*vlow - g2*k*vlow); - v[2] = -1. / (1. + g2 + g*k) * (-g*s0 - s1 - g*vband + g2*vhigh + g*k*vhigh - g2*vlow); - self->s[0] = 2. * v[1] - s0; - self->s[1] = 2. * v[2] - s1; + v[0] = -1. / (1. + g2 + g*k) * (-s0 + g*s1 - g*k*s0 + g2*vband + g*vhigh - g*vlow - g2*k*vlow); + v[1] = -1. / (1. + g2 + g*k) * (-g*s0 - s1 - g*vband + g2*vhigh + g*k*vhigh - g2*vlow); + self->s[0] = 2. * v[0] - s0; + self->s[1] = 2. * v[1] - s1; - return (float)(vhigh + v[2]); + return (float)(vhigh + v[1]); } void ZaMultiCompX2Plugin::calc_lr4(float f, int i) { float srate = getSampleRate(); - linear_svf_set_xover(&simper[0][i], srate, f, 0.25); - linear_svf_set_xover(&simper[1][i], srate, f, 0.25); + linear_svf_set_xover(&simper[0][i][0], srate, f, 0.7071068, 0); // lp layer0 + linear_svf_set_xover(&simper[0][i][1], srate, f, 0.7071068, 0); // lp layer1 + linear_svf_set_xover(&simper[1][i][0], srate, f, 0.7071068, 1); // hp layer0 + linear_svf_set_xover(&simper[1][i][1], srate, f, 0.7071068, 1); // hp layer1 + linear_svf_set_xover(&simper[2][i][0], srate, f, 0.7071068, 2); // bp layer0 + linear_svf_set_xover(&simper[2][i][1], srate, f, 0.7071068, 2); // bp layer1 } void ZaMultiCompX2Plugin::run_lr4(int i, float in, float *outlo, float *outhi) { - *outlo = run_linear_svf_xover(&simper[0][i], in, 1., 0.); - *outhi = run_linear_svf_xover(&simper[1][i], in, 0., 1.); + float lo, hi, ap; +/* + lo = run_linear_svf_xover(&simper[0][i][0], in); + ap = run_linear_svf_xover(&simper[2][i][0], lo); + *outlo = run_linear_svf_xover(&simper[0][i][1], ap); + + hi = run_linear_svf_xover(&simper[1][i][0], in); + ap = run_linear_svf_xover(&simper[2][i][1], hi); + *outhi = run_linear_svf_xover(&simper[1][i][1], ap); +*/ + ap = run_linear_svf_xover(&simper[2][i][0], in); + lo = run_linear_svf_xover(&simper[0][i][0], ap); + *outlo = run_linear_svf_xover(&simper[0][i][1], lo); + + ap = run_linear_svf_xover(&simper[2][i][1], in); + hi = run_linear_svf_xover(&simper[1][i][0], ap); + *outhi = run_linear_svf_xover(&simper[1][i][1], hi); } void ZaMultiCompX2Plugin::run_comp(int k, float inL, float inR, float *outL, float *outR) diff --git a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp index b89f2f9..f775e0c 100644 --- a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp +++ b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp @@ -175,14 +175,15 @@ Stereo version of ZaMultiComp, with individual threshold controls for each band struct linear_svf { double k; double g; + double m0, m1, m2; double s[2]; }; - struct linear_svf simper[2][MAX_FILT]; - void linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance); + struct linear_svf simper[3][MAX_FILT][2]; + void linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance, int hi); void linear_svf_reset(struct linear_svf *self); - float run_linear_svf_xover(struct linear_svf *self, float in, float mixlow, float mixhigh); + float run_linear_svf_xover(struct linear_svf *self, float in); // ------------------------------------------------------------------- private: -- cgit v1.2.3