[SCM] calf/master: + Framework: separate metadata-related parts out of plugin classes and plugin control interface (work in progress, only JACK host and GUI-less LV2 work now)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:38:19 UTC 2013


The following commit has been merged in the master branch:
commit 897573ccc6350dafa7a32c6f9a8726efcea1a3b3
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Tue Nov 4 21:44:49 2008 +0000

    + Framework: separate metadata-related parts out of plugin classes and plugin control interface (work in progress, only JACK host and GUI-less LV2 work now)

diff --git a/src/calf/giface.h b/src/calf/giface.h
index c65130b..4892f94 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -109,8 +109,6 @@ enum parameter_flags
 /// Check for infinity (with appropriate-ish tolerance)
 #define IS_FAKE_INFINITY(value) (fabs(value-FAKE_INFINITY) < 1.0)
 
-class null_audio_module;
-
 /// Information record about plugin's menu command
 struct plugin_command_info
 {
@@ -177,8 +175,18 @@ struct send_configure_iface
 
 struct plugin_command_info;
 
+struct plugin_metadata_iface
+{
+    /// @return plugin long name
+    virtual const char *inst_get_name() = 0;
+    /// @return plugin LV2 label
+    virtual const char *inst_get_id() = 0;
+    /// @return plugin human-readable label
+    virtual const char *inst_get_label() = 0;
+};
+
 /// Interface for host-GUI-plugin interaction (should be really split in two, but ... meh)
-struct plugin_ctl_iface
+struct plugin_ctl_iface: public virtual plugin_metadata_iface
 {
     /// @return description structure for given parameter
     virtual parameter_properties *get_param_props(int param_no) = 0;
@@ -196,12 +204,6 @@ struct plugin_ctl_iface
     virtual int get_param_port_offset() = 0;
     /// Load preset with given number
     virtual bool activate_preset(int bank, int program) = 0;
-    /// @return plugin long name
-    virtual const char *get_name() = 0;
-    /// @return plugin LV2 label
-    virtual const char *get_id() = 0;
-    /// @return plugin human-readable label
-    virtual const char *get_label() = 0;
     /// @return number of audio inputs
     virtual int get_input_count()=0;
     /// @return number of audio outputs
@@ -286,7 +288,8 @@ std::string xml_escape(const std::string &src);
 
 /// Empty implementations for plugin functions. Note, that functions aren't virtual, because they're called via the particular
 /// subclass (flanger_audio_module etc) via template wrappers (ladspa_wrapper<> etc), not via base class pointer/reference
-class null_audio_module: public line_graph_iface
+template<class Metadata>
+class audio_module: public Metadata
 {
 public:
     /// Handle MIDI Note On
@@ -332,6 +335,29 @@ public:
     inline void params_reset() {}
 };
 
+template<class Metadata>
+class plugin_metadata: public virtual plugin_metadata_iface
+{    
+public:
+    static const char *port_names[];
+    static parameter_properties param_props[];
+    static synth::ladspa_plugin_info plugin_info;
+
+    const char *inst_get_name() { return Metadata::get_name(); } 
+    const char *inst_get_id() { return Metadata::get_id(); } 
+    const char *inst_get_label() { return Metadata::get_label(); } 
+    
+};
+
+#define CALF_PORT_NAMES(name) template<> const char *synth::plugin_metadata<name##_metadata>::port_names[]
+#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[]
+#define CALF_PLUGIN_INFO(name) template<> synth::ladspa_plugin_info plugin_metadata<name##_metadata>::plugin_info
+#define PLUGIN_NAME_ID_LABEL(name, id, label) \
+    static const char *get_name() { return name; } \
+    static const char *get_id() { return id; } \
+    static const char *get_label() { return label; } \
+    
+
 extern const char *calf_copyright_info;
 
 };
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index dca5837..f1e1eab 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -230,19 +230,22 @@ struct vumeter
 };
 
 template<class Module>
-class jack_host: public jack_host_base {
+class jack_host: public jack_host_base, public Module {
 public:
-    Module module;
-    port inputs[Module::in_count], outputs[Module::out_count];
-    vumeter input_vus[Module::in_count], output_vus[Module::out_count];
-    float params[Module::param_count];
+    using Module::in_count;
+    using Module::out_count;
+    using Module::param_count;
+
+    port inputs[in_count], outputs[out_count];
+    vumeter input_vus[in_count], output_vus[out_count];
+    float param_values[param_count];
     float midi_meter;
     
     jack_host()
     {
         for (int i = 0; i < Module::param_count; i++) {
-            module.params[i] = &params[i];
-            params[i] = Module::param_props[i].def_value;
+            param_values[i] = Module::param_props[i].def_value;
+            Module::params[i] = &param_values[i];
         }
         midi_meter = 0;
     }
@@ -254,9 +257,9 @@ public:
     }
     
     virtual void init_module() {
-        module.set_sample_rate(client->sample_rate);
-        module.activate();
-        module.params_changed();
+        Module::set_sample_rate(client->sample_rate);
+        Module::activate();
+        Module::params_changed();
     }
 
     virtual synth::parameter_properties* get_param_props(int param_no) { return Module::param_props + param_no; }
@@ -267,23 +270,23 @@ public:
         switch(buffer[0] >> 4)
         {
         case 8:
-            module.note_off(buffer[1], buffer[2]);
+            Module::note_off(buffer[1], buffer[2]);
             break;
         case 9:
             if (!buffer[2])
-                module.note_off(buffer[1], 0);
+                Module::note_off(buffer[1], 0);
             else
-                module.note_on(buffer[1], buffer[2]);
+                Module::note_on(buffer[1], buffer[2]);
             break;
         case 10:
-            module.program_change(buffer[1]);
+            Module::program_change(buffer[1]);
             break;
         case 11:
-            module.control_change(buffer[1], buffer[2]);
+            Module::control_change(buffer[1], buffer[2]);
             break;
         case 14:
             value = buffer[1] + 128 * buffer[2] - 8192;
-            module.pitch_bend(value);
+            Module::pitch_bend(value);
             break;
         }
     }
@@ -291,16 +294,16 @@ public:
     {
         if (!len)
             return;
-        for (int i = 0; i < Module::in_count; i++)
-            input_vus[i].update(module.ins[i] + time, len);
-        unsigned int mask = module.process(time, len, -1, -1);
-        for (int i = 0; i < Module::out_count; i++)
+        for (int i = 0; i < in_count; i++)
+            input_vus[i].update(Module::ins[i] + time, len);
+        unsigned int mask = Module::process(time, len, -1, -1);
+        for (int i = 0; i < out_count; i++)
         {
             if (!(mask & (1 << i))) {
-                dsp::zero(module.outs[i] + time, len);
+                dsp::zero(Module::outs[i] + time, len);
                 output_vus[i].update_zeros(len);
             } else
-                output_vus[i].update(module.outs[i] + time, len);
+                output_vus[i].update(Module::outs[i] + time, len);
         }
         // decay linearly for 0.1s
         float new_meter = midi_meter - len / (0.1 * client->sample_rate);
@@ -309,25 +312,25 @@ public:
         midi_meter = new_meter;
     }
     virtual float get_level(unsigned int port) { 
-        if (port < Module::in_count)
+        if (port < in_count)
             return input_vus[port].level;
-        port -= Module::in_count;
-        if (port < Module::out_count)
+        port -= in_count;
+        if (port < out_count)
             return output_vus[port].level;
-        port -= Module::out_count;
+        port -= out_count;
         if (port == 0 && Module::support_midi)
             return midi_meter;
         return 0.f;
     }
     int process(jack_nframes_t nframes)
     {
-        for (int i=0; i<Module::in_count; i++) {
-            module.ins[i] = inputs[i].data = (float *)jack_port_get_buffer(inputs[i].handle, nframes);
+        for (int i=0; i<in_count; i++) {
+            Module::ins[i] = inputs[i].data = (float *)jack_port_get_buffer(inputs[i].handle, nframes);
         }
         if (Module::support_midi)
             midi_port.data = (float *)jack_port_get_buffer(midi_port.handle, nframes);
         if (changed) {
-            module.params_changed();
+            Module::params_changed();
             changed = false;
         }
 
@@ -357,14 +360,14 @@ public:
             }
         }
         process_part(time, nframes - time);
-        module.params_reset();
+        Module::params_reset();
         return 0;
     }
     
     void cache_ports()
     {
-        for (int i=0; i<Module::out_count; i++) {
-            module.outs[i] = outputs[i].data = (float *)jack_port_get_buffer(outputs[i].handle, 0);
+        for (int i=0; i<out_count; i++) {
+            Module::outs[i] = outputs[i].data = (float *)jack_port_get_buffer(outputs[i].handle, 0);
         }
     }
     
@@ -375,7 +378,7 @@ public:
     
     virtual port *get_inputs() { return inputs; }
     virtual port *get_outputs() { return outputs; }
-    virtual float *get_params() { return params; }
+    virtual float *get_params() { return param_values; }
     virtual int get_input_count() { return Module::in_count; }
     virtual int get_output_count() { return Module::out_count; }
     virtual int get_param_count() { return Module::param_count; }
@@ -386,10 +389,10 @@ public:
         return Module::in_count + Module::out_count;
     }
     virtual float get_param_value(int param_no) {
-        return params[param_no];
+        return param_values[param_no];
     }
     virtual void set_param_value(int param_no, float value) {
-        params[param_no] = value;
+        param_values[param_no] = value;
         changed = true;
     }
     virtual const char *get_gui_xml() {
@@ -397,7 +400,7 @@ public:
     }
     virtual line_graph_iface *get_line_graph_iface()
     {
-        return &module;
+        return dynamic_cast<line_graph_iface *>(this);
     }
     virtual const char *get_name()
     {
@@ -415,17 +418,17 @@ public:
         return Module::get_commands();
     }
     virtual void execute(int cmd_no) {
-        module.execute(cmd_no);
+        Module::execute(cmd_no);
     }
     virtual char *configure(const char *key, const char *value) { 
-        return module.configure(key, value);
+        return Module::configure(key, value);
     }
     virtual void send_configures(send_configure_iface *sci) {
-        module.send_configures(sci);
+        Module::send_configures(sci);
     }
     virtual void clear_preset() {
         for (int i=0; i < Module::param_count; i++)
-            *module.params[i] = Module::param_props[i].def_value;
+            param_values[i] = Module::param_props[i].def_value;
         // This is never called in practice, at least for now
         const char **p = Module::get_default_configure_vars();
         if (p)
diff --git a/src/calf/ladspa_wrap.h b/src/calf/ladspa_wrap.h
index 53f5c04..6057b98 100644
--- a/src/calf/ladspa_wrap.h
+++ b/src/calf/ladspa_wrap.h
@@ -67,7 +67,7 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
     }
     virtual line_graph_iface *get_line_graph_iface()
     {
-        return this;
+        return dynamic_cast<line_graph_iface *>(this);
     }
     virtual bool activate_preset(int bank, int program) { 
         return false;
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index 02abb45..4a815b7 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -83,7 +83,7 @@ struct lv2_instance: public Module, public plugin_ctl_iface
     }
     virtual line_graph_iface *get_line_graph_iface()
     {
-        return this;
+        return dynamic_cast<line_graph_iface *>(this);
     }
     virtual bool activate_preset(int bank, int program) { 
         return false;
diff --git a/src/calf/modules.h b/src/calf/modules.h
index dbf4a5a..dbdac04 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -32,14 +32,9 @@ namespace synth {
 
 using namespace dsp;
 
-#define PLUGIN_NAME_ID_LABEL(name, id, label) \
-    static const char *get_name() { return name; } \
-    static const char *get_id() { return id; } \
-    static const char *get_label() { return label; } \
-    
-class null_audio_module;
 struct ladspa_plugin_info;
     
+#if 0
 class amp_audio_module: public null_audio_module
 {
 public:
@@ -48,7 +43,6 @@ public:
     float *outs[2];
     float *params[1];
     uint32_t srate;
-    static const char *port_names[in_count + out_count];
     static parameter_properties param_props[];
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
         if (!inputs_mask)
@@ -61,18 +55,20 @@ public:
         }
         return inputs_mask;
     }
-    static const char *get_name() { return "amp"; }
-    static const char *get_id() { return "amp"; }
-    static const char *get_label() { return "Amp"; }
 };
+#endif
 
-class flanger_audio_module: public null_audio_module
+struct flanger_metadata: public plugin_metadata<flanger_metadata>
 {
 public:
     enum { par_delay, par_depth, par_rate, par_fb, par_stereo, par_reset, par_amount, param_count };
     enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
-    static const char *port_names[in_count + out_count];
-    static synth::ladspa_plugin_info plugin_info;
+    PLUGIN_NAME_ID_LABEL("flanger", "flanger", "Flanger")
+};
+
+class flanger_audio_module: public audio_module<flanger_metadata>
+{
+public:
     dsp::simple_flanger<float, 2048> left, right;
     float *ins[in_count]; 
     float *outs[out_count];
@@ -80,7 +76,6 @@ public:
     uint32_t srate;
     bool clear_reset;
     float last_r_phase;
-    static parameter_properties param_props[];
     void set_sample_rate(uint32_t sr) {
         srate = sr;
         left.setup(sr);
@@ -134,16 +129,18 @@ public:
         right.process(outs[1] + offset, ins[1] + offset, nsamples);
         return outputs_mask; // XXXKF allow some delay after input going blank
     }
-    PLUGIN_NAME_ID_LABEL("flanger", "flanger", "Flanger")
 };
 
-class phaser_audio_module: public null_audio_module
+struct phaser_metadata: public plugin_metadata<phaser_metadata>
 {
-public:
     enum { par_freq, par_depth, par_rate, par_fb, par_stages, par_stereo, par_reset, par_amount, param_count };
     enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
-    static const char *port_names[in_count + out_count];
-    static synth::ladspa_plugin_info plugin_info;
+    PLUGIN_NAME_ID_LABEL("phaser", "phaser", "Phaser")
+};
+
+class phaser_audio_module: public audio_module<phaser_metadata>
+{
+public:
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
@@ -151,7 +148,6 @@ public:
     bool clear_reset;
     float last_r_phase;
     dsp::simple_phaser<12> left, right;
-    static parameter_properties param_props[];
     void set_sample_rate(uint32_t sr) {
         srate = sr;
         left.setup(sr);
@@ -207,23 +203,25 @@ public:
         right.process(outs[1] + offset, ins[1] + offset, nsamples);
         return outputs_mask; // XXXKF allow some delay after input going blank
     }
-    PLUGIN_NAME_ID_LABEL("phaser", "phaser", "Phaser")
 };
 
-class reverb_audio_module: public null_audio_module
+struct reverb_metadata: public plugin_metadata<reverb_metadata>
 {
-public:    
     enum { par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, param_count };
     enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
-    static const char *port_names[in_count + out_count];
-    static synth::ladspa_plugin_info plugin_info;
+    PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb")
+};
+
+
+class reverb_audio_module: public audio_module<reverb_metadata>
+{
+public:    
     dsp::reverb<float> reverb;
     uint32_t srate;
     gain_smoothing amount;
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
-    static parameter_properties param_props[];
     
     void params_changed() {
         //reverb.set_time(0.5*pow(8.0f, *params[par_decay]));
@@ -256,22 +254,23 @@ public:
         reverb.extra_sanitize();
         return outputs_mask;
     }
-    PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb")
 };
 
-class filter_audio_module: public null_audio_module
+struct filter_metadata: public plugin_metadata<filter_metadata>
 {
-public:    
     enum { par_cutoff, par_resonance, par_mode, par_inertia, param_count };
     enum { in_count = 2, out_count = 2, rt_capable = true, require_midi = false, support_midi = false };
+    PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter")
+};
+
+class filter_audio_module: public audio_module<filter_metadata>
+{
+public:    
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
-    static const char *port_names[];
     dsp::biquad_d1<float> left[3], right[3];
     uint32_t srate;
-    static parameter_properties param_props[];
-    static synth::ladspa_plugin_info plugin_info;
     int order;
     inertia<exponential_ramp> inertia_cutoff, inertia_resonance;
     once_per_n timer;
@@ -409,21 +408,23 @@ public:
         }
         return ostate;
     }
-    PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter")
 };
 
-class vintage_delay_audio_module: public null_audio_module
+struct vintage_delay_metadata: public plugin_metadata<vintage_delay_metadata>
+{
+    enum { par_bpm, par_divide, par_time_l, par_time_r, par_feedback, par_amount, par_mixmode, par_medium, param_count };
+    enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
+    PLUGIN_NAME_ID_LABEL("vintage_delay", "vintagedelay", "Vintage Delay")
+};
+
+class vintage_delay_audio_module: public audio_module<vintage_delay_metadata>
 {
 public:    
     // 1MB of delay memory per channel... uh, RAM is cheap
     enum { MAX_DELAY = 262144, ADDR_MASK = MAX_DELAY - 1 };
-    enum { par_bpm, par_divide, par_time_l, par_time_r, par_feedback, par_amount, par_mixmode, par_medium, param_count };
-    enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
-    static const char *port_names[in_count + out_count];
-    static synth::ladspa_plugin_info plugin_info;
     float buffers[2][MAX_DELAY];
     int bufptr, deltime_l, deltime_r, mixmode, medium, old_medium;
     gain_smoothing amt_left, amt_right, fb_left, fb_right;
@@ -431,7 +432,6 @@ public:
     dsp::biquad_d2<float> biquad_left[2], biquad_right[2];
     
     uint32_t srate;
-    static parameter_properties param_props[];
     
     vintage_delay_audio_module()
     {
@@ -521,15 +521,19 @@ public:
         }
         return ostate;
     }
-    PLUGIN_NAME_ID_LABEL("vintage_delay", "vintagedelay", "Vintage Delay")
 };
 
-class rotary_speaker_audio_module: public null_audio_module
+struct rotary_speaker_metadata: public plugin_metadata<rotary_speaker_metadata>
 {
 public:
     enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, param_count };
     enum { in_count = 2, out_count = 2, support_midi = true, require_midi = false, rt_capable = true };
-    static const char *port_names[];
+    PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker")
+};
+
+class rotary_speaker_audio_module: public audio_module<rotary_speaker_metadata>
+{
+public:
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
@@ -540,8 +544,6 @@ public:
     dsp::simple_delay<8, float> phaseshift;
     uint32_t srate;
     int vibrato_mode;
-    static parameter_properties param_props[];
-    static synth::ladspa_plugin_info plugin_info;
     /// Current CC1 (Modulation) value, normalized to [0, 1]
     float mwhl_value;
     /// Current CC64 (Hold) value, normalized to [0, 1]
@@ -719,25 +721,28 @@ public:
             return;
         }
     }
-    PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker")
 };
 
-// A multitap stereo chorus thing
-class multichorus_audio_module: public null_audio_module
+/// A multitap stereo chorus thing - metadata
+struct multichorus_metadata: public plugin_metadata<multichorus_metadata>
 {
 public:    
     enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_lfophase_l, par_lfophase_r, param_count };
     enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
+    PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
+};
+
+/// A multitap stereo chorus thing - processing
+class multichorus_audio_module: public audio_module<multichorus_metadata>
+{
+public:
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
-    static const char *port_names[];
     uint32_t srate;
     dsp::multichorus<float, sine_multi_lfo<float, 8>, 4096> left, right;
     float last_r_phase;
     
-    static parameter_properties param_props[];
-    static synth::ladspa_plugin_info plugin_info;
 public:    
     multichorus_audio_module()
     {
@@ -784,7 +789,6 @@ public:
             *params[par_lfophase_r] = (double)right.lfo.phase * 360.0 / 4096.0;
         return outputs_mask; // XXXKF allow some delay after input going blank
     }
-    PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
 };
 
 extern std::string get_builtin_modules_rdf();
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index a509398..a42d4f4 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -27,22 +27,24 @@ namespace synth {
 
 #if ENABLE_EXPERIMENTAL
 
-class compressor_audio_module: public null_audio_module {
+struct compressor_metadata: public plugin_metadata<compressor_metadata>
+{
+    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, param_count };
+    PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor")
+};
+
+class compressor_audio_module: public audio_module<compressor_metadata> {
 private:
     float linslope, clip, peak;
     bool aweighting;
     aweighter awL, awR;
 public:
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
-    enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, param_count };
 
-    static const char *port_names[in_count + out_count];
-    static synth::ladspa_plugin_info plugin_info;
     float *ins[in_count];
     float *outs[out_count];
     float *params[param_count];
     uint32_t srate;
-    static parameter_properties param_props[];
     void activate() {
         linslope = 0.f;
         peak = 0.f;
@@ -150,10 +152,6 @@ public:
         return inputs_mask;
     }
 
-    static const char *get_name() { return "compressor"; }
-    static const char *get_id() { return "compressor"; }
-    static const char *get_label() { return "Compressor"; }
-
     void set_sample_rate(uint32_t sr) {
             srate = sr;
             awL.set(sr);
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index db6cabf..aa9ae23 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -35,18 +35,21 @@ namespace synth {
 
 #define MONOSYNTH_WAVE_BITS 12
     
-/// Monosynth-in-making. Parameters may change at any point, so don't make songs with it!
-/// It lacks inertia for parameters, even for those that really need it.
-class monosynth_audio_module: public null_audio_module
+struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
 {
-public:
     enum { wave_saw, wave_sqr, wave_pulse, wave_sine, wave_triangle, wave_varistep, wave_skewsaw, wave_skewsqr, wave_test1, wave_test2, wave_test3, wave_test4, wave_test5, wave_test6, wave_test7, wave_test8, wave_count };
     enum { flt_lp12, flt_lp24, flt_2lp12, flt_hp12, flt_lpbr, flt_hpbr, flt_bp6, flt_2bp6 };
     enum { par_wave1, par_wave2, par_detune, par_osc2xpose, par_oscmode, par_oscmix, par_filtertype, par_cutoff, par_resonance, par_cutoffsep, par_envmod, par_envtores, par_envtoamp, par_attack, par_decay, par_sustain, par_release, par_keyfollow, par_legato, par_portamento, par_vel2filter, par_vel2amp, par_master, param_count };
     enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64 };
-    static const char *port_names[];
-    static synth::ladspa_plugin_info plugin_info;
+    PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
+};
+    
+/// Monosynth-in-making. Parameters may change at any point, so don't make songs with it!
+/// It lacks inertia for parameters, even for those that really need it.
+class monosynth_audio_module: public audio_module<monosynth_metadata>
+{
+public:
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
@@ -71,7 +74,6 @@ public:
     synth::keystack stack;
     dsp::gain_smoothing master;
     
-    static parameter_properties param_props[];
     static const char *get_gui_xml();
     static void generate_waves();
     void set_sample_rate(uint32_t sr);
@@ -200,16 +202,20 @@ public:
     static const char *get_label() { return "Monosynth"; }
 };
 
-using namespace dsp;
+struct organ_metadata: public plugin_metadata<organ_metadata>
+{
+    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
+    enum { param_count = drawbar_organ::param_count };
+    PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ")
+};
 
-struct organ_audio_module: public null_audio_module, public drawbar_organ
+struct organ_audio_module: public audio_module<organ_metadata>, public drawbar_organ
 {
 public:
     using drawbar_organ::note_on;
     using drawbar_organ::note_off;
     using drawbar_organ::control_change;
-    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
-    static const char *port_names[];
+    enum { param_count = drawbar_organ::param_count};
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
@@ -223,8 +229,6 @@ public:
     : drawbar_organ(&par_values)
     {
     }
-    static parameter_properties param_props[];
-    static synth::ladspa_plugin_info plugin_info;
     static const char *get_gui_xml();
 
     void set_sample_rate(uint32_t sr) {
diff --git a/src/calf/osc.h b/src/calf/osc.h
index 942fccb..467ae7a 100644
--- a/src/calf/osc.h
+++ b/src/calf/osc.h
@@ -219,7 +219,7 @@ struct waveform_oscillator: public simple_oscillator
     inline float get()
     {
         uint32_t wpos = phase >> (32 - SIZE_BITS);
-        float value = lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SIZE - 1)) * (1.0f / SIZE));
+        float value = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SIZE - 1)) * (1.0f / SIZE));
         phase += phasedelta;
         return value;
     }
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index a45b34b..e2b57a2 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -137,15 +137,15 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
     virtual bool get_graph(int index, int subindex, float *data, int points, cairo_t *context) {
         return Module::get_static_graph(index, subindex, params[index], data, points, context);
     }
-    virtual const char *get_name()
+    virtual const char *inst_get_name()
     {
         return Module::get_name();
     }
-    virtual const char *get_id()
+    virtual const char *inst_get_id()
     {
         return Module::get_id();
     }
-    virtual const char *get_label()
+    virtual const char *inst_get_label()
     {
         return Module::get_label();
     }
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index 8b83c20..f1d4ecd 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -244,7 +244,7 @@ void host_session::remove_plugin(plugin_ctl_iface *plugin)
 
 bool host_session::activate_preset(int plugin_no, const std::string &preset, bool builtin)
 {
-    string cur_plugin = plugins[plugin_no]->get_id();
+    string cur_plugin = dynamic_cast<plugin_metadata_iface *>(plugins[plugin_no])->inst_get_id();
     preset_vector &pvec = (builtin ? get_builtin_presets() : get_user_presets()).presets;
     for (unsigned int i = 0; i < pvec.size(); i++) {
         if (pvec[i].name == preset && pvec[i].plugin == cur_plugin)
@@ -369,7 +369,7 @@ void host_session::update_lash()
                     jack_host_base *p = plugins[i];
                     char ss[32];
                     plugin_preset preset;
-                    preset.plugin = p->get_id();
+                    preset.plugin = dynamic_cast<plugin_metadata_iface *>(p)->inst_get_id();
                     preset.get_from(p);
                     sprintf(ss, "Plugin%d", i);
                     pstr = preset.to_xml();
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index 11c532e..62e822b 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -111,15 +111,15 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
     {
         return Module::get_static_graph(index, subindex, params[index], data, points, context);
     }
-    virtual const char *get_name()
+    virtual const char *inst_get_name()
     {
         return Module::get_name();
     }
-    virtual const char *get_id()
+    virtual const char *inst_get_id()
     {
         return Module::get_id();
     }
-    virtual const char *get_label()
+    virtual const char *inst_get_label()
     {
         return Module::get_label();
     }
diff --git a/src/main_win.cpp b/src/main_win.cpp
index 3e3c70b..5c88c34 100644
--- a/src/main_win.cpp
+++ b/src/main_win.cpp
@@ -191,7 +191,9 @@ main_window::plugin_strip *main_window::create_strip(plugin_ctl_iface *plugin)
     gtk_widget_show(sep);
     row++;
     
-    GtkWidget *label = gtk_toggle_button_new_with_label(plugin->get_label());
+    plugin_metadata_iface *pmi = dynamic_cast<plugin_metadata_iface *>(plugin);
+    assert(pmi);
+    GtkWidget *label = gtk_toggle_button_new_with_label(pmi->inst_get_label());
     gtk_table_attach(GTK_TABLE(strips_table), label, 0, 1, row, row + 2, ao, GTK_SHRINK, 0, 0);
     strip->name = label;
     gtk_signal_connect(GTK_OBJECT(label), "toggled", G_CALLBACK(gui_button_pressed), 
@@ -250,7 +252,9 @@ void main_window::update_strip(plugin_ctl_iface *plugin)
 void main_window::open_gui(plugin_ctl_iface *plugin)
 {
     plugin_gui_window *gui_win = new plugin_gui_window(this);
-    gui_win->create(plugin, (prefix + plugin->get_name()).c_str(), plugin->get_id());
+    plugin_metadata_iface *pmi = dynamic_cast<plugin_metadata_iface *>(plugin);
+    assert(pmi);
+    gui_win->create(plugin, (prefix + pmi->inst_get_name()).c_str(), pmi->inst_get_id());
     gtk_widget_show_all(GTK_WIDGET(gui_win->toplevel));
     plugins[plugin]->gui_win = gui_win; 
 }
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index a0a9466..d9ecb43 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -132,7 +132,7 @@ void make_rdf()
     #define RDF_EXPR(Module) \
         generate_ladspa_rdf(Module::plugin_info, Module::param_props, Module::port_names, Module::param_count, Module::in_count + Module::out_count);
     
-    #define PER_MODULE_ITEM(name, isSynth, jackname) if (!isSynth) rdf += RDF_EXPR(name##_audio_module)
+    #define PER_MODULE_ITEM(name, isSynth, jackname) if (!isSynth) rdf += RDF_EXPR(name##_metadata)
     #define PER_SMALL_MODULE_ITEM(...)
     #include <calf/modulelist.h>
     
diff --git a/src/modules.cpp b/src/modules.cpp
index b68cdd2..178db81 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -39,9 +39,9 @@ const char *synth::calf_copyright_info = "(C) 2001-2008 Krzysztof Foltman, licen
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *flanger_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"};
 
-parameter_properties flanger_audio_module::param_props[] = {
+CALF_PORT_PROPS(flanger) = {
     { 0.1,      0.1, 10,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "min_delay", "Minimum delay" },
     { 0.5,      0.1, 10,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Modulation depth" },
     { 0.25,    0.01, 20,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" },
@@ -51,13 +51,13 @@ parameter_properties flanger_audio_module::param_props[] = {
     { 1,          0, 2,     0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
 };
 
-synth::ladspa_plugin_info flanger_audio_module::plugin_info = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", synth::calf_copyright_info, "FlangerPlugin" };
+CALF_PLUGIN_INFO(flanger) = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", synth::calf_copyright_info, "FlangerPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *phaser_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(phaser) = {"In L", "In R", "Out L", "Out R"};
 
-parameter_properties phaser_audio_module::param_props[] = {
+CALF_PORT_PROPS(phaser) = {
     { 1000,      20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "base_freq", "Center Freq" },
     { 4000,       0, 10800,  0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Modulation depth" },
     { 0.25,    0.01, 20,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" },
@@ -68,15 +68,15 @@ parameter_properties phaser_audio_module::param_props[] = {
     { 1,          0, 2,     0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
 };
 
-synth::ladspa_plugin_info phaser_audio_module::plugin_info = { 0x8484, "Phaser", "Calf Phaser", "Krzysztof Foltman", synth::calf_copyright_info, "PhaserPlugin" };
+CALF_PLUGIN_INFO(phaser) = { 0x8484, "Phaser", "Calf Phaser", "Krzysztof Foltman", synth::calf_copyright_info, "PhaserPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *reverb_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(reverb) = {"In L", "In R", "Out L", "Out R"};
 
 const char *reverb_room_sizes[] = { "Small", "Medium", "Large", "Tunnel-like" };
 
-parameter_properties reverb_audio_module::param_props[] = {
+CALF_PORT_PROPS(reverb) = {
     { 1.5,      0.5, 15.0,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "decay_time", "Decay time" },
     { 5000,    2000,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hf_damp", "High Frq Damp" },
     { 2,          0,    3,    0, PF_ENUM | PF_CTL_COMBO , reverb_room_sizes, "room_size", "Room size", },
@@ -84,11 +84,11 @@ parameter_properties reverb_audio_module::param_props[] = {
     { 0.25,       0,    2,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
 };
 
-synth::ladspa_plugin_info reverb_audio_module::plugin_info = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", synth::calf_copyright_info, "ReverbPlugin" };
+CALF_PLUGIN_INFO(reverb) = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", synth::calf_copyright_info, "ReverbPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *filter_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(filter) = {"In L", "In R", "Out L", "Out R"};
 
 const char *filter_choices[] = {
     "12dB/oct Lowpass",
@@ -99,18 +99,18 @@ const char *filter_choices[] = {
     "36dB/oct Highpass",
 };
 
-parameter_properties filter_audio_module::param_props[] = {
+CALF_PORT_PROPS(filter) = {
     { 2000,      10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Frequency" },
     { 0.707,  0.707,   20,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "res", "Resonance" },
     { 0,          0,    5,    1, PF_ENUM | PF_CTL_COMBO, filter_choices, "mode", "Mode" },
     { 20,         5,  100,    20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Inertia"},
 };
 
-synth::ladspa_plugin_info filter_audio_module::plugin_info = { 0x847f, "Filter", "Calf Filter", "Krzysztof Foltman", synth::calf_copyright_info, "FilterPlugin" };
+CALF_PLUGIN_INFO(filter) = { 0x847f, "Filter", "Calf Filter", "Krzysztof Foltman", synth::calf_copyright_info, "FilterPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *vintage_delay_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(vintage_delay) = {"In L", "In R", "Out L", "Out R"};
 
 const char *vintage_delay_mixmodes[] = {
     "Stereo",
@@ -123,7 +123,7 @@ const char *vintage_delay_fbmodes[] = {
     "Old Tape",
 };
 
-parameter_properties vintage_delay_audio_module::param_props[] = {
+CALF_PORT_PROPS(vintage_delay) = {
     { 120,      30,    300,2701, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" },
     {  4,        1,    16,    1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "subdiv", "Subdivide"},
     {  3,        1,    16,    1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_l", "Time L"},
@@ -134,15 +134,15 @@ parameter_properties vintage_delay_audio_module::param_props[] = {
     { 1,         0,    2,     0, PF_ENUM | PF_CTL_COMBO, vintage_delay_fbmodes, "medium", "Medium" },
 };
 
-synth::ladspa_plugin_info vintage_delay_audio_module::plugin_info = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", synth::calf_copyright_info, "DelayPlugin" };
+CALF_PLUGIN_INFO(vintage_delay) = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", synth::calf_copyright_info, "DelayPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *rotary_speaker_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(rotary_speaker) = {"In L", "In R", "Out L", "Out R"};
 
 const char *rotary_speaker_speed_names[] = { "Off", "Chorale", "Tremolo", "HoldPedal", "ModWheel", "Manual" };
 
-parameter_properties rotary_speaker_audio_module::param_props[] = {
+CALF_PORT_PROPS(rotary_speaker) = {
     { 2,         0,  5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" },
     { 0.5,        0,    1,    0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "spacing", "Tap Spacing" },
     { 0.5,        0,    1,    0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "shift", "Tap Offset" },
@@ -153,13 +153,13 @@ parameter_properties rotary_speaker_audio_module::param_props[] = {
     { 0.3,        0,    1,  101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" },
 };
 
-synth::ladspa_plugin_info rotary_speaker_audio_module::plugin_info = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", synth::calf_copyright_info, "SimulationPlugin" };
+CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", synth::calf_copyright_info, "SimulationPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
-const char *multichorus_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PORT_NAMES(multichorus) = {"In L", "In R", "Out L", "Out R"};
 
-parameter_properties multichorus_audio_module::param_props[] = {
+CALF_PORT_PROPS(multichorus) = {
     { 5,        0.1,  10,   0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "min_delay", "Minimum delay" },
     { 6,        0.1,  10,   0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Modulation depth" },
     { 0.5,     0.01,  20,   0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" },
@@ -171,14 +171,18 @@ parameter_properties multichorus_audio_module::param_props[] = {
     { 180,        0, 360,  91, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "lfo_phase_r", "Right LFO phase" },
 };
 
-synth::ladspa_plugin_info multichorus_audio_module::plugin_info = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", synth::calf_copyright_info, "ChorusPlugin" };
+CALF_PLUGIN_INFO(multichorus) = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", synth::calf_copyright_info, "ChorusPlugin" };
+
+////////////////////////////////////////////////////////////////////////////
 
 #if ENABLE_EXPERIMENTAL
 
+CALF_PORT_NAMES(compressor) = {"In L", "In R", "Out L", "Out R"};
+
 const char *compressor_detection_names[] = { "RMS", "Peak" };
 const char *compressor_stereo_link_names[] = { "Average", "Maximum" };
 
-parameter_properties compressor_audio_module::param_props[] = {
+CALF_PORT_PROPS(compressor) = {
     { 0.0625,      0, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" },
     { 5,      1, 100,  101, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" },
     { 15,     0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" },
@@ -194,9 +198,7 @@ parameter_properties compressor_audio_module::param_props[] = {
     { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
 };
 
-synth::ladspa_plugin_info compressor_audio_module::plugin_info = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", synth::calf_copyright_info, "CompressorPlugin" };
-
-const char *compressor_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", synth::calf_copyright_info, "CompressorPlugin" };
 
 #endif
 
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 145da17..7c179df 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -31,7 +31,7 @@
 using namespace synth;
 using namespace std;
 
-const char *monosynth_audio_module::port_names[] = {
+CALF_PORT_NAMES(monosynth) = {
     "Out L", "Out R", 
 };
 
@@ -51,7 +51,7 @@ const char *monosynth_filter_choices[] = {
     "2x6dB/oct Bandpass",
 };
 
-synth::ladspa_plugin_info monosynth_audio_module::plugin_info = { 0x8480, "Monosynth", "Calf Monosynth", "Krzysztof Foltman", synth::calf_copyright_info, "SynthesizerPlugin" };
+CALF_PLUGIN_INFO(monosynth) = { 0x8480, "Monosynth", "Calf Monosynth", "Krzysztof Foltman", synth::calf_copyright_info, "SynthesizerPlugin" };
 
 static const char *monosynth_gui_xml =
     "<vbox border=\"10\">"
@@ -192,9 +192,9 @@ static const char *monosynth_gui_xml =
         "</hbox>"
     "</vbox>";
 
-parameter_properties monosynth_audio_module::param_props[] = {
-    { wave_saw,         0, wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO, monosynth_waveform_names, "o1_wave", "Osc1 Wave" },
-    { wave_sqr,         0, wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO, monosynth_waveform_names, "o2_wave", "Osc2 Wave" },
+CALF_PORT_PROPS(monosynth) = {
+    { monosynth_metadata::wave_saw,         0, monosynth_metadata::wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO, monosynth_waveform_names, "o1_wave", "Osc1 Wave" },
+    { monosynth_metadata::wave_sqr,         0, monosynth_metadata::wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO, monosynth_waveform_names, "o2_wave", "Osc2 Wave" },
     { 10,         0,  100,    0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "o12_detune", "O1<>2 Detune" },
     { 12,       -24,   24,    0, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "o2_xpose", "Osc 2 transpose" },
     { 0,          0,    5,    0, PF_ENUM | PF_CTL_COMBO, monosynth_mode_names, "phase_mode", "Phase mode" },
@@ -388,7 +388,7 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int
             double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
             cfloat z = 1.0 / exp(cfloat(0.0, freq));
             
-            biquad_d1<float> &f = subindex ? filter2 : filter;
+            dsp::biquad_d1<float> &f = subindex ? filter2 : filter;
             float level = f.freq_gain(freq, srate);
             if (!is_stereo_filter())
                 level *= filter2.freq_gain(freq, srate);
diff --git a/src/organ.cpp b/src/organ.cpp
index 856eb6c..80a6f96 100644
--- a/src/organ.cpp
+++ b/src/organ.cpp
@@ -32,8 +32,9 @@
 
 using namespace synth;
 using namespace std;
+using namespace dsp;
 
-synth::ladspa_plugin_info organ_audio_module::plugin_info = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", synth::calf_copyright_info, "SynthesizerPlugin" };
+CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", synth::calf_copyright_info, "SynthesizerPlugin" };
 
 #define DRAWBAR_UI(no) \
             "<label  attach-x=\"" no "\" attach-y=\"0\" param=\"l" no "\"/>" \
@@ -420,7 +421,7 @@ bool organ_audio_module::get_graph(int index, int subindex, float *data, int poi
     return false;
 }
 
-const char *organ_audio_module::port_names[] = {"Out L", "Out R"};
+CALF_PORT_NAMES(organ) = {"Out L", "Out R"};
 
 const char *organ_percussion_trigger_names[] = { "First note", "Each note", "Each, no retrig", "Polyphonic" };
 
@@ -442,7 +443,7 @@ const char *organ_ampctl_names[] = { "None", "Direct", "Flt 1", "Flt 2", "All"
 
 const char *organ_vibrato_mode_names[] = { "None", "Direct", "Flt 1", "Flt 2", "Voice", "Global"  };
 
-parameter_properties organ_audio_module::param_props[] = {
+CALF_PORT_PROPS(organ) = {
     { 8,       0,  8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l1", "16'" },
     { 8,       0,  8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l2", "5 1/3'" },
     { 8,       0,  8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l3", "8'" },

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list