[SCM] calf/master: * experimental version of filter plugin refactored into three base classes
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:38:50 UTC 2013
The following commit has been merged in the master branch:
commit fc742721655b82d0e936451396f03d1cb4b850ae
Author: Hans Baier <jack at hansbaier.(none)>
Date: Sat Jan 17 15:19:41 2009 +0700
* experimental version of filter plugin refactored into three base classes
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index d0926a9..63b24db 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -92,6 +92,14 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
enum { step_size = 64 };
PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
};
+
+/*
+/// Filterclavier - metadata
+struct filterclavier_metadata: public plugin_metadata<filterclavier_metadata>
+{
+
+};
+*/
/// Thor's compressor - metadata
struct compressor_metadata: public plugin_metadata<compressor_metadata>
diff --git a/src/calf/modules.h b/src/calf/modules.h
index c47d04f..d60b40f 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -239,6 +239,7 @@ public:
void deactivate();
};
+#if !ENABLE_EXPERIMENTAL
class filter_audio_module: public audio_module<filter_metadata>, public line_graph_iface
{
public:
@@ -377,6 +378,7 @@ public:
float freq_gain(int subindex, float freq, float srate);
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
};
+#endif
class vintage_delay_audio_module: public audio_module<vintage_delay_metadata>
{
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index 8067bd3..eaecb70 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -21,10 +21,259 @@
#ifndef __CALF_MODULES_DEV_H
#define __CALF_MODULES_DEV_H
+#include <calf/inertia.h>
+#include <calf/biquad.h>
+#include <stdexcept>
+
namespace calf_plugins {
#if ENABLE_EXPERIMENTAL
+class filter_module_base
+{
+public:
+ virtual void calculate_filter(float freq, float q, int mode) = 0;
+ virtual void filter_activate() = 0;
+ virtual int process_channel(uint16_t channel_no, float *in, float *out, uint32_t numsamples, int inmask) = 0;
+ virtual float freq_gain(int subindex, float freq, float srate) = 0;
+};
+class biquad_filter_module: public filter_module_base
+{
+private:
+ dsp::biquad_d1<float> left[3], right[3];
+ int order;
+
+public:
+ uint32_t srate;
+
+public:
+ biquad_filter_module() : order(0) {}
+
+ void calculate_filter(float freq, float q, int mode)
+ {
+ if (mode < 3) {
+ order = mode + 1;
+ left[0].set_lp_rbj(freq, pow(q, 1.0 / order), srate);
+ } else {
+ order = mode - 2;
+ left[0].set_hp_rbj(freq, pow(q, 1.0 / order), srate);
+ }
+
+ right[0].copy_coeffs(left[0]);
+ for (int i = 1; i < order; i++) {
+ left[i].copy_coeffs(left[0]);
+ right[i].copy_coeffs(left[0]);
+ }
+ }
+
+ void filter_activate()
+ {
+ for (int i=0; i < order; i++) {
+ left[i].reset();
+ right[i].reset();
+ }
+ }
+
+ inline int process_channel(uint16_t channel_no, float *in, float *out, uint32_t numsamples, int inmask) {
+ dsp::biquad_d1<float> *filter;
+ switch (channel_no) {
+ case 0:
+ filter = left;
+ break;
+
+ case 1:
+ filter = right;
+ break;
+
+ default:
+ throw std::invalid_argument("channel_no");
+ break;
+ }
+
+ if (inmask) {
+ switch(order) {
+ case 1:
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[0].process(in[i]);
+ break;
+ case 2:
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[1].process(filter[0].process(in[i]));
+ break;
+ case 3:
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[2].process(filter[1].process(filter[0].process(in[i])));
+ break;
+ }
+ } else {
+ if (filter[order - 1].empty())
+ return 0;
+ switch(order) {
+ case 1:
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[0].process_zeroin();
+ break;
+ case 2:
+ if (filter[0].empty())
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[1].process_zeroin();
+ else
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[1].process(filter[0].process_zeroin());
+ break;
+ case 3:
+ if (filter[1].empty())
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[2].process_zeroin();
+ else
+ for (uint32_t i = 0; i < numsamples; i++)
+ out[i] = filter[2].process(filter[1].process(filter[0].process_zeroin()));
+ break;
+ }
+ }
+ for (int i = 0; i < order; i++)
+ filter[i].sanitize();
+ return filter[order - 1].empty() ? 0 : inmask;
+ }
+
+ float freq_gain(int subindex, float freq, float srate)
+ {
+ float level = 1.0;
+ for (int j = 0; j < order; j++)
+ level *= left[j].freq_gain(freq, srate);
+ return level;
+ }
+};
+
+template<typename FilterClass, typename Metadata>
+class filter_module_with_inertia: public FilterClass
+{
+public:
+ float *ins[Metadata::in_count];
+ float *outs[Metadata::out_count];
+ float *params[Metadata::param_count];
+
+ inertia<exponential_ramp> inertia_cutoff, inertia_resonance;
+ once_per_n timer;
+ bool is_active;
+
+ filter_module_with_inertia()
+ : inertia_cutoff(exponential_ramp(128), 20)
+ , inertia_resonance(exponential_ramp(128), 20)
+ , timer(128)
+ {
+ is_active = false;
+ }
+
+ void calculate_filter()
+ {
+ float freq = inertia_cutoff.get_last();
+ // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
+ // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
+ float q = inertia_resonance.get_last();
+ int mode = dsp::fastf2i_drm(*params[Metadata::par_mode]);
+ // printf("freq = %f q = %f mode = %d\n", freq, q, mode);
+
+ int inertia = dsp::fastf2i_drm(*params[Metadata::par_inertia]);
+ if (inertia != inertia_cutoff.ramp.length()) {
+ inertia_cutoff.ramp.set_length(inertia);
+ inertia_resonance.ramp.set_length(inertia);
+ }
+
+ FilterClass::calculate_filter(freq, q, mode);
+ }
+
+ void template_params_changed()
+ {
+ inertia_cutoff.set_inertia(*params[Metadata::par_cutoff]);
+ inertia_resonance.set_inertia(*params[Metadata::par_resonance]);
+ calculate_filter();
+ }
+
+ void on_timer()
+ {
+ inertia_cutoff.step();
+ inertia_resonance.step();
+ calculate_filter();
+ }
+
+ void template_activate()
+ {
+ template_params_changed();
+ FilterClass::filter_activate();
+ timer = once_per_n(FilterClass::srate / 1000);
+ timer.start();
+ is_active = true;
+ }
+
+ void template_set_sample_rate(uint32_t sr)
+ {
+ FilterClass::srate = sr;
+ }
+
+
+ void template_deactivate()
+ {
+ is_active = false;
+ }
+
+ uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
+// printf("sr=%d cutoff=%f res=%f mode=%f\n", FilterClass::srate, *params[Metadata::par_cutoff], *params[Metadata::par_resonance], *params[Metadata::par_mode]);
+ uint32_t ostate = 0;
+ numsamples += offset;
+ while(offset < numsamples) {
+ uint32_t numnow = numsamples - offset;
+ // if inertia's inactive, we can calculate the whole buffer at once
+ if (inertia_cutoff.active() || inertia_resonance.active())
+ numnow = timer.get(numnow);
+
+ if (outputs_mask & 1) {
+ ostate |= FilterClass::process_channel(0, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1);
+ }
+ if (outputs_mask & 2) {
+ ostate |= FilterClass::process_channel(1, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2);
+ }
+
+ if (timer.elapsed()) {
+ on_timer();
+ }
+ offset += numnow;
+ }
+ return ostate;
+ }
+};
+
+class filter_audio_module:
+ public audio_module<filter_metadata>,
+ public filter_module_with_inertia<biquad_filter_module, filter_metadata>,
+ public line_graph_iface
+{
+public:
+ void params_changed()
+ {
+ template_params_changed();
+ }
+
+ void activate()
+ {
+ template_activate();
+ }
+
+ void set_sample_rate(uint32_t sr)
+ {
+ template_set_sample_rate(sr);
+ }
+
+
+ void deactivate()
+ {
+ template_deactivate();
+ }
+
+
+ bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
+ bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
+};
#endif
};
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index cb134ed..3242bed 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -26,6 +26,7 @@
#endif
#include <calf/giface.h>
#include <calf/modules.h>
+#include <calf/modules_dev.h>
using namespace dsp;
using namespace calf_plugins;
@@ -191,7 +192,7 @@ void reverb_audio_module::set_sample_rate(uint32_t sr)
}
///////////////////////////////////////////////////////////////////////////////////////////////
-
+#if !ENABLE_EXPERIMENTAL
void filter_audio_module::activate()
{
params_changed();
@@ -239,7 +240,25 @@ bool filter_audio_module::get_gridline(int index, int subindex, float &pos, bool
return get_freq_gridline(subindex, pos, vertical, legend, context);
return false;
}
+#else
+bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+{
+ if (!is_active)
+ return false;
+ if (index == par_cutoff && !subindex) {
+ context->set_line_width(1.5);
+ return ::get_graph(*this, subindex, data, points);
+ }
+ return false;
+}
+bool filter_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+{
+ if (index == par_cutoff)
+ return get_freq_gridline(subindex, pos, vertical, legend, context);
+ return false;
+}
+#endif
///////////////////////////////////////////////////////////////////////////////////////////////
rotary_speaker_audio_module::rotary_speaker_audio_module()
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list