Merge branch 'calf-updates'

* calf-updates:
  Use generic single VU meter in some dynamics plugins as well. (cherry picked from commit 50505a2d304555bb3b766c43af5cd1a27de331e2)
  Refactor metering code out of distortion plugins. (cherry picked from commit 84d873861da7b4ad205061b00fcc9f73c47140b6)
  More variable initialisation. (cherry picked from commit 40bbe048f27fc7190001383f93097127119ee667)
  Initialise old-state variables to prevent "stuck" graphs. (cherry picked from commit 2a795084ee9e73712a4b690b84158cc745ff1d30)
(cherry picked from commit cb52114261)
This commit is contained in:
Tobias Doerffel
2010-08-31 11:40:52 +02:00
parent 8ebdee61f6
commit 380b0bfa9b
7 changed files with 271 additions and 263 deletions

View File

@@ -29,7 +29,6 @@
#include "giface.h"
#include "metadata.h"
#include "loudness.h"
#include "primitives.h"
namespace calf_plugins {

View File

@@ -29,6 +29,7 @@
#include "giface.h"
#include "loudness.h"
#include "metadata.h"
#include "plugin_tools.h"
namespace calf_plugins {
@@ -97,8 +98,7 @@ public:
class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
private:
typedef compressor_audio_module AM;
uint32_t clip_in, clip_out;
float meter_in, meter_out;
stereo_in_out_metering<compressor_metadata> meters;
gain_reduction_audio_module compressor;
public:
typedef std::complex<double> cfloat;
@@ -138,8 +138,7 @@ private:
CalfScModes sc_mode;
mutable CalfScModes sc_mode_old, sc_mode_old1;
float f1_active, f2_active;
uint32_t clip_in, clip_out;
float meter_in, meter_out;
stereo_in_out_metering<sidechaincompressor_metadata> meters;
gain_reduction_audio_module compressor;
dsp::biquad_d2<float> f1L, f1R, f2L, f2R;
public:
@@ -225,8 +224,7 @@ public:
class gate_audio_module: public audio_module<gate_metadata>, public line_graph_iface {
private:
typedef gate_audio_module AM;
uint32_t clip_in, clip_out;
float meter_in, meter_out;
stereo_in_out_metering<gate_metadata> meters;
expander_audio_module gate;
public:
typedef std::complex<double> cfloat;
@@ -266,8 +264,7 @@ private:
CalfScModes sc_mode;
mutable CalfScModes sc_mode_old, sc_mode_old1;
float f1_active, f2_active;
uint32_t clip_in, clip_out;
float meter_in, meter_out;
stereo_in_out_metering<sidechaingate_metadata> meters;
expander_audio_module gate;
dsp::biquad_d2<float> f1L, f1R, f2L, f2R;
public:

View File

@@ -28,6 +28,7 @@
#include "audio_fx.h"
#include "giface.h"
#include "metadata.h"
#include "plugin_tools.h"
namespace calf_plugins {
@@ -37,8 +38,8 @@ private:
float hp_pre_freq_old, lp_pre_freq_old;
float hp_post_freq_old, lp_post_freq_old;
float p_level_old, p_freq_old, p_q_old;
uint32_t clip_in, clip_out;
float meter_in, meter_out, meter_drive;
stereo_in_out_metering<saturator_metadata> meters;
float meter_drive;
dsp::biquad_d2<float> lp[2][4], hp[2][4];
dsp::biquad_d2<float> p[2];
dsp::tap_distortion dist[2];
@@ -57,8 +58,8 @@ public:
class exciter_audio_module: public audio_module<exciter_metadata> {
private:
float freq_old;
uint32_t clip_in, clip_out;
float meter_in, meter_out, meter_drive;
stereo_in_out_metering<exciter_metadata> meters;
float meter_drive;
dsp::biquad_d2<float> hp[2][4];
dsp::tap_distortion dist[2];
public:
@@ -76,8 +77,8 @@ public:
class bassenhancer_audio_module: public audio_module<bassenhancer_metadata> {
private:
float freq_old;
uint32_t clip_in, clip_out;
float meter_in, meter_out, meter_drive;
stereo_in_out_metering<exciter_metadata> meters;
float meter_drive;
dsp::biquad_d2<float> lp[2][4];
dsp::tap_distortion dist[2];
public:

View File

@@ -0,0 +1,85 @@
/* Calf DSP plugin pack
* Tools to use in plugins
*
* Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02111-1307, USA.
*/
#ifndef CALF_PLUGIN_TOOLS_H
#define CALF_PLUGIN_TOOLS_H
#include <config.h>
#include "giface.h"
#include "vumeter.h"
namespace calf_plugins {
/// Base class for universal stereo level metering
struct stereo_in_out_metering_base
{
dsp::vumeter vumeter_in, vumeter_out;
stereo_in_out_metering_base()
{
reset();
}
void reset()
{
vumeter_in.reset();
vumeter_out.reset();
}
};
/// Universal stereo level metering for a specific plugin
template<class Metadata>
class stereo_in_out_metering: public stereo_in_out_metering_base
{
public:
inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples)
{
if (params[Metadata::param_meter_in] || params[Metadata::param_clip_in]) {
if (inputs)
vumeter_in.update_stereo(inputs[0] ? inputs[0] + offset : NULL, inputs[1] ? inputs[1] + offset : NULL, nsamples);
else
vumeter_in.update_zeros(nsamples);
if (params[Metadata::param_meter_in])
*params[Metadata::param_meter_in] = vumeter_in.level;
if (params[Metadata::param_clip_in])
*params[Metadata::param_clip_in] = vumeter_in.clip > 0 ? 1.f : 0.f;
}
if (params[Metadata::param_meter_out] || params[Metadata::param_clip_out]) {
if (outputs)
vumeter_out.update_stereo(outputs[0] ? outputs[0] + offset : NULL, outputs[1] ? outputs[1] + offset : NULL, nsamples);
else
vumeter_out.update_zeros(nsamples);
if (params[Metadata::param_meter_out])
*params[Metadata::param_meter_out] = vumeter_out.level;
if (params[Metadata::param_clip_out])
*params[Metadata::param_clip_out] = vumeter_out.clip > 0 ? 1.f : 0.f;
}
}
void bypassed(float *const *params, unsigned int nsamples)
{
reset();
process(params, NULL, NULL, 0, nsamples);
}
};
};
#endif

View File

@@ -0,0 +1,95 @@
/* Calf DSP Library
* Peak metering facilities.
*
* Copyright (C) 2007 Krzysztof Foltman
*
* 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, or (at your option)
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef __CALF_VUMETER_H
#define __CALF_VUMETER_H
namespace dsp {
/// Peak meter class
struct vumeter
{
/// Measured signal level
float level;
/// Falloff of signal level (b1 coefficient of a 1-pole filter)
float falloff;
/// Clip indicator (set to 1 when |value| >= 1, fading otherwise)
float clip;
/// Falloff of clip indicator (b1 coefficient of a 1-pole filter); set to 1 if no falloff is required (manual reset of clip indicator)
float clip_falloff;
vumeter()
{
falloff = 0.999f;
clip_falloff = 0.999f;
reset();
}
void reset()
{
level = 0;
clip = 0;
}
/// Update peak meter based on input signal
inline void update(const float *src, unsigned int len)
{
update_stereo(src, NULL, len);
}
/// Update peak meter based on louder of two input signals
inline void update_stereo(const float *src1, const float *src2, unsigned int len)
{
// "Age" the old level by falloff^length
level *= pow(falloff, len);
// Same for clip level (using different fade constant)
clip *= pow(clip_falloff, len);
dsp::sanitize(level);
dsp::sanitize(clip);
// Process input samples - to get peak value, take a max of all values in the input signal and "aged" old peak
// Clip is set to 1 if any sample is out-of-range, if no clip occurs, the "aged" value is assumed
if (src1)
run_sample_loop(src1, len);
if (src2)
run_sample_loop(src2, len);
}
inline void run_sample_loop(const float *src, unsigned int len)
{
float tmp = level;
for (unsigned int i = 0; i < len; i++) {
float sig = fabs(src[i]);
tmp = std::max(tmp, sig);
if (sig >= 1.f)
clip = 1.f;
}
level = tmp;
}
/// Update clip meter as if update was called with all-zero input signal
inline void update_zeros(unsigned int len)
{
level *= pow((double)falloff, (double)len);
clip *= pow((double)clip_falloff, (double)len);
dsp::sanitize(level);
dsp::sanitize(clip);
}
};
};
#endif

View File

@@ -363,6 +363,7 @@ compressor_audio_module::compressor_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
meters.reset();
}
void compressor_audio_module::activate()
@@ -371,10 +372,7 @@ void compressor_audio_module::activate()
// set all filters and strips
compressor.activate();
params_changed();
meter_in = 0.f;
meter_out = 0.f;
clip_in = 0.f;
clip_out = 0.f;
meters.reset();
}
void compressor_audio_module::deactivate()
{
@@ -395,6 +393,8 @@ void compressor_audio_module::set_sample_rate(uint32_t sr)
uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
bool bypass = *params[param_bypass] > 0.5f;
numsamples += offset;
if(bypass) {
@@ -405,16 +405,10 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples,
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.bypassed(params, orig_numsamples);
} else {
// process
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
compressor.update_curve();
while(offset < numsamples) {
@@ -439,26 +433,11 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples,
outs[0][offset] = outL;
outs[1][offset] = outR;
// clip LED's
if(std::max(fabs(inL), fabs(inR)) > 1.f) {
clip_in = srate >> 3;
}
if(std::max(fabs(outL), fabs(outR)) > 1.f) {
clip_out = srate >> 3;
}
// rise up out meter
meter_in = std::max(fabs(inL), fabs(inR));;
meter_out = std::max(fabs(outL), fabs(outR));;
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
}
// draw meters
SET_IF_CONNECTED(clip_in)
SET_IF_CONNECTED(clip_out)
SET_IF_CONNECTED(meter_in)
SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_compression] != NULL) {
@@ -512,6 +491,12 @@ sidechaincompressor_audio_module::sidechaincompressor_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
f1_freq_old1 = 0.f;
f2_freq_old1 = 0.f;
f1_level_old1 = 0.f;
f2_level_old1 = 0.f;
sc_mode_old1 = WIDEBAND;
meters.reset();
}
void sidechaincompressor_audio_module::activate()
@@ -520,10 +505,7 @@ void sidechaincompressor_audio_module::activate()
// set all filters and strips
compressor.activate();
params_changed();
meter_in = 0.f;
meter_out = 0.f;
clip_in = 0.f;
clip_out = 0.f;
meters.reset();
}
void sidechaincompressor_audio_module::deactivate()
{
@@ -680,6 +662,8 @@ void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr)
uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
bool bypass = *params[param_bypass] > 0.5f;
numsamples += offset;
if(bypass) {
@@ -690,15 +674,10 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.bypassed(params, orig_numsamples);
} else {
// process
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
compressor.update_curve();
while(offset < numsamples) {
@@ -778,32 +757,16 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
// send to output
outs[0][offset] = outL;
outs[1][offset] = outR;
// clip LED's
if(std::max(fabs(inL), fabs(inR)) > 1.f) {
clip_in = srate >> 3;
}
if(std::max(fabs(outL), fabs(outR)) > 1.f) {
clip_out = srate >> 3;
}
// rise up out meter
meter_in = std::max(fabs(inL), fabs(inR));;
meter_out = std::max(fabs(outL), fabs(outR));;
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
f1L.sanitize();
f1R.sanitize();
f2L.sanitize();
f2R.sanitize();
}
// draw meters
SET_IF_CONNECTED(clip_in)
SET_IF_CONNECTED(clip_out)
SET_IF_CONNECTED(meter_in)
SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_compression] != NULL) {
@@ -899,6 +862,11 @@ deesser_audio_module::deesser_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
f1_freq_old1 = 0.f;
f2_freq_old1 = 0.f;
f1_level_old1 = 0.f;
f2_level_old1 = 0.f;
f2_q_old1 = 0.f;
}
void deesser_audio_module::activate()
@@ -1129,6 +1097,7 @@ gate_audio_module::gate_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
meters.reset();
}
void gate_audio_module::activate()
@@ -1137,10 +1106,7 @@ void gate_audio_module::activate()
// set all filters and strips
gate.activate();
params_changed();
meter_in = 0.f;
meter_out = 0.f;
clip_in = 0.f;
clip_out = 0.f;
meters.reset();
}
void gate_audio_module::deactivate()
{
@@ -1161,6 +1127,8 @@ void gate_audio_module::set_sample_rate(uint32_t sr)
uint32_t gate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
bool bypass = *params[param_bypass] > 0.5f;
numsamples += offset;
if(bypass) {
@@ -1171,15 +1139,9 @@ uint32_t gate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.bypassed(params, orig_numsamples);
} else {
// process
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
gate.update_curve();
while(offset < numsamples) {
@@ -1204,26 +1166,11 @@ uint32_t gate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32
outs[0][offset] = outL;
outs[1][offset] = outR;
// clip LED's
if(std::max(fabs(inL), fabs(inR)) > 1.f) {
clip_in = srate >> 3;
}
if(std::max(fabs(outL), fabs(outR)) > 1.f) {
clip_out = srate >> 3;
}
// rise up out meter
meter_in = std::max(fabs(inL), fabs(inR));;
meter_out = std::max(fabs(outL), fabs(outR));;
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
}
// draw meters
SET_IF_CONNECTED(clip_in)
SET_IF_CONNECTED(clip_out)
SET_IF_CONNECTED(meter_in)
SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_gating] != NULL) {
@@ -1277,6 +1224,11 @@ sidechaingate_audio_module::sidechaingate_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
f1_freq_old = f2_freq_old = f1_level_old = f2_level_old = 0;
f1_freq_old1 = f2_freq_old1 = f1_level_old1 = f2_level_old1 = 0;
sc_mode_old = sc_mode_old1 = WIDEBAND; // doesn't matter as long as it's sane
meters.reset();
}
void sidechaingate_audio_module::activate()
@@ -1285,10 +1237,7 @@ void sidechaingate_audio_module::activate()
// set all filters and strips
gate.activate();
params_changed();
meter_in = 0.f;
meter_out = 0.f;
clip_in = 0.f;
clip_out = 0.f;
meters.reset();
}
void sidechaingate_audio_module::deactivate()
{
@@ -1445,6 +1394,8 @@ void sidechaingate_audio_module::set_sample_rate(uint32_t sr)
uint32_t sidechaingate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
bool bypass = *params[param_bypass] > 0.5f;
numsamples += offset;
if(bypass) {
@@ -1455,15 +1406,10 @@ uint32_t sidechaingate_audio_module::process(uint32_t offset, uint32_t numsample
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.bypassed(params, orig_offset);
} else {
// process
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
gate.update_curve();
while(offset < numsamples) {
@@ -1544,31 +1490,16 @@ uint32_t sidechaingate_audio_module::process(uint32_t offset, uint32_t numsample
outs[0][offset] = outL;
outs[1][offset] = outR;
// clip LED's
if(std::max(fabs(inL), fabs(inR)) > 1.f) {
clip_in = srate >> 3;
}
if(std::max(fabs(outL), fabs(outR)) > 1.f) {
clip_out = srate >> 3;
}
// rise up out meter
meter_in = std::max(fabs(inL), fabs(inR));;
meter_out = std::max(fabs(outL), fabs(outR));;
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
f1L.sanitize();
f1R.sanitize();
f2L.sanitize();
f2R.sanitize();
}
// draw meters
SET_IF_CONNECTED(clip_in)
SET_IF_CONNECTED(clip_out)
SET_IF_CONNECTED(meter_in)
SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_gating] != NULL) {
@@ -1663,6 +1594,13 @@ gain_reduction_audio_module::gain_reduction_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
old_threshold = 0.f;
old_ratio = 0.f;
old_knee = 0.f;
old_makeup = 0.f;
old_detection = 0.f;
old_bypass = 0.f;
old_mute = 0.f;
}
void gain_reduction_audio_module::activate()
@@ -1889,6 +1827,17 @@ expander_audio_module::expander_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
old_range = 0.f;
old_threshold = 0.f;
old_ratio = 0.f;
old_knee = 0.f;
old_makeup = 0.f;
old_detection = 0.f;
old_bypass = 0.f;
old_mute = 0.f;
old_trigger = 0.f;
old_stereo_link = 0.f;
}
void expander_audio_module::activate()

View File

@@ -38,10 +38,6 @@ saturator_audio_module::saturator_audio_module()
{
is_active = false;
srate = 0;
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
}
@@ -50,6 +46,8 @@ void saturator_audio_module::activate()
is_active = true;
// set all filters
params_changed();
meters.reset();
meter_drive = 0.f;
}
void saturator_audio_module::deactivate()
{
@@ -120,6 +118,8 @@ void saturator_audio_module::set_sample_rate(uint32_t sr)
uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
bool bypass = *params[param_bypass] > 0.5f;
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
numsamples += offset;
if(bypass) {
// everything bypassed
@@ -137,18 +137,8 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
}
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
meters.bypassed(params, orig_numsamples);
} else {
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
float in_avg[2] = {0.f, 0.f};
float out_avg[2] = {0.f, 0.f};
@@ -157,7 +147,6 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
while(offset < numsamples) {
// cycle through samples
float out[2], in[2] = {0.f, 0.f};
float maxIn, maxOut = 0.f;
int c = 0;
if(in_count > 1 && out_count > 1) {
@@ -178,6 +167,8 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
proc[0] = in[0] * *params[param_level_in];
proc[1] = in[1] * *params[param_level_in];
float onedivlevelin = 1.0 / *params[param_level_in];
for (int i = 0; i < c; ++i) {
// all pre filters in chain
proc[i] = lp[i][1].process(lp[i][0].process(proc[i]));
@@ -200,7 +191,7 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
proc[i] = hp[i][2].process(hp[i][3].process(proc[i]));
//subtract gain
proc[i] /= *params[param_level_in];
proc[i] *= onedivlevelin;
}
if(in_count > 1 && out_count > 1) {
@@ -209,42 +200,23 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
outs[0][offset] = out[0];
out[1] = ((proc[1] * *params[param_mix]) + in[1] * (1 - *params[param_mix])) * *params[param_level_out];
outs[1][offset] = out[1];
maxIn = std::max(fabs(in[0]), fabs(in[1]));
maxOut = std::max(fabs(out[0]), fabs(out[1]));
} else if(out_count > 1) {
// mono -> pseudo stereo
out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out];
outs[0][offset] = out[0];
out[1] = out[0];
outs[1][offset] = out[1];
maxOut = fabs(out[0]);
maxIn = fabs(in[0]);
} else {
// stereo -> mono
// or full mono
out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out];
outs[0][offset] = out[0];
maxIn = fabs(in[0]);
maxOut = fabs(out[0]);
}
if(maxIn > 1.f) {
clip_in = srate >> 3;
}
if(maxOut > 1.f) {
clip_out = srate >> 3;
}
// set up in / out meters
if(maxIn > meter_in) {
meter_in = maxIn;
}
if(maxOut > meter_out) {
meter_out = maxOut;
}
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
tube_avg = (sqrt(std::max(out_avg[0], out_avg[1])) / numsamples) - (sqrt(std::max(in_avg[0], in_avg[1])) / numsamples);
meter_drive = (5.0f * fabs(tube_avg) * (float(*params[param_blend]) + 30.0f));
@@ -270,19 +242,6 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u
p[1].sanitize();
}
// draw meters
if(params[param_clip_in] != NULL) {
*params[param_clip_in] = clip_in;
}
if(params[param_clip_out] != NULL) {
*params[param_clip_out] = clip_out;
}
if(params[param_meter_in] != NULL) {
*params[param_meter_in] = meter_in;
}
if(params[param_meter_out] != NULL) {
*params[param_meter_out] = meter_out;
}
if(params[param_meter_drive] != NULL) {
*params[param_meter_drive] = meter_drive;
}
@@ -300,10 +259,6 @@ exciter_audio_module::exciter_audio_module()
{
is_active = false;
srate = 0;
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
}
@@ -351,6 +306,8 @@ void exciter_audio_module::set_sample_rate(uint32_t sr)
uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
bool bypass = *params[param_bypass] > 0.5f;
numsamples += offset;
if(bypass) {
@@ -369,25 +326,18 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
}
++offset;
}
meters.bypassed(params, orig_numsamples);
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
} else {
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
// process
while(offset < numsamples) {
// cycle through samples
float out[2], in[2] = {0.f, 0.f};
float maxIn, maxOut, maxDrive = 0.f;
float maxDrive = 0.f;
int c = 0;
if(in_count > 1 && out_count > 1) {
@@ -434,8 +384,6 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
else
out[1] = (proc[1] * *params[param_amount] + in[1]) * *params[param_level_out];
outs[1][offset] = out[1];
maxIn = std::max(fabs(in[0]), fabs(in[1]));
maxOut = std::max(fabs(out[0]), fabs(out[1]));
maxDrive = std::max(dist[0].get_distortion_level() * *params[param_amount],
dist[1].get_distortion_level() * *params[param_amount]);
} else if(out_count > 1) {
@@ -447,8 +395,6 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
outs[0][offset] = out[0];
out[1] = out[0];
outs[1][offset] = out[1];
maxOut = fabs(out[0]);
maxIn = fabs(in[0]);
maxDrive = dist[0].get_distortion_level() * *params[param_amount];
} else {
// stereo -> mono
@@ -458,24 +404,10 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
else
out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out];
outs[0][offset] = out[0];
maxIn = fabs(in[0]);
maxOut = fabs(out[0]);
maxDrive = dist[0].get_distortion_level() * *params[param_amount];
}
if(maxIn > 1.f) {
clip_in = srate >> 3;
}
if(maxOut > 1.f) {
clip_out = srate >> 3;
}
// set up in / out meters
if(maxIn > meter_in) {
meter_in = maxIn;
}
if(maxOut > meter_out) {
meter_out = maxOut;
}
if(maxDrive > meter_drive) {
meter_drive = maxDrive;
}
@@ -483,6 +415,7 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
// clean up
hp[0][0].sanitize();
hp[1][0].sanitize();
@@ -494,19 +427,6 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
hp[1][3].sanitize();
}
// draw meters
if(params[param_clip_in] != NULL) {
*params[param_clip_in] = clip_in;
}
if(params[param_clip_out] != NULL) {
*params[param_clip_out] = clip_out;
}
if(params[param_meter_in] != NULL) {
*params[param_meter_in] = meter_in;
}
if(params[param_meter_out] != NULL) {
*params[param_meter_out] = meter_out;
}
if(params[param_meter_drive] != NULL) {
*params[param_meter_drive] = meter_drive;
}
@@ -524,16 +444,14 @@ bassenhancer_audio_module::bassenhancer_audio_module()
{
is_active = false;
srate = 0;
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.reset();
meter_drive = 0.f;
}
void bassenhancer_audio_module::activate()
{
is_active = true;
meters.reset();
// set all filters
params_changed();
}
@@ -575,6 +493,8 @@ void bassenhancer_audio_module::set_sample_rate(uint32_t sr)
uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
bool bypass = *params[param_bypass] > 0.5f;
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
numsamples += offset;
if(bypass) {
// everything bypassed
@@ -593,24 +513,16 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
++offset;
}
// displays, too
clip_in = 0.f;
clip_out = 0.f;
meter_in = 0.f;
meter_out = 0.f;
meters.bypassed(params, orig_numsamples);
meter_drive = 0.f;
} else {
clip_in -= std::min(clip_in, numsamples);
clip_out -= std::min(clip_out, numsamples);
meter_in = 0.f;
meter_out = 0.f;
meter_drive = 0.f;
// process
while(offset < numsamples) {
// cycle through samples
float out[2], in[2] = {0.f, 0.f};
float maxIn, maxOut, maxDrive = 0.f;
float maxDrive = 0.f;
int c = 0;
if(in_count > 1 && out_count > 1) {
@@ -657,8 +569,6 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
else
out[1] = (proc[1] * *params[param_amount] + in[1]) * *params[param_level_out];
outs[1][offset] = out[1];
maxIn = std::max(fabs(in[0]), fabs(in[1]));
maxOut = std::max(fabs(out[0]), fabs(out[1]));
maxDrive = std::max(dist[0].get_distortion_level() * *params[param_amount],
dist[1].get_distortion_level() * *params[param_amount]);
} else if(out_count > 1) {
@@ -670,8 +580,6 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
outs[0][offset] = out[0];
out[1] = out[0];
outs[1][offset] = out[1];
maxOut = fabs(out[0]);
maxIn = fabs(in[0]);
maxDrive = dist[0].get_distortion_level() * *params[param_amount];
} else {
// stereo -> mono
@@ -681,24 +589,10 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
else
out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out];
outs[0][offset] = out[0];
maxIn = fabs(in[0]);
maxOut = fabs(out[0]);
maxDrive = dist[0].get_distortion_level() * *params[param_amount];
}
if(maxIn > 1.f) {
clip_in = srate >> 3;
}
if(maxOut > 1.f) {
clip_out = srate >> 3;
}
// set up in / out meters
if(maxIn > meter_in) {
meter_in = maxIn;
}
if(maxOut > meter_out) {
meter_out = maxOut;
}
if(maxDrive > meter_drive) {
meter_drive = maxDrive;
}
@@ -706,6 +600,7 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
// clean up
lp[0][0].sanitize();
lp[1][0].sanitize();
@@ -717,19 +612,6 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples
lp[1][3].sanitize();
}
// draw meters
if(params[param_clip_in] != NULL) {
*params[param_clip_in] = clip_in;
}
if(params[param_clip_out] != NULL) {
*params[param_clip_out] = clip_out;
}
if(params[param_meter_in] != NULL) {
*params[param_meter_in] = meter_in;
}
if(params[param_meter_out] != NULL) {
*params[param_meter_out] = meter_out;
}
if(params[param_meter_drive] != NULL) {
*params[param_meter_drive] = meter_drive;
}