[SCM] calf/master: Refactor metering code out of distortion plugins.
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:20 UTC 2013
The following commit has been merged in the master branch:
commit 84d873861da7b4ad205061b00fcc9f73c47140b6
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Sun Aug 29 23:31:22 2010 +0100
Refactor metering code out of distortion plugins.
diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index bfc4a58..5430340 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -8,5 +8,5 @@ noinst_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h custom_ctl.h \
main_win.h metadata.h modmatrix.h \
modules.h modules_comp.h modules_dev.h modules_dist.h modules_eq.h modules_mod.h modules_synths.h \
modulelist.h \
- multichorus.h onepole.h organ.h osc.h osctl.h osctlnet.h osctl_glib.h preset.h \
+ multichorus.h onepole.h organ.h osc.h osctl.h osctlnet.h osctl_glib.h plugin_tools.h preset.h \
preset_gui.h primitives.h session_mgr.h synth.h utils.h vumeter.h wave.h waveshaping.h
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index a0dd201..5057fee 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -66,7 +66,7 @@ public:
jack_port_t *handle;
float *data;
std::string name;
- vumeter meter;
+ dsp::vumeter meter;
port() : handle(NULL), data(NULL) {}
~port() { }
};
diff --git a/src/calf/modules.h b/src/calf/modules.h
index d204218..b9395c6 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -29,7 +29,6 @@
#include "giface.h"
#include "metadata.h"
#include "loudness.h"
-#include "primitives.h"
namespace calf_plugins {
diff --git a/src/calf/modules_dist.h b/src/calf/modules_dist.h
index 6c49c37..d7be7dd 100644
--- a/src/calf/modules_dist.h
+++ b/src/calf/modules_dist.h
@@ -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:
diff --git a/src/calf/plugin_tools.h b/src/calf/plugin_tools.h
new file mode 100644
index 0000000..aad5cdf
--- /dev/null
+++ b/src/calf/plugin_tools.h
@@ -0,0 +1,80 @@
+/* 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;
+ }
+ }
+};
+
+};
+
+#endif
+
diff --git a/src/calf/vumeter.h b/src/calf/vumeter.h
index de174c1..6ef1e76 100644
--- a/src/calf/vumeter.h
+++ b/src/calf/vumeter.h
@@ -21,6 +21,8 @@
#ifndef __CALF_VUMETER_H
#define __CALF_VUMETER_H
+namespace dsp {
+
/// Peak meter class
struct vumeter
{
@@ -36,30 +38,47 @@ struct vumeter
vumeter()
{
falloff = 0.999f;
- level = 0;
clip_falloff = 0.999f;
+ reset();
+ }
+
+ void reset()
+ {
+ level = 0;
clip = 0;
}
/// Update peak meter based on input signal
- inline void update(float *src, unsigned int len)
+ 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
- float tmp = level * pow(falloff, len);
+ level *= pow(falloff, len);
// Same for clip level (using different fade constant)
- double tmp_clip = clip * pow(clip_falloff, len);
+ 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)
- tmp_clip = 1.f;
+ clip = 1.f;
}
level = tmp;
- clip = tmp_clip;
- dsp::sanitize(level);
- dsp::sanitize(clip);
}
/// Update clip meter as if update was called with all-zero input signal
inline void update_zeros(unsigned int len)
@@ -71,4 +90,6 @@ struct vumeter
}
};
+};
+
#endif
diff --git a/src/modules_dist.cpp b/src/modules_dist.cpp
index aba40fc..1592e32 100644
--- a/src/modules_dist.cpp
+++ b/src/modules_dist.cpp
@@ -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,9 @@ 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.reset();
+ meters.process(params, NULL, NULL, 0, 0);
} 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 +148,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 +168,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 +192,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 +201,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 +243,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 +260,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 +307,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 +327,19 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin
}
++offset;
}
+ meters.reset();
+ meters.process(params, NULL, NULL, 0, 0);
// 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 +386,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 +397,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 +406,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 +417,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 +429,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 +446,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 +495,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 +515,17 @@ 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.reset();
+ meters.process(params, NULL, NULL, 0, 0);
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 +572,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 +583,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 +592,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 +603,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 +615,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;
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list