summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2016-04-20 12:47:30 +1000
committerDamien Zammit <damien@zamaudio.com>2016-04-20 12:47:30 +1000
commit63e6ea7e43949ec907f78cf58931c1343d0ed00e (patch)
tree3ede9498045edc44bc174e370717e77bd62044cf /plugins
parentfa60d65bd5c0c5523ebc83de20c8ae8d140139d5 (diff)
Fixed MAJOR bug with ZaMaximX2 limiter, now no clipping step and
improved algorithm for limiting Signed-off-by: Damien Zammit <damien@zamaudio.com>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ZaMaximX2/ZaMaximX2Plugin.cpp132
-rw-r--r--plugins/ZaMaximX2/ZaMaximX2Plugin.hpp19
2 files changed, 65 insertions, 86 deletions
diff --git a/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp b/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp
index d6a8396..6f41ccd 100644
--- a/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp
+++ b/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp
@@ -165,15 +165,19 @@ void ZaMaximX2Plugin::activate()
int i;
gainred = 0.0f;
outlevel = -45.0f;
- for (i = 0; i < MAX_SAMPLES; i++) {
- cn[0][i] = z[0][i] = emaxn[0][i] = 0.f;
- cn[1][i] = z[1][i] = emaxn[1][i] = 0.f;
+ for (i = 0; i < MAX_DELAY; i++) {
+ cn[0][i] = z[0][i] = 0.f;
+ cn[1][i] = z[1][i] = 0.f;
+ }
+ for (i = 0; i < MAX_AVG; i++) {
+ emaxn[1][i] = 0.f;
+ emaxn[0][i] = 0.f;
}
posz[0] = posz[1] = 0;
pose[0] = pose[1] = 0;
posc[0] = posc[1] = 0;
emax_old[0] = emax_old[1] = 0.f;
- eavg_old[0] = eavg_old[1] = 0.f;
+ e_old[0] = e_old[1] = 0.f;
}
void ZaMaximX2Plugin::deactivate()
@@ -181,49 +185,31 @@ void ZaMaximX2Plugin::deactivate()
activate();
}
-double ZaMaximX2Plugin::normalise(double in, double gainr)
+double ZaMaximX2Plugin::normalise(double in)
{
if (ceiling < thresdb) {
return in;
}
- return from_dB(-(thresdb - ceiling + gainr)) * in;
-}
-
-double ZaMaximX2Plugin::clip(double in)
-{
- if (in < -1.f)
- in = -1.f;
- if (in > 1.f)
- in = 1.f;
- return in;
+ return from_dB(-thresdb + ceiling) * in;
}
-void ZaMaximX2Plugin::pushsample(double in[], double sample, int *pos)
+void ZaMaximX2Plugin::pushsample(double in[], double sample, int *pos, int maxsamples)
{
(*pos)++;
- if (*pos >= MAX_SAMPLES) {
+ if (*pos >= maxsamples) {
*pos = 0;
}
in[*pos] = sample;
}
-double ZaMaximX2Plugin::getoldsample(double in[], int pos)
-{
- int p = pos - 1;
- if (p < 0) {
- p = MAX_SAMPLES;
- }
- return in[p];
-}
-
double ZaMaximX2Plugin::avgall(double in[])
{
int i;
double avg = 0.f;
- for (i = 0; i < MAX_SAMPLES; i++) {
+ for (i = 0; i < MAX_AVG; i++) {
avg += in[i];
}
- avg = avg / (double)(MAX_SAMPLES);
+ avg = avg / (double)(MAX_AVG);
return avg;
}
@@ -231,7 +217,7 @@ double ZaMaximX2Plugin::maxsample(double in[])
{
int i;
double max = 0.f;
- for (i = 0; i < MAX_SAMPLES; i++) {
+ for (i = 0; i < MAX_DELAY; i++) {
if (fabs(in[i]) > fabs(max)) {
max = in[i];
}
@@ -242,81 +228,77 @@ double ZaMaximX2Plugin::maxsample(double in[])
void ZaMaximX2Plugin::run(const float** inputs, float** outputs, uint32_t frames)
{
uint32_t i;
- double N = (float)MAX_SAMPLES;
- double M = (float)MAX_SAMPLES;
+ double N = (double)MAX_DELAY;
+ double navg = (double)MAX_AVG;
double absx[2];
double c[2];
double xmax[2];
double emax[2];
- double eavg[2];
+ double avge[2];
double g[2];
double srate = getSampleRate();
double alpha = 1.0001;
- double aa = 1. - pow( (alpha - 1.f) / alpha, 1. / ( N + 1. ) );
+ double aatt = 1. - pow( (alpha - 1.) / alpha, 1. / ( N + 1. ) );
double a;
- double beta = 0.f;
- for (i = 0; i < M; i++) {
- beta += pow(1. - aa, N + 1. - i);
+ double beta;
+ double e;
+ double target;
+ double max;
+ double maxx = 0;
+ beta = 0.;
+ for (i = 0; i < navg; i++) {
+ beta += pow(1. - aatt, N + 1. - i);
}
- beta /= M;
+ beta /= navg;
double inL, inR;
for (i = 0; i < frames; i++) {
inL = inputs[0][i];
inR = inputs[1][i];
- absx[0] = MAX(fabs(inL), fabs(inR));
- c[0] = MAX(absx[0], (absx[0]-beta*eavg_old[0]) / (1. - beta));
- pushsample(&cn[0][0], sanitize_denormal(c[0]), &posc[0]);
+ absx[0] = fmaxf(fabsf(inL), fabsf(inR));
+ c[0] = fmaxf(absx[0], (absx[0]-beta*e_old[0]) / (1. - beta));
xmax[0] = maxsample(&cn[0][0]);
+ target = xmax[0];
- if (xmax[0] < emaxn[0][pose[0]]) {
- a = 1000 / (release * srate);
+ if (target > emax_old[0]) {
+ a = aatt;
} else {
- a = aa;
+ a = 1000 / (release * srate);
}
- emax[0] = a*xmax[0] + (1. - a)*emaxn[0][pose[0]];
- pushsample(&emaxn[0][0], sanitize_denormal(emax[0]), &pose[0]);
- eavg[0] = avgall(&emaxn[0][0]);
- if (eavg[0] == 0.f) {
+ emax[0] = (a*target + (1. - a)*emax_old[0]);
+//push
+ e = avgall(&emaxn[0][0]);
+ avge[0] = e;
+ avge[0] += emaxn[0][(pose[0]+1+MAX_AVG) % MAX_AVG]/(navg+1.);
+ e = avge[0];
+
+ if (e == 0.f) {
g[0] = 1.;
} else {
- g[0] = MIN(1., from_dB(thresdb) / eavg[0]);
+ g[0] = sanitize_denormal(fminf(1., from_dB(thresdb) / e));
}
- absx[1] = absx[0];
- c[1] = MAX(absx[1], (absx[1]-beta*eavg_old[1]) / (1. - beta));
- pushsample(&cn[1][0], sanitize_denormal(c[1]), &posc[1]);
- xmax[1] = maxsample(&cn[1][0]);
-
- if (xmax[1] < emaxn[1][pose[1]]) {
- a = 1000 / (release * srate);
- } else {
- a = aa;
- }
- emax[1] = a*xmax[1] + (1. - a)*emaxn[1][pose[1]];
- pushsample(&emaxn[1][0], sanitize_denormal(emax[1]), &pose[1]);
- eavg[1] = avgall(&emaxn[1][0]);
- if (eavg[1] == 0.f) {
- g[1] = 1.;
- } else {
- g[1] = MIN(1., from_dB(thresdb) / eavg[1]);
- }
+ gainred = -to_dB(g[0]);
- gainred = MAX(-to_dB(g[0]), -to_dB(g[1]));
+ outputs[0][i] = z[0][(posz[0]+1+MAX_DELAY) % MAX_DELAY] * g[0] * from_dB(ceiling - thresdb);
+ outputs[1][i] = z[1][(posz[1]+1+MAX_DELAY) % MAX_DELAY] * g[0] * from_dB(ceiling - thresdb);
- outputs[0][i] = (float)clip(normalise(z[0][posz[0]] * g[0], 0.));
- outputs[1][i] = (float)clip(normalise(z[1][posz[1]] * g[1], 0.));
+ max = fmaxf(fabsf(outputs[0][i]), fabsf(outputs[1][i]));
- outlevel = to_dB(MAX(fabs(eavg[0]), fabs(eavg[1]))) + (ceiling - thresdb);
- pushsample(&z[0][0], sanitize_denormal(inL), &posz[0]);
- pushsample(&z[1][0], sanitize_denormal(inR), &posz[1]);
+ if (maxx < max)
+ maxx = max;
+
+ pushsample(&emaxn[0][0], sanitize_denormal(emax[0]), &pose[0], MAX_AVG);
+ pushsample(&cn[0][0], sanitize_denormal(c[0]), &posc[0], MAX_DELAY);
+ pushsample(&z[0][0], sanitize_denormal(inL), &posz[0], MAX_DELAY);
+ pushsample(&z[1][0], sanitize_denormal(inR), &posz[1], MAX_DELAY);
emax_old[0] = sanitize_denormal(emax[0]);
- eavg_old[0] = sanitize_denormal(eavg[0]);
- emax_old[1] = sanitize_denormal(emax[1]);
- eavg_old[1] = sanitize_denormal(eavg[1]);
+ e_old[0] = sanitize_denormal(e);
}
+ outlevel = (maxx == 0.f) ? -160. : to_dB(maxx);
+ if (outlevel > 0.) printf("g=%f out=%f\n", gainred, outlevel);
}
// -----------------------------------------------------------------------
diff --git a/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp b/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp
index 68cf7c7..b162d2e 100644
--- a/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp
+++ b/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp
@@ -20,10 +20,8 @@
#include "DistrhoPlugin.hpp"
-#define MAX_SAMPLES 64
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-#define MIN(a,b) ((a) > (b) ? (b) : (a))
-
+#define MAX_DELAY 24
+#define MAX_AVG 12
START_NAMESPACE_DISTRHO
@@ -119,12 +117,11 @@ protected:
void activate() override;
void deactivate() override;
void run(const float** inputs, float** outputs, uint32_t frames) override;
- double normalise(double in, double gainr);
+ double normalise(double in);
double clip(double in);
double avgall(double in[]);
double maxsample(double in[]);
- void pushsample(double in[], double sample, int *pos);
- void pushall(double in[], double sample, int *pos);
+ void pushsample(double in[], double sample, int *pos, int maxsamples);
double getoldsample(double in[], int pos);
// -------------------------------------------------------------------
@@ -132,11 +129,11 @@ protected:
private:
float release,ceiling,thresdb,gainred,outlevel;//parameters
int pose[2], posz[2], posc[2];
- double cn[2][MAX_SAMPLES];
- double emaxn[2][MAX_SAMPLES];
- double z[2][MAX_SAMPLES];
+ double cn[2][MAX_DELAY];
+ double emaxn[2][MAX_AVG];
+ double z[2][MAX_DELAY];
double emax_old[2];
- double eavg_old[2];
+ double e_old[2];
};
// -----------------------------------------------------------------------