|
- /*
- * ZamEQ2 2 band parametric equaliser
- * Copyright (C) 2014 Damien Zammit <damien@zamaudio.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the doc/GPL.txt file.
- */
-
- #include "ZamEQ2Plugin.hpp"
-
- START_NAMESPACE_DISTRHO
-
- // -----------------------------------------------------------------------
-
- ZamEQ2Plugin::ZamEQ2Plugin()
- : Plugin(paramCount, 1, 0) // 1 program, 0 states
- {
- // set default values
- d_setProgram(0);
- }
-
- // -----------------------------------------------------------------------
- // Init
-
- void ZamEQ2Plugin::d_initParameter(uint32_t index, Parameter& parameter)
- {
- switch (index)
- {
- case paramGain1:
- parameter.hints = PARAMETER_IS_AUTOMABLE;
- parameter.name = "Boost/Cut 1";
- parameter.symbol = "boost1";
- parameter.unit = "dB";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = -50.0f;
- parameter.ranges.max = 20.0f;
- break;
- case paramQ1:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Bandwidth 1";
- parameter.symbol = "bw1";
- parameter.unit = " ";
- parameter.ranges.def = 2.0f;
- parameter.ranges.min = 0.1f;
- parameter.ranges.max = 6.0f;
- break;
- case paramFreq1:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Frequency 1";
- parameter.symbol = "f1";
- parameter.unit = "Hz";
- parameter.ranges.def = 500.0f;
- parameter.ranges.min = 20.0f;
- parameter.ranges.max = 14000.0f;
- break;
- case paramGain2:
- parameter.hints = PARAMETER_IS_AUTOMABLE;
- parameter.name = "Boost/Cut 2";
- parameter.symbol = "boost2";
- parameter.unit = "dB";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = -50.0f;
- parameter.ranges.max = 20.0f;
- break;
- case paramQ2:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Bandwidth 2";
- parameter.symbol = "bw2";
- parameter.unit = " ";
- parameter.ranges.def = 2.0f;
- parameter.ranges.min = 0.1f;
- parameter.ranges.max = 6.0f;
- break;
- case paramFreq2:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Frequency 2";
- parameter.symbol = "f2";
- parameter.unit = "Hz";
- parameter.ranges.def = 3000.0f;
- parameter.ranges.min = 20.0f;
- parameter.ranges.max = 14000.0f;
- break;
- case paramGainL:
- parameter.hints = PARAMETER_IS_AUTOMABLE;
- parameter.name = "Boost/Cut L";
- parameter.symbol = "boostl";
- parameter.unit = "dB";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = -50.0f;
- parameter.ranges.max = 20.0f;
- break;
- case paramFreqL:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Frequency L";
- parameter.symbol = "fl";
- parameter.unit = "Hz";
- parameter.ranges.def = 250.0f;
- parameter.ranges.min = 20.0f;
- parameter.ranges.max = 14000.0f;
- break;
- case paramGainH:
- parameter.hints = PARAMETER_IS_AUTOMABLE;
- parameter.name = "Boost/Cut H";
- parameter.symbol = "boosth";
- parameter.unit = "dB";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = -50.0f;
- parameter.ranges.max = 20.0f;
- break;
- case paramFreqH:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_LOGARITHMIC;
- parameter.name = "Frequency H";
- parameter.symbol = "fh";
- parameter.unit = "Hz";
- parameter.ranges.def = 8000.0f;
- parameter.ranges.min = 20.0f;
- parameter.ranges.max = 14000.0f;
- break;
- case paramMaster:
- parameter.hints = PARAMETER_IS_AUTOMABLE;
- parameter.name = "Master Gain";
- parameter.symbol = "master";
- parameter.unit = "dB";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = -12.0f;
- parameter.ranges.max = 12.0f;
- break;
- case paramTogglePeaks:
- parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_BOOLEAN;
- parameter.name = "Peaks ON";
- parameter.symbol = "peaks";
- parameter.unit = " ";
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = 0.0f;
- parameter.ranges.max = 1.0f;
- break;
- }
- }
-
- void ZamEQ2Plugin::d_initProgramName(uint32_t index, d_string& programName)
- {
- if (index != 0)
- return;
-
- programName = "Default";
- }
-
- // -----------------------------------------------------------------------
- // Internal data
-
- float ZamEQ2Plugin::d_getParameterValue(uint32_t index) const
- {
- switch (index)
- {
- case paramGain1:
- return gain1;
- break;
- case paramQ1:
- return q1;
- break;
- case paramFreq1:
- return freq1;
- break;
- case paramGain2:
- return gain2;
- break;
- case paramQ2:
- return q2;
- break;
- case paramFreq2:
- return freq2;
- break;
- case paramGainL:
- return gainl;
- break;
- case paramFreqL:
- return freql;
- break;
- case paramGainH:
- return gainh;
- break;
- case paramFreqH:
- return freqh;
- break;
- case paramMaster:
- return master;
- break;
- case paramTogglePeaks:
- return togglepeaks;
- break;
- default:
- return 0.0f;
- }
- }
-
- void ZamEQ2Plugin::d_setParameterValue(uint32_t index, float value)
- {
- switch (index)
- {
- case paramGain1:
- gain1 = value;
- break;
- case paramQ1:
- q1 = value;
- break;
- case paramFreq1:
- freq1 = value;
- break;
- case paramGain2:
- gain2 = value;
- break;
- case paramQ2:
- q2 = value;
- break;
- case paramFreq2:
- freq2 = value;
- break;
- case paramGainL:
- gainl = value;
- break;
- case paramFreqL:
- freql = value;
- break;
- case paramGainH:
- gainh = value;
- break;
- case paramFreqH:
- freqh = value;
- break;
- case paramMaster:
- master = value;
- break;
- case paramTogglePeaks:
- togglepeaks = value;
- break;
- }
- }
-
- void ZamEQ2Plugin::d_setProgram(uint32_t index)
- {
- if (index != 0)
- return;
-
- /* Default parameter values */
- gain1 = 0.0f;
- q1 = 1.0f;
- freq1 = 500.0f;
- gain2 = 0.0f;
- q2 = 1.0f;
- freq2 = 3000.0f;
- gainl = 0.0f;
- freql = 250.0f;
- gainh = 0.0f;
- freqh = 8000.0f;
- master = 0.f;
- togglepeaks = 0.f;
-
- /* Default variable values */
-
- /* reset filter values */
- d_activate();
- }
-
- // -----------------------------------------------------------------------
- // Process
-
- void ZamEQ2Plugin::d_activate()
- {
- int i;
- 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;
- }
- }
-
- 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;
- }
- }
-
- float ZamEQ2Plugin::run_filter(int i, int ch, double in)
- {
- double out;
- in = sanitize_denormal(in);
- 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] + 1e-20f;
- out = sanitize_denormal(out);
- x2[ch][i] = sanitize_denormal(x1[ch][i]);
- y2[ch][i] = sanitize_denormal(y1[ch][i]);
- x1[ch][i] = in;
- y1[ch][i] = out;
-
- return (float) out;
- }
-
- void ZamEQ2Plugin::d_run(const float** inputs, float** outputs, uint32_t frames)
- {
- float srate = d_getSampleRate();
-
- 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];
- in = sanitize_denormal(in);
-
- //lowshelf
- tmpl = (gainl == 0.f) ? in : run_filter(0, 0, in);
-
- //highshelf
- tmph = (gainh == 0.f) ? tmpl : run_filter(3, 0, tmpl);
-
- //parametric1
- tmp = (gain1 == 0.f) ? tmph : run_filter(1, 0, tmph);
-
- //parametric2
- tmpl = (gain2 == 0.f) ? tmp : run_filter(2, 0, tmp);
-
- outputs[0][i] = inputs[0][i];
- outputs[0][i] = (float) tmpl;
- outputs[0][i] *= from_dB(master);
- }
- }
-
- // -----------------------------------------------------------------------
-
- Plugin* createPlugin()
- {
- return new ZamEQ2Plugin();
- }
-
- // -----------------------------------------------------------------------
-
- END_NAMESPACE_DISTRHO
|