diff options
author | Damien Zammit <damien@zamaudio.com> | 2015-11-01 03:08:27 +1100 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2015-11-01 03:08:27 +1100 |
commit | 13b5c73a47a68852cffd24a1c2af99cfe3199058 (patch) | |
tree | be5d17875421cbcd47e533c032f24993c40382d9 /plugins/ZaMaximX2 | |
parent | b4d8ca27dc9946b8d15a17932efbd764b23f236e (diff) |
Third generation DSP for maximiser
Signed-off-by: Damien Zammit <damien@zamaudio.com>
Diffstat (limited to 'plugins/ZaMaximX2')
-rw-r--r-- | plugins/ZaMaximX2/ZaMaximX2Plugin.cpp | 102 | ||||
-rw-r--r-- | plugins/ZaMaximX2/ZaMaximX2Plugin.hpp | 8 | ||||
-rw-r--r-- | plugins/ZaMaximX2/ZaMaximX2UI.cpp | 10 |
3 files changed, 50 insertions, 70 deletions
diff --git a/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp b/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp index d6a8396..c206879 100644 --- a/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp +++ b/plugins/ZaMaximX2/ZaMaximX2Plugin.cpp @@ -42,7 +42,7 @@ void ZaMaximX2Plugin::initParameter(uint32_t index, Parameter& parameter) parameter.unit = "ms"; parameter.ranges.def = 25.0f; parameter.ranges.min = 1.0f; - parameter.ranges.max = 100.0f; + parameter.ranges.max = 500.0f; break; case paramCeiling: parameter.hints = kParameterIsAutomable; @@ -97,8 +97,8 @@ void ZaMaximX2Plugin::loadProgram(uint32_t index) { switch(index) { case 0: - release = 25.0; - ceiling = -3.0; + release = 150.0; + ceiling = -0.5; thresdb = 0.0; gainred = 0.0; outlevel = -45.0; @@ -166,14 +166,12 @@ void ZaMaximX2Plugin::activate() 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; + z[0][i] = 0.f; + z[1][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; + smoothold[0] = smoothold[1] = 0.f; + envold[0] = envold[1] = 0.f; } void ZaMaximX2Plugin::deactivate() @@ -242,80 +240,64 @@ 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 absx[2]; double c[2]; - double xmax[2]; - double emax[2]; - double eavg[2]; - double g[2]; double srate = getSampleRate(); - double alpha = 1.0001; - double aa = 1. - pow( (alpha - 1.f) / alpha, 1. / ( N + 1. ) ); - double a; - double beta = 0.f; - for (i = 0; i < M; i++) { - beta += pow(1. - aa, N + 1. - i); - } - beta /= M; + double tau = exp(-1000. / (release*srate)); + double env[2]; + double smooth[2]; + double targetgain = from_dB(ceiling); double inL, inR; for (i = 0; i < frames; i++) { inL = inputs[0][i]; inR = inputs[1][i]; + + // input 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]); - xmax[0] = maxsample(&cn[0][0]); - - if (xmax[0] < emaxn[0][pose[0]]) { - a = 1000 / (release * srate); + + // Envelope extractor + if (envold[0] > absx[0]) { + env[0] = tau * envold[0] + (1. - tau) * absx[0]; } else { - a = aa; + env[0] = absx[0]; } - 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) { - g[0] = 1.; + if (envold[1] > absx[0]) { + env[1] = tau * envold[1] + (1. - tau) * absx[0]; } else { - g[0] = MIN(1., from_dB(thresdb) / eavg[0]); + env[1] = absx[0]; } - - 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); + + // control gain calculator + c[0] = 1. / (1. / targetgain + (1. - 1. / targetgain)*env[0]); + c[0] *= MIN(1., env[0] / from_dB(thresdb)); + c[1] = 1. / (1. / targetgain + (1. - 1. / targetgain)*env[1]); + c[1] *= MIN(1., env[1] / from_dB(thresdb)); + + // smoother + if (c[0] > smoothold[0]) { + smooth[0] = smoothold[0]*tau + c[0]*(1.-tau); } else { - a = aa; + smooth[0] = c[0]; } - 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.; + if (c[1] > smoothold[1]) { + smooth[1] = smoothold[1]*tau + c[1]*(1.-tau); } else { - g[1] = MIN(1., from_dB(thresdb) / eavg[1]); + smooth[1] = c[1]; } - gainred = MAX(-to_dB(g[0]), -to_dB(g[1])); - - 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.)); + outputs[0][i] = (float)clip(normalise(z[0][posz[0]] * smooth[0], 0.)); + outputs[1][i] = (float)clip(normalise(z[1][posz[1]] * smooth[1], 0.)); - outlevel = to_dB(MAX(fabs(eavg[0]), fabs(eavg[1]))) + (ceiling - thresdb); + outlevel = to_dB(MAX(fabs(outputs[0][i]), fabs(outputs[1][i]))) + (ceiling - thresdb); pushsample(&z[0][0], sanitize_denormal(inL), &posz[0]); pushsample(&z[1][0], sanitize_denormal(inR), &posz[1]); - 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]); + smoothold[0] = sanitize_denormal(smooth[0]); + smoothold[1] = sanitize_denormal(smooth[1]); + envold[0] = sanitize_denormal(env[0]); + envold[1] = sanitize_denormal(env[1]); } } diff --git a/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp b/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp index feff4f5..c5b1782 100644 --- a/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp +++ b/plugins/ZaMaximX2/ZaMaximX2Plugin.hpp @@ -121,12 +121,10 @@ 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]; + int posz[2]; double z[2][MAX_SAMPLES]; - double emax_old[2]; - double eavg_old[2]; + double smoothold[2]; + double envold[2]; }; // ----------------------------------------------------------------------- diff --git a/plugins/ZaMaximX2/ZaMaximX2UI.cpp b/plugins/ZaMaximX2/ZaMaximX2UI.cpp index d62378f..03e6150 100644 --- a/plugins/ZaMaximX2/ZaMaximX2UI.cpp +++ b/plugins/ZaMaximX2/ZaMaximX2UI.cpp @@ -47,9 +47,9 @@ ZaMaximX2UI::ZaMaximX2UI() fKnobRelease = new ImageKnob(this, knobImage); fKnobRelease->setAbsolutePos(27, 46); fKnobRelease->setId(ZaMaximX2Plugin::paramRelease); - fKnobRelease->setRange(1.0f, 100.0f); + fKnobRelease->setRange(1.0f, 500.0f); fKnobRelease->setStep(1.0f); - fKnobRelease->setDefault(25.0f); + fKnobRelease->setDefault(150.0f); fKnobRelease->setRotationAngle(240); fKnobRelease->setCallback(this); @@ -67,7 +67,7 @@ ZaMaximX2UI::ZaMaximX2UI() fKnobCeiling->setId(ZaMaximX2Plugin::paramCeiling); fKnobCeiling->setRange(-30.0f, 0.0f); fKnobCeiling->setStep(0.1f); - fKnobCeiling->setDefault(-3.0f); + fKnobCeiling->setDefault(-0.5f); fKnobCeiling->setRotationAngle(240); fKnobCeiling->setCallback(this); @@ -112,9 +112,9 @@ void ZaMaximX2UI::programLoaded(uint32_t index) { switch(index) { case 0: - fKnobRelease->setValue(1.0f); + fKnobRelease->setValue(150.0f); fKnobThresh->setValue(0.0f); - fKnobCeiling->setValue(-6.0f); + fKnobCeiling->setValue(-0.5f); break; } } |