summaryrefslogtreecommitdiff
path: root/plugins/ZaMultiCompX2
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2014-04-11 16:27:50 +1000
committerDamien Zammit <damien@zamaudio.com>2014-04-11 16:27:50 +1000
commite3ace76151c24b6bc0e0d39df51288c3b9e7c28b (patch)
tree91453b6aa9abdcd887241bdd7d1701148f0827da /plugins/ZaMultiCompX2
parent3bedeb23d8e3fc9d75f31db9e2554a4161c6d7a0 (diff)
Added ZaMultiCompX2 DSP
Signed-off-by: Damien Zammit <damien@zamaudio.com>
Diffstat (limited to 'plugins/ZaMultiCompX2')
-rw-r--r--plugins/ZaMultiCompX2/DistrhoPluginInfo.h4
-rw-r--r--plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp253
-rw-r--r--plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp45
3 files changed, 197 insertions, 105 deletions
diff --git a/plugins/ZaMultiCompX2/DistrhoPluginInfo.h b/plugins/ZaMultiCompX2/DistrhoPluginInfo.h
index 043709f..a42533c 100644
--- a/plugins/ZaMultiCompX2/DistrhoPluginInfo.h
+++ b/plugins/ZaMultiCompX2/DistrhoPluginInfo.h
@@ -23,8 +23,8 @@
#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_SYNTH 0
-#define DISTRHO_PLUGIN_NUM_INPUTS 1
-#define DISTRHO_PLUGIN_NUM_OUTPUTS 1
+#define DISTRHO_PLUGIN_NUM_INPUTS 2
+#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_LATENCY 0
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
diff --git a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp
index 430da6a..164620a 100644
--- a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp
+++ b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.cpp
@@ -195,6 +195,15 @@ void ZaMultiCompX2Plugin::d_initParameter(uint32_t index, Parameter& parameter)
parameter.ranges.min = -12.0f;
parameter.ranges.max = 12.0f;
break;
+ case paramStereoDet:
+ parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_BOOLEAN;
+ parameter.name = "Detection (MAX/avg)";
+ parameter.symbol = "stereodet";
+ parameter.unit = " ";
+ parameter.ranges.def = 1.0f;
+ parameter.ranges.min = 0.0f;
+ parameter.ranges.max = 1.0f;
+ break;
}
}
@@ -264,6 +273,9 @@ float ZaMultiCompX2Plugin::d_getParameterValue(uint32_t index) const
case paramGlobalGain:
return globalgain;
break;
+ case paramStereoDet:
+ return stereodet;
+ break;
default:
return 0.0f;
}
@@ -324,6 +336,9 @@ void ZaMultiCompX2Plugin::d_setParameterValue(uint32_t index, float value)
case paramGlobalGain:
globalgain = value;
break;
+ case paramStereoDet:
+ stereodet = value;
+ break;
}
}
@@ -350,6 +365,7 @@ void ZaMultiCompX2Plugin::d_setProgram(uint32_t index)
toggle[1] = 0.0f;
toggle[2] = 0.0f;
globalgain = 0.0f;
+ stereodet = 1.0f;
/* Default variable values */
@@ -362,15 +378,17 @@ void ZaMultiCompX2Plugin::d_setProgram(uint32_t index)
void ZaMultiCompX2Plugin::d_activate()
{
- int i;
- for (i = 0; i < MAX_COMP; i++) {
- old_yl[i]=old_y1[i]=0.f;
- }
+ int i,j;
+ for (i = 0; i < MAX_COMP; i++)
+ for (j = 0; j < 2; j++)
+ old_yl[j][i]=old_y1[j][i]=0.f;
for (i = 0; i < MAX_FILT; i++) {
- a0[i] = a1[i] = a2[i] = 0.f;
- b1[i] = b2[i] = 0.f;
- w1[i] = w2[i] = 0.f;
+ for (j = 0; j < 2; j++) {
+ a0[j][i] = a1[j][i] = a2[j][i] = 0.f;
+ b1[j][i] = b2[j][i] = 0.f;
+ w1[j][i] = w2[j][i] = 0.f;
+ }
}
}
@@ -379,20 +397,20 @@ void ZaMultiCompX2Plugin::d_deactivate()
// all values to zero
}
-float ZaMultiCompX2Plugin::run_filter(int i, float in)
+float ZaMultiCompX2Plugin::run_filter(int i, int ch, float in)
{
in = sanitize_denormal(in);
- w1[i] = sanitize_denormal(w1[i]);
- w2[i] = sanitize_denormal(w2[i]);
+ w1[ch][i] = sanitize_denormal(w1[ch][i]);
+ w2[ch][i] = sanitize_denormal(w2[ch][i]);
- float tmp = in - w1[i] * b1[i] - w2[i] * b2[i];
- float out = tmp * a0[i] + w1[i] * a1[i] + w2[i] * a2[i];
- w2[i] = w1[i];
- w1[i] = tmp;
+ float tmp = in - w1[ch][i] * b1[ch][i] - w2[ch][i] * b2[ch][i];
+ float out = tmp * a0[ch][i] + w1[ch][i] * a1[ch][i] + w2[ch][i] * a2[ch][i];
+ w2[ch][i] = w1[ch][i];
+ w1[ch][i] = tmp;
return out;
}
-void ZaMultiCompX2Plugin::set_lp_coeffs(float fc, float q, float sr, int i, float gain=1.0)
+void ZaMultiCompX2Plugin::set_lp_coeffs(float fc, float q, float sr, int i, int ch, float gain=1.0)
{
float omega=(float)(2.f*M_PI*fc/sr);
float sn=sin(omega);
@@ -400,13 +418,13 @@ void ZaMultiCompX2Plugin::set_lp_coeffs(float fc, float q, float sr, int i, floa
float alpha=(float)(sn/(2.f*q));
float inv=(float)(1.0/(1.0+alpha));
- a2[i] = a0[i] = (float)(gain*inv*(1.f - cs)*0.5f);
- a1[i] = a0[i] + a0[i];
- b1[i] = (float)(-2.f*cs*inv);
- b2[i] = (float)((1.f - alpha)*inv);
+ a2[ch][i] = a0[ch][i] = (float)(gain*inv*(1.f - cs)*0.5f);
+ a1[ch][i] = a0[ch][i] + a0[ch][i];
+ b1[ch][i] = (float)(-2.f*cs*inv);
+ b2[ch][i] = (float)((1.f - alpha)*inv);
}
-void ZaMultiCompX2Plugin::set_hp_coeffs(float fc, float q, float sr, int i, float gain=1.0)
+void ZaMultiCompX2Plugin::set_hp_coeffs(float fc, float q, float sr, int i, int ch, float gain=1.0)
{
float omega=(float)(2.f*M_PI*fc/sr);
float sn=sin(omega);
@@ -414,59 +432,102 @@ void ZaMultiCompX2Plugin::set_hp_coeffs(float fc, float q, float sr, int i, floa
float alpha=(float)(sn/(2.f*q));
float inv=(float)(1.f/(1.f+alpha));
- a0[i] = (float)(gain*inv*(1.f + cs)/2.f);
- a1[i] = -2.f * a0[i];
- a2[i] = a0[i];
- b1[i] = (float)(-2.f*cs*inv);
- b2[i] = (float)((1.f - alpha)*inv);
+ a0[ch][i] = (float)(gain*inv*(1.f + cs)/2.f);
+ a1[ch][i] = -2.f * a0[ch][i];
+ a2[ch][i] = a0[ch][i];
+ b1[ch][i] = (float)(-2.f*cs*inv);
+ b2[ch][i] = (float)((1.f - alpha)*inv);
}
-float ZaMultiCompX2Plugin::run_comp(int k, float in)
+float ZaMultiCompX2Plugin::run_comp(int k, int ch, float inL, float inR)
{
float srate = d_getSampleRate();
float makeupgain = from_dB(makeup[k]);
float width=(knee-0.99f)*6.f;
float attack_coeff = exp(-1000.f/(attack * srate));
float release_coeff = exp(-1000.f/(release * srate));
+ int stereolink = (stereodet > 0.5f) ? STEREOLINK_MAX : STEREOLINK_AVERAGE;
float cdb=0.f;
- float gain = 1.f;
- float xg, xl, yg, yl, y1;
+ float Lgain = 1.f;
+ float Rgain = 1.f;
+ float Lxg, Lyg;
+ float Rxg, Ryg;
+ float Lxl, Lyl, Ly1;
+ float Rxl, Ryl, Ry1;
float out;
- yg=0.f;
- xg = (in==0.f) ? -160.f : to_dB(fabs(in));
- xg = sanitize_denormal(xg);
-
-
- if (2.f*(xg-thresdb)<-width) {
- yg = xg;
- } else if (2.f*fabs(xg-thresdb)<=width) {
- yg = xg + (1.f/ratio-1.f)*(xg-thresdb+width/2.f)*(xg-thresdb+width/2.f)/(2.f*width);
- } else if (2.f*(xg-thresdb)>width) {
- yg = thresdb + (xg-thresdb)/ratio;
+ Lyg = Ryg = 0.f;
+ Lxg = (inL==0.f) ? -160.f : to_dB(fabs(inL));
+ Rxg = (inR==0.f) ? -160.f : to_dB(fabs(inR));
+ Lxg = sanitize_denormal(Lxg);
+ Rxg = sanitize_denormal(Rxg);
+
+
+ if (2.f*(Lxg-thresdb)<-width) {
+ Lyg = Lxg;
+ } else if (2.f*fabs(Lxg-thresdb)<=width) {
+ Lyg = Lxg + (1.f/ratio-1.f)*(Lxg-thresdb+width/2.f)*(Lxg-thresdb+width/2.f)/(2.f*width);
+ } else if (2.f*(Lxg-thresdb)>width) {
+ Lyg = thresdb + (Lxg-thresdb)/ratio;
}
+
+ Lyg = sanitize_denormal(Lyg);
+
+ if (2.f*(Rxg-thresdb)<-width) {
+ Ryg = Rxg;
+ } else if (2.f*fabs(Rxg-thresdb)<=width) {
+ Ryg = Rxg + (1.f/ratio-1.f)*(Rxg-thresdb+width/2.f)*(Rxg-thresdb+width/2.f)/(2.f*width);
+ } else if (2.f*(Rxg-thresdb)>width) {
+ Ryg = thresdb + (Rxg-thresdb)/ratio;
+ }
+
+ Ryg = sanitize_denormal(Ryg);
+
+ if (stereolink == STEREOLINK_MAX) {
+ Lxl = Rxl = fmaxf(Lxg - Lyg, Rxg - Ryg);
+ } else {
+ Lxl = Rxl = (Lxg - Lyg + Rxg - Ryg) / 2.f;
+ }
+
+ old_y1[0][k] = sanitize_denormal(old_y1[0][k]);
+ old_y1[1][k] = sanitize_denormal(old_y1[1][k]);
+ old_yl[0][k] = sanitize_denormal(old_yl[0][k]);
+ old_yl[1][k] = sanitize_denormal(old_yl[1][k]);
+
+
+ Ly1 = fmaxf(Lxl, release_coeff * old_y1[0][k]+(1.f-release_coeff)*Lxl);
+ Lyl = attack_coeff * old_yl[0][k]+(1.f-attack_coeff)*Ly1;
+ Ly1 = sanitize_denormal(Ly1);
+ Lyl = sanitize_denormal(Lyl);
+
+ cdb = -Lyl;
+ Lgain = from_dB(cdb);
+
+ gainr[k] = Lyl;
- yg = sanitize_denormal(yg);
-
- xl = xg - yg;
- old_y1[k] = sanitize_denormal(old_y1[k]);
- old_yl[k] = sanitize_denormal(old_yl[k]);
-
- y1 = fmaxf(xl, release_coeff * old_y1[k]+(1.f-release_coeff)*xl);
- yl = attack_coeff * old_yl[k]+(1.f-attack_coeff)*y1;
- y1 = sanitize_denormal(y1);
- yl = sanitize_denormal(yl);
-
- cdb = -yl;
- gain = from_dB(cdb);
- gainr[k] = yl;
-
- out = in;
- out *= gain * makeupgain;
-
- old_yl[k] = yl;
- old_y1[k] = y1;
+ Ry1 = fmaxf(Rxl, release_coeff * old_y1[1][k]+(1.f-release_coeff)*Rxl);
+ Ryl = attack_coeff * old_yl[1][k]+(1.f-attack_coeff)*Ry1;
+ Ry1 = sanitize_denormal(Ry1);
+ Ryl = sanitize_denormal(Ryl);
+
+ cdb = -Ryl;
+ Rgain = from_dB(cdb);
+
+ //gainr_r = Ryl;
+
+ if (ch == 0) {
+ out = inL;
+ out *= Lgain * makeupgain;
+ } else {
+ out = inR;
+ out *= Rgain * makeupgain;
+ }
+
+ old_yl[0][k] = Lyl;
+ old_yl[1][k] = Ryl;
+ old_y1[0][k] = Ly1;
+ old_y1[1][k] = Ry1;
return out;
}
@@ -478,32 +539,60 @@ void ZaMultiCompX2Plugin::d_run(float** inputs, float** outputs, uint32_t frames
int tog2 = (toggle[1] > 0.f) ? 1 : 0;
int tog3 = (toggle[2] > 0.f) ? 1 : 0;
- set_lp_coeffs(xover1, ONEOVERROOT2, srate, 0);
- set_lp_coeffs(xover1, ONEOVERROOT2, srate, 1);
- set_hp_coeffs(xover1, ONEOVERROOT2, srate, 2);
- set_hp_coeffs(xover1, ONEOVERROOT2, srate, 3);
- set_lp_coeffs(xover2, ONEOVERROOT2, srate, 4);
- set_lp_coeffs(xover2, ONEOVERROOT2, srate, 5);
- set_hp_coeffs(xover2, ONEOVERROOT2, srate, 6);
- set_hp_coeffs(xover2, ONEOVERROOT2, srate, 7);
+ set_lp_coeffs(xover1, ONEOVERROOT2, srate, 0, 0);
+ set_lp_coeffs(xover1, ONEOVERROOT2, srate, 1, 0);
+ set_hp_coeffs(xover1, ONEOVERROOT2, srate, 2, 0);
+ set_hp_coeffs(xover1, ONEOVERROOT2, srate, 3, 0);
+ set_lp_coeffs(xover2, ONEOVERROOT2, srate, 4, 0);
+ set_lp_coeffs(xover2, ONEOVERROOT2, srate, 5, 0);
+ set_hp_coeffs(xover2, ONEOVERROOT2, srate, 6, 0);
+ set_hp_coeffs(xover2, ONEOVERROOT2, srate, 7, 0);
+
+ set_lp_coeffs(xover1, ONEOVERROOT2, srate, 0, 1);
+ set_lp_coeffs(xover1, ONEOVERROOT2, srate, 1, 1);
+ set_hp_coeffs(xover1, ONEOVERROOT2, srate, 2, 1);
+ set_hp_coeffs(xover1, ONEOVERROOT2, srate, 3, 1);
+ set_lp_coeffs(xover2, ONEOVERROOT2, srate, 4, 1);
+ set_lp_coeffs(xover2, ONEOVERROOT2, srate, 5, 1);
+ set_hp_coeffs(xover2, ONEOVERROOT2, srate, 6, 1);
+ set_hp_coeffs(xover2, ONEOVERROOT2, srate, 7, 1);
for (uint32_t i = 0; i < frames; ++i) {
- float tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, fil1, fil2, fil3, fil4;
-
- outputs[0][i] = inputs[0][i];
- fil1 = run_filter(0, inputs[0][i]);
- tmp1 = run_filter(1, fil1);
- tmp2 = tog1 ? run_comp(0, tmp1) : tmp1;
- fil2 = run_filter(2, inputs[0][i]);
- tmp3 = run_filter(3, fil2);
- fil3 = run_filter(4, tmp3);
- tmp4 = run_filter(5, fil3);
- tmp3 = tog2 ? run_comp(1, tmp4) : tmp4;
- fil4 = run_filter(6, inputs[0][i]);
- tmp5 = run_filter(7, fil4);
- tmp6 = tog3 ? run_comp(2, tmp5) : tmp5;
- outputs[0][i] = tmp2 + tmp3 + tmp6;
+ float tmp1[2], tmp2[2], tmp3[2], tmp4[2], tmp5[2], tmp6[2];
+ float fil1[2], fil2[2], fil3[2], fil4[2];
+
+ // Interleaved channel processing
+ outputs[0][i] = inputs[0][i];
+ outputs[1][i] = inputs[1][i];
+ fil1[0] = run_filter(0, 0, inputs[0][i]);
+ fil1[1] = run_filter(0, 1, inputs[1][i]);
+ tmp1[0] = run_filter(1, 0, fil1[0]);
+ tmp1[1] = run_filter(1, 1, fil1[1]);
+ tmp2[0] = tog1 ? run_comp(0, 0, tmp1[0], tmp1[1]) : tmp1[0];
+ tmp2[1] = tog1 ? run_comp(0, 1, tmp1[0], tmp1[1]) : tmp1[1];
+
+ fil2[0] = run_filter(2, 0, inputs[0][i]);
+ fil2[1] = run_filter(2, 1, inputs[1][i]);
+ tmp3[0] = run_filter(3, 0, fil2[0]);
+ tmp3[1] = run_filter(3, 1, fil2[1]);
+ fil3[0] = run_filter(4, 0, tmp3[0]);
+ fil3[1] = run_filter(4, 1, tmp3[1]);
+ tmp4[0] = run_filter(5, 0, fil3[0]);
+ tmp4[1] = run_filter(5, 1, fil3[1]);
+ tmp3[0] = tog2 ? run_comp(1, 0, tmp4[0], tmp4[1]) : tmp4[0];
+ tmp3[1] = tog2 ? run_comp(1, 1, tmp4[0], tmp4[1]) : tmp4[1];
+
+ fil4[0] = run_filter(6, 0, inputs[0][i]);
+ fil4[1] = run_filter(6, 1, inputs[1][i]);
+ tmp5[0] = run_filter(7, 0, fil4[0]);
+ tmp5[1] = run_filter(7, 1, fil4[1]);
+ tmp6[0] = tog3 ? run_comp(2, 0, tmp5[0], tmp5[1]) : tmp5[0];
+ tmp6[1] = tog3 ? run_comp(2, 1, tmp5[0], tmp5[1]) : tmp5[1];
+
+ outputs[0][i] = tmp2[0] + tmp3[0] + tmp6[0];
+ outputs[1][i] = tmp2[1] + tmp3[1] + tmp6[1];
outputs[0][i] *= from_dB(globalgain);
+ outputs[1][i] *= from_dB(globalgain);
}
}
diff --git a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp
index 1bf77b2..a491292 100644
--- a/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp
+++ b/plugins/ZaMultiCompX2/ZaMultiCompX2Plugin.hpp
@@ -15,17 +15,19 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
-#ifndef ZAMULTICOMPPLUGIN_HPP_INCLUDED
-#define ZAMULTICOMPPLUGIN_HPP_INCLUDED
+#ifndef ZAMULTICOMPX2PLUGIN_HPP_INCLUDED
+#define ZAMULTICOMPX2PLUGIN_HPP_INCLUDED
+
+#include "DistrhoPlugin.hpp"
+
+START_NAMESPACE_DISTRHO
#define MAX_FILT 8
#define MAX_COMP 3
#define ONEOVERROOT2 0.7071068f
#define ROOT2 1.4142135f
-
-#include "DistrhoPlugin.hpp"
-
-START_NAMESPACE_DISTRHO
+#define STEREOLINK_MAX 1
+#define STEREOLINK_AVERAGE 0
// -----------------------------------------------------------------------
@@ -55,6 +57,7 @@ public:
paramToggle2,
paramToggle3,
+ paramStereoDet,
paramGlobalGain,
paramCount
};
@@ -88,7 +91,7 @@ protected:
long d_getUniqueId() const noexcept override
{
- return d_cconst('Z', 'M', 'C', 'P');
+ return d_cconst('Z', 'M', 'M', '2');
}
// -------------------------------------------------------------------
@@ -124,10 +127,10 @@ protected:
return (20.f*log10(g));
}
- float run_comp(int k, float in);
- float run_filter(int i, float in);
- void set_lp_coeffs(float fc, float q, float sr, int i, float gain);
- void set_hp_coeffs(float fc, float q, float sr, int i, float gain);
+ float run_comp(int k, int ch, float inL, float inR);
+ float run_filter(int i, int ch, float in);
+ void set_lp_coeffs(float fc, float q, float sr, int i, int ch, float gain);
+ void set_hp_coeffs(float fc, float q, float sr, int i, int ch, float gain);
void d_activate() override;
void d_deactivate() override;
@@ -136,19 +139,19 @@ protected:
// -------------------------------------------------------------------
private:
- float attack,release,knee,ratio,thresdb,makeup[MAX_COMP],globalgain;
+ float attack,release,knee,ratio,thresdb,makeup[MAX_COMP],globalgain,stereodet;
float gainr[MAX_COMP],toggle[MAX_COMP],xover1,xover2;
- float old_yl[MAX_COMP], old_y1[MAX_COMP];
+ float old_yl[2][MAX_COMP], old_y1[2][MAX_COMP];
// Crossover filter coefficients
- float a0[MAX_FILT];
- float a1[MAX_FILT];
- float a2[MAX_FILT];
- float b1[MAX_FILT];
- float b2[MAX_FILT];
+ float a0[2][MAX_FILT];
+ float a1[2][MAX_FILT];
+ float a2[2][MAX_FILT];
+ float b1[2][MAX_FILT];
+ float b2[2][MAX_FILT];
//Crossover filter states
- float w1[MAX_FILT];
- float w2[MAX_FILT];
+ float w1[2][MAX_FILT];
+ float w2[2][MAX_FILT];
};
@@ -156,4 +159,4 @@ private:
END_NAMESPACE_DISTRHO
-#endif // ZAMULTICOMP_HPP_INCLUDED
+#endif