summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2014-04-21 19:20:46 +1000
committerDamien Zammit <damien@zamaudio.com>2014-04-21 19:20:46 +1000
commita94ef95fb155a608f85df1ed6154858820fb0b3e (patch)
treed400f295bb103a6f1baaf9651c659328ae98ca46
parenta6f1d885fec6080bb9fa8116c61c3393a7cf36fd (diff)
Changed ZamEQ2 DSP to Zolzer model
Signed-off-by: Damien Zammit <damien@zamaudio.com>
-rw-r--r--plugins/ZamEQ2/ZamEQ2Plugin.cpp278
-rw-r--r--plugins/ZamEQ2/ZamEQ2Plugin.hpp26
2 files changed, 120 insertions, 184 deletions
diff --git a/plugins/ZamEQ2/ZamEQ2Plugin.cpp b/plugins/ZamEQ2/ZamEQ2Plugin.cpp
index 27693ca..f193d43 100644
--- a/plugins/ZamEQ2/ZamEQ2Plugin.cpp
+++ b/plugins/ZamEQ2/ZamEQ2Plugin.cpp
@@ -282,18 +282,12 @@ void ZamEQ2Plugin::d_setProgram(uint32_t index)
void ZamEQ2Plugin::d_activate()
{
- x1=x2=y1=y2=0.f;
- x1a=x2a=y1a=y2a=0.f;
- a0x=a1x=a2x=b0x=b1x=b2x=gainx=0.f;
- a0y=a1y=a2y=b0y=b1y=b2y=gainy=0.f;
- zln1=zln2=zld1=zld2=0.f;
- zhn1=zhn2=zhd1=zhd2=0.f;
-
int i;
- for (i = 0; i < 3; ++i) {
- Bl[i] = Al[i] = Bh[i] = Ah[i] = 0.f;
- Bl[i] = Al[i] = Bh[i] = Ah[i] = 0.f;
- Bl[i] = Al[i] = Bh[i] = Ah[i] = 0.f;
+ for (i = 0; i < MAX_FILT; ++i) {
+ x1[0][i] = x2[0][i] = 0.f;
+ y1[0][i] = y2[0][i] = 0.f;
+ b0[0][i] = b1[0][i] = b2[0][i] = 0.f;
+ a1[0][i] = a2[0][i] = 0.f;
}
}
@@ -302,180 +296,130 @@ void ZamEQ2Plugin::d_deactivate()
// all values to zero
}
-void ZamEQ2Plugin::peq(double G0, double G, double GB, double w0, double Dw,
- double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, double *gn) {
-
- double F,G00,F00,num,den,G1,G01,G11,F01,F11,W2,Dww,C,D,B,A;
- F = fabs(G*G - GB*GB);
- G00 = fabs(G*G - G0*G0);
- F00 = fabs(GB*GB - G0*G0);
- num = G0*G0 * (w0*w0 - M_PI*M_PI)*(w0*w0 - M_PI*M_PI)
- + G*G * F00 * M_PI*M_PI * Dw*Dw / F;
- den = (w0*w0 - M_PI*M_PI)*(w0*w0 - M_PI*M_PI)
- + F00 * M_PI*M_PI * Dw*Dw / F;
- G1 = sqrt(num/den);
- G01 = fabs(G*G - G0*G1);
- G11 = fabs(G*G - G1*G1);
- F01 = fabs(GB*GB - G0*G1);
- F11 = fabs(GB*GB - G1*G1);
- W2 = sqrt(G11 / G00) * tan(w0/2.f)*tan(w0/2.f);
- Dww = (1.f + sqrt(F00 / F11) * W2) * tan(Dw/2.f);
- C = F11 * Dww*Dww - 2.f * W2 * (F01 - sqrt(F00 * F11));
- D = 2.f * W2 * (G01 - sqrt(G00 * G11));
- A = sqrt((C + D) / F);
- B = sqrt((G*G * C + GB*GB * D) / F);
- *gn = G1;
- *b0 = (G1 + G0*W2 + B) / (1.f + W2 + A);
- *b1 = -2.f*(G1 - G0*W2) / (1.f + W2 + A);
- *b2 = (G1 - B + G0*W2) / (1.f + W2 + A);
- *a0 = 1.f;
- *a1 = -2.f*(1.f - W2) / (1.f + W2 + A);
- *a2 = (1 + W2 - A) / (1.f + W2 + A);
-
- *b1 = sanitize_denormal(*b1);
- *b2 = sanitize_denormal(*b2);
- *a0 = sanitize_denormal(*a0);
- *a1 = sanitize_denormal(*a1);
- *a2 = sanitize_denormal(*a2);
- *gn = sanitize_denormal(*gn);
- if (!std::isnormal(*b0)) { *b0 = 1.f; }
+
+void ZamEQ2Plugin::lowshelf(int i, int ch, float srate, float fc, float g)
+{
+ float k, v0;
+
+ k = tanf(M_PI * fc / srate);
+ v0 = powf(10., g / 20.);
+
+ if (g < 0.f) {
+ // LF cut
+ float denom = v0 + sqrt(2. * v0)*k + k*k;
+ b0[ch][i] = v0 * (1. + sqrt(2.)*k + k*k) / denom;
+ b1[ch][i] = 2. * v0*(k*k - 1.) / denom;
+ b2[ch][i] = v0 * (1. - sqrt(2.)*k + k*k) / denom;
+ a1[ch][i] = 2. * (k*k - v0) / denom;
+ a2[ch][i] = (v0 - sqrt(2. * v0)*k + k*k) / denom;
+ } else {
+ // LF boost
+ float denom = 1. + sqrt(2.)*k + k*k;
+ b0[ch][i] = (1. + sqrt(2. * v0)*k + v0*k*k) / denom;
+ b1[ch][i] = 2. * (v0*k*k - 1.) / denom;
+ b2[ch][i] = (1. - sqrt(2. * v0)*k + v0*k*k) / denom;
+ a1[ch][i] = 2. * (k*k - 1.) / denom;
+ a2[ch][i] = (1. - sqrt(2.)*k + k*k) / denom;
+ }
+}
+
+void ZamEQ2Plugin::highshelf(int i, int ch, float srate, float fc, float g)
+{
+ float k, v0;
+
+ k = tanf(M_PI * fc / srate);
+ v0 = powf(10., g / 20.);
+
+ if (g < 0.f) {
+ // HF cut
+ float denom = 1. + sqrt(2. * v0)*k + v0*k*k;
+ b0[ch][i] = v0*(1. + sqrt(2.)*k + k*k) / denom;
+ b1[ch][i] = 2. * v0*(k*k - 1.) / denom;
+ b2[ch][i] = v0*(1. - sqrt(2.)*k + k*k) / denom;
+ a1[ch][i] = 2. * (v0*k*k - 1.) / denom;
+ a2[ch][i] = (1. - sqrt(2. * v0)*k + v0*k*k) / denom;
+ } else {
+ // HF boost
+ float denom = 1. + sqrt(2.)*k + k*k;
+ b0[ch][i] = (v0 + sqrt(2. * v0)*k + k*k) / denom;
+ b1[ch][i] = 2. * (k*k - v0) / denom;
+ b2[ch][i] = (v0 - sqrt(2. * v0)*k + k*k) / denom;
+ a1[ch][i] = 2. * (k*k - 1.) / denom;
+ a2[ch][i] = (1. - sqrt(2.)*k + k*k) / denom;
+ }
+}
+
+void ZamEQ2Plugin::peq(int i, int ch, float srate, float fc, float g, float bw)
+{
+ float k, v0, q;
+
+ k = tanf(M_PI * fc / srate);
+ v0 = powf(10., g / 20.);
+ q = powf(2., 1./bw)/(powf(2., bw) - 1.); //q from octave bw
+
+ if (g < 0.f) {
+ // cut
+ float denom = 1. + k/(v0*q) + k*k;
+ b0[ch][i] = (1. + k/q + k*k) / denom;
+ b1[ch][i] = 2. * (k*k - 1.) / denom;
+ b2[ch][i] = (1. - k/q + k*k) / denom;
+ a1[ch][i] = b1[ch][i];
+ a2[ch][i] = (1. - k/(v0*q) + k*k) / denom;
+ } else {
+ // boost
+ float denom = 1. + k/q + k*k;
+ b0[ch][i] = (1. + k*v0/q + k*k) / denom;
+ b1[ch][i] = 2. * (k*k - 1.) / denom;
+ b2[ch][i] = (1. - k*v0/q + k*k) / denom;
+ a1[ch][i] = b1[ch][i];
+ a2[ch][i] = (1. - k/q + k*k) / denom;
+ }
}
-void ZamEQ2Plugin::lowshelfeq(double, double G, double, double w0, double, double q, double B[], double A[]) {
- double alpha,b0,b1,b2,a0,a1,a2;
- G = powf(10.f,G/20.f);
- double AA = sqrt(G);
-
- alpha = sin(w0)/2.f * sqrt( (AA + 1.f/AA)*(1.f/q - 1.f) + 2.f );
- b0 = AA*( (AA+1.f) - (AA-1.f)*cos(w0) + 2.f*sqrt(AA)*alpha );
- b1 = 2.f*AA*( (AA-1.f) - (AA+1.f)*cos(w0) );
- b2 = AA*( (AA+1.f) - (AA-1.f)*cos(w0) - 2.f*sqrt(AA)*alpha );
- a0 = (AA+1.f) + (AA-1.f)*cos(w0) + 2.f*sqrt(AA)*alpha;
- a1 = -2.f*( (AA-1.f) + (AA+1.f)*cos(w0) );
- a2 = (AA+1.f) + (AA-1.f)*cos(w0) - 2.f*sqrt(AA)*alpha;
-
- B[0] = b0/a0;
- B[1] = b1/a0;
- B[2] = b2/a0;
- A[0] = 1.f;
- A[1] = a1/a0;
- A[2] = a2/a0;
-}
-
-void ZamEQ2Plugin::highshelfeq(double, double G, double, double w0, double, double q, double B[], double A[]) {
- double alpha,b0,b1,b2,a0,a1,a2;
- G = powf(10.f,G/20.f);
- double AA = sqrt(G);
-
- alpha = sin(w0)/2.f * sqrt( (AA + 1.f/AA)*(1.f/q - 1.f) + 2.f );
- b0 = AA*( (AA+1.f) + (AA-1.f)*cos(w0) + 2.f*sqrt(AA)*alpha );
- b1 = -2.f*AA*( (AA-1.f) + (AA+1.f)*cos(w0) );
- b2 = AA*( (AA+1.f) + (AA-1.f)*cos(w0) - 2.f*sqrt(AA)*alpha );
- a0 = (AA+1.f) - (AA-1.f)*cos(w0) + 2.f*sqrt(AA)*alpha;
- a1 = 2.f*( (AA-1.f) - (AA+1.f)*cos(w0) );
- a2 = (AA+1.f) - (AA-1.f)*cos(w0) - 2.f*sqrt(AA)*alpha;
-
- B[0] = b0/a0;
- B[1] = b1/a0;
- B[2] = b2/a0;
- A[0] = 1.f;
- A[1] = a1/a0;
- A[2] = a2/a0;
+float ZamEQ2Plugin::run_filter(int i, int ch, double in)
+{
+ double out;
+ out = in * b0[ch][i] + x1[ch][i] * b1[ch][i]
+ + x2[ch][i] * b2[ch][i]
+ - y1[ch][i] * a1[ch][i]
+ - y2[ch][i] * a2[ch][i];
+ x2[ch][i] = x1[ch][i];
+ y2[ch][i] = y1[ch][i];
+ x1[ch][i] = in;
+ y1[ch][i] = out;
+
+ return (float) out;
}
void ZamEQ2Plugin::d_run(float** inputs, float** outputs, uint32_t frames)
{
float srate = d_getSampleRate();
- double dcgain = 1.f;
-
- double qq1 = pow(2.0, 1.0/q1)/(pow(2.0, q1) - 1.0); //q from octave bw
- double boost1 = from_dB(gain1);
- double fc1 = freq1 / srate;
- double w01 = fc1*2.f*M_PI;
- double bwgain1 = sqrt(boost1);
- double bw1 = fc1 / qq1;
-
- double qq2 = pow(2.0, 1.0/q2)/(pow(2.0, q2) - 1.0); //q from octave bw
- double boost2 = from_dB(gain2);
- double fc2 = freq2 / srate;
- double w02 = fc2*2.f*M_PI;
- double bwgain2 = sqrt(boost2);
- double bw2 = fc2 / qq2;
-
- double boostl = from_dB(gainl);
- double All = sqrt(boostl);
- double bwl = 2.f*M_PI*freql/ srate;
- double bwgaindbl = to_dB(All);
-
- double boosth = from_dB(gainh);
- double Ahh = sqrt(boosth);
- double bwh = 2.f*M_PI*freqh/ srate;
- double bwgaindbh = to_dB(Ahh);
-
- peq(dcgain,boost1,bwgain1,w01,bw1,&a0x,&a1x,&a2x,&b0x,&b1x,&b2x,&gainx);
- peq(dcgain,boost2,bwgain2,w02,bw2,&a0y,&a1y,&a2y,&b0y,&b1y,&b2y,&gainy);
- lowshelfeq(0.f,gainl,bwgaindbl,2.f*M_PI*freql/srate,bwl,1.0f,Bl,Al);
- highshelfeq(0.f,gainh,bwgaindbh,2.f*M_PI*freqh/srate,bwh,1.0f,Bh,Ah);
+
+ lowshelf(0, 0, srate, freql, gainl);
+ peq(1, 0, srate, freq1, gain1, q1);
+ peq(2, 0, srate, freq2, gain2, q2);
+ highshelf(3, 0, srate, freqh, gainh);
for (uint32_t i = 0; i < frames; i++) {
double tmp,tmpl, tmph;
double in = inputs[0][i];
- x1 = sanitize_denormal(x1);
- x2 = sanitize_denormal(x2);
- y1 = sanitize_denormal(y1);
- y2 = sanitize_denormal(y2);
- x1a = sanitize_denormal(x1a);
- x2a = sanitize_denormal(x2a);
- y1a = sanitize_denormal(y1a);
- y2a = sanitize_denormal(y2a);
- zln1 = sanitize_denormal(zln1);
- zln2 = sanitize_denormal(zln2);
- zld1 = sanitize_denormal(zld1);
- zld2 = sanitize_denormal(zld2);
- zhn1 = sanitize_denormal(zhn1);
- zhn2 = sanitize_denormal(zhn2);
- zhd1 = sanitize_denormal(zhd1);
- zhd2 = sanitize_denormal(zhd2);
in = sanitize_denormal(in);
//lowshelf
- tmpl = in * Bl[0] +
- zln1 * Bl[1] +
- zln2 * Bl[2] -
- zld1 * Al[1] -
- zld2 * Al[2];
- zln2 = zln1;
- zld2 = zld1;
- zln1 = in;
- zld1 = tmpl;
+ tmpl = run_filter(0, 0, in);
//highshelf
- tmph = tmpl * Bh[0] +
- zhn1 * Bh[1] +
- zhn2 * Bh[2] -
- zhd1 * Ah[1] -
- zhd2 * Ah[2];
- zhn2 = zhn1;
- zhd2 = zhd1;
- zhn1 = tmpl;
- zhd1 = tmph;
-
+ tmph = run_filter(1, 0, tmpl);
+
//parametric1
- tmp = tmph * b0x + x1 * b1x + x2 * b2x - y1 * a1x - y2 * a2x;
- x2 = x1;
- y2 = y1;
- x1 = tmph;
- y1 = tmp;
-
- //parametric2
- outputs[0][i] = inputs[0][i];
- outputs[0][i] = tmp * b0y + x1a * b1y + x2a * b2y - y1a * a1y - y2a * a2y;
- x2a = x1a;
- y2a = y1a;
- x1a = tmp;
- y1a = outputs[0][i];
+ tmp = run_filter(2, 0, tmph);
- outputs[0][i] *= from_dB(master);
+ //parametric2
+ tmpl = run_filter(3, 0, tmp);
+
+ outputs[0][i] = inputs[0][i];
+ outputs[0][i] = (float) tmpl;
+ outputs[0][i] *= from_dB(master);
}
}
diff --git a/plugins/ZamEQ2/ZamEQ2Plugin.hpp b/plugins/ZamEQ2/ZamEQ2Plugin.hpp
index 4493121..7ff0521 100644
--- a/plugins/ZamEQ2/ZamEQ2Plugin.hpp
+++ b/plugins/ZamEQ2/ZamEQ2Plugin.hpp
@@ -20,6 +20,8 @@
#include "DistrhoPlugin.hpp"
+#define MAX_FILT 4
+
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------
@@ -118,27 +120,17 @@ protected:
void d_deactivate() override;
void d_run(float** inputs, float** outputs, uint32_t frames) override;
- void peq(double G0, double G, double GB, double w0, double Dw,
- double *a0, double *a1, double *a2,
- double *b0, double *b1, double *b2, double *gn);
- void lowshelfeq(double G0, double G, double GB,
- double w0, double Dw, double q, double B[], double A[]);
- void highshelfeq(double G0, double G, double GB,
- double w0, double Dw, double q, double B[], double A[]);
+ void peq(int i, int ch, float srate, float fc, float g, float bw);
+ void lowshelf(int i, int ch, float srate, float fc, float g);
+ void highshelf(int i, int ch, float srate, float fc, float g);
+ float run_filter(int i, int ch, double in);
+ double x1[1][MAX_FILT], x2[1][MAX_FILT], y1[1][MAX_FILT], y2[1][MAX_FILT];
+ double b0[1][MAX_FILT], b1[1][MAX_FILT], b2[1][MAX_FILT];
+ double a1[1][MAX_FILT], a2[1][MAX_FILT];
// -------------------------------------------------------------------
private:
float gain1,q1,freq1,gain2,q2,freq2,gainl,freql,gainh,freqh,master,togglepeaks; //parameters
- double x1,x2,y1,y2;
- double x1a,x2a,y1a,y2a;
- double zln1,zln2,zld1,zld2;
- double zhn1,zhn2,zhd1,zhd2;
- double a0x,a1x,a2x,b0x,b1x,b2x,gainx;
- double a0y,a1y,a2y,b0y,b1y,b2y,gainy;
- double Bl[3];
- double Al[3];
- double Bh[3];
- double Ah[3];
};
// -----------------------------------------------------------------------