[SCM] calf/master: General refactoring. Start implementing external GUI.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:39:57 UTC 2013


The following commit has been merged in the master branch:
commit ae7f7293961a3ea3b194b73ab35886f94e562cd7
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Fri Apr 2 22:53:54 2010 +0100

    General refactoring. Start implementing external GUI.
    
    Constify metadata functions. Constify other functions that really needed
    it. Make variables keeping old state mutable for now. Move filter composition
    operations into biquad.h. Replace global function get_all_plugins with
    a singleton class that returns the same list (as const) or a single plugin
    by URI. Add a skeleton implementation of functions in lv2_external_ui
    and skeleton UI related functions for external UI.

diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index 56d08f6..bf61f94 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -53,21 +53,21 @@ protected:
     gain_smoothing gs_wet, gs_dry;
 public:
     fixed_point<unsigned int, 20> phase, dphase;
-    float get_rate() {
+    float get_rate() const {
         return rate;
     }
     void set_rate(float rate) {
         this->rate = rate;
         dphase = rate/sample_rate*4096;        
     }
-    float get_wet() {
+    float get_wet() const {
         return wet;
     }
     void set_wet(float wet) {
         this->wet = wet;
         gs_wet.set_inertia(wet);
     }
-    float get_dry() {
+    float get_dry() const {
         return dry;
     }
     void set_dry(float dry) {
@@ -115,13 +115,13 @@ public:
         stages = 0;
         set_stages(6);
     }
-    float get_base_frq() {
+    float get_base_frq() const {
         return base_frq;
     }
     void set_base_frq(float _base_frq) {
         base_frq = _base_frq;
     }
-    int get_stages() {
+    int get_stages() const {
         return stages;
     }
     void set_stages(int _stages) {
@@ -135,13 +135,13 @@ public:
         }
         stages = _stages;
     }
-    float get_mod_depth() {
+    float get_mod_depth() const {
         return mod_depth;
     }
     void set_mod_depth(float _mod_depth) {
         mod_depth = _mod_depth;
     }
-    float get_fb() {
+    float get_fb() const {
         return fb;
     }
     void set_fb(float fb) {
@@ -196,7 +196,7 @@ public:
             *buf_out++ = sdry + swet;
         }
     }
-    float freq_gain(float freq, float sr)
+    float freq_gain(float freq, float sr) const
     {
         typedef std::complex<double> cfloat;
         freq *= 2.0 * M_PI / sr;
@@ -225,14 +225,14 @@ protected:
     float min_delay, mod_depth;
     sine_table<int, 4096, 65536> sine;
 public:
-    float get_min_delay() {
+    float get_min_delay() const {
         return min_delay;
     }
     void set_min_delay(float min_delay) {
         this->min_delay = min_delay;
         this->min_delay_samples = (int)(min_delay * 65536.0 * sample_rate);
     }
-    float get_mod_depth() {
+    float get_mod_depth() const {
         return mod_depth;
     }
     void set_mod_depth(float mod_depth) {
@@ -319,7 +319,7 @@ public:
         set_rate(get_rate());
         set_min_delay(get_min_delay());
     }
-    float get_fb() {
+    float get_fb() const {
         return fb;
     }
     void set_fb(float fb) {
@@ -386,7 +386,7 @@ public:
         }
         last_delay_pos = delay_pos;
     }
-    float freq_gain(float freq, float sr)
+    float freq_gain(float freq, float sr) const
     {
         typedef std::complex<double> cfloat;
         freq *= 2.0 * M_PI / sr;
@@ -504,7 +504,7 @@ public:
             rdec[i]=exp(-float(tr[i] >> 16) / fDec);
         }
     }
-    float get_time() {
+    float get_time() const {
         return time;
     }
     void set_time(float time) {
@@ -512,14 +512,14 @@ public:
         // fb = pow(1.0f/4096.0f, (float)(1700/(time*sr)));
         fb = 1.0 - 0.3 / (time * sr / 44100.0);
     }
-    float get_type() {
+    float get_type() const {
         return type;
     }
     void set_type(int type) {
         this->type = type;
         update_times();
     }
-    float get_diffusion() {
+    float get_diffusion() const {
         return diffusion;
     }
     void set_diffusion(float diffusion) {
@@ -531,7 +531,7 @@ public:
         this->diffusion = diffusion;
         update_times();
     }
-    float get_fb()
+    float get_fb() const
     {
         return this->fb;
     }
@@ -539,7 +539,7 @@ public:
     {
         this->fb = fb;
     }
-    float get_cutoff() {
+    float get_cutoff() const {
         return cutoff;
     }
     void set_cutoff(float cutoff) {
@@ -604,7 +604,7 @@ public:
     virtual void  filter_activate() = 0;
     virtual void  sanitize() = 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;
+    virtual float freq_gain(int subindex, float freq, float srate) const = 0;
 
     virtual ~filter_module_iface() {}
 };
@@ -730,7 +730,7 @@ public:
         return filter[order - 1].empty() ? 0 : inmask;
     }
     
-    float freq_gain(int subindex, float freq, float srate)
+    float freq_gain(int subindex, float freq, float srate) const
     {
         float level = 1.0;
         for (int j = 0; j < order; j++)
diff --git a/src/calf/biquad.h b/src/calf/biquad.h
index e1f4195..99cf2a4 100644
--- a/src/calf/biquad.h
+++ b/src/calf/biquad.h
@@ -305,7 +305,7 @@ public:
     /// Return the filter's gain at frequency freq
     /// @param freq   Frequency to look up
     /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
-    float freq_gain(float freq, float sr)
+    float freq_gain(float freq, float sr) const
     {
         typedef std::complex<double> cfloat;
         freq *= 2.0 * M_PI / sr;
@@ -316,7 +316,7 @@ public:
     
     /// Return H(z) the filter's gain at frequency freq
     /// @param z   Z variable (e^jw)
-    cfloat h_z(const cfloat &z)
+    cfloat h_z(const cfloat &z) const
     {
         
         return (cfloat(a0) + double(a1) * z + double(a2) * z*z) / (cfloat(1.0) + double(b1) * z + double(b2) * z*z);
@@ -396,7 +396,7 @@ struct biquad_d1: public biquad_coeffs<Coeff>
         dsp::zero(x2);
         dsp::zero(y2);
     }
-    inline bool empty() {
+    inline bool empty() const {
         return (y1 == 0.f && y2 == 0.f);
     }
     
@@ -448,7 +448,7 @@ struct biquad_d2: public biquad_coeffs<Coeff>
     }
 
     /// Is the filter state completely silent? (i.e. set to 0 by sanitize function)
-    inline bool empty() {
+    inline bool empty() const {
         return (w1 == 0.f && w2 == 0.f);
     }
     
@@ -575,6 +575,74 @@ struct biquad_d1_lerp: public biquad_coeffs<Coeff>
     
 };
     
+/// Compose two filters in series
+template<class F1, class F2>
+class filter_compose {
+public:
+    typedef std::complex<float> cfloat;
+    F1 f1;
+    F2 f2;
+public:
+    float process(float value) {
+        return f2.process(f1.process(value));
+    }
+    
+    inline cfloat h_z(const cfloat &z) const {
+        return f1.h_z(z) * f2.h_z(z);
+    }
+    
+    /// Return the filter's gain at frequency freq
+    /// @param freq   Frequency to look up
+    /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
+    float freq_gain(float freq, float sr) const
+    {
+        typedef std::complex<double> cfloat;
+        freq *= 2.0 * M_PI / sr;
+        cfloat z = 1.0 / exp(cfloat(0.0, freq));
+        
+        return std::abs(h_z(z));
+    }
+    
+    void sanitize() {
+        f1.sanitize();
+        f2.sanitize();
+    }
+};
+
+/// Compose two filters in parallel
+template<class F1, class F2>
+class filter_sum {
+public:
+    typedef std::complex<double> cfloat;
+    F1 f1;
+    F2 f2;
+public:
+    float process(float value) {
+        return f2.process(value) + f1.process(value);
+    }
+    
+    inline cfloat h_z(const cfloat &z) const {
+        return f1.h_z(z) + f2.h_z(z);
+    }
+    
+    /// Return the filter's gain at frequency freq
+    /// @param freq   Frequency to look up
+    /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
+    float freq_gain(float freq, float sr) const
+    {
+        typedef std::complex<double> cfloat;
+        freq *= 2.0 * M_PI / sr;
+        cfloat z = 1.0 / exp(cfloat(0.0, freq));
+        
+        return std::abs(h_z(z));
+    }
+    
+    void sanitize() {
+        f1.sanitize();
+        f2.sanitize();
+    }
+};
+
 };
 
 #endif
diff --git a/src/calf/custom_ctl.h b/src/calf/custom_ctl.h
index fa09bf7..831c12f 100644
--- a/src/calf/custom_ctl.h
+++ b/src/calf/custom_ctl.h
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
 struct CalfLineGraph
 {
     GtkDrawingArea parent;
-    calf_plugins::line_graph_iface *source;
+    const calf_plugins::line_graph_iface *source;
     int source_id;
     bool is_square;
     cairo_surface_t *cache_surface;
diff --git a/src/calf/giface.h b/src/calf/giface.h
index a41db4c..eace902 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -168,17 +168,17 @@ struct line_graph_iface
     /// @param context cairo context to adjust (for multicolour graphs etc.)
     /// @retval true graph data was returned; subindex+1 graph may or may not be available
     /// @retval false graph data was not returned; subindex+1 graph does not exist either
-    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) { return false; }
+    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { return false; }
 
     /// Obtain subindex'th dot of parameter 'index'
     /// @param index parameter/dot number (usually tied to particular plugin control port)
     /// @param subindex dot number (there may be multiple dots graphs for one parameter)
-    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) { return false; }
+    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { return false; }
     
     /// Obtain subindex'th dot of parameter 'index'
     /// @param index parameter/dot number (usually tied to particular plugin control port)
     /// @param subindex dot number (there may be multiple dots graphs for one parameter)
-    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) { return false; }
+    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return false; }
     
     /// Obtain subindex'th static graph of parameter index (static graphs are only dependent on parameter value, not plugin state)
     /// @param index parameter/graph number (usually tied to particular plugin control port)
@@ -189,7 +189,7 @@ struct line_graph_iface
     /// @param context cairo context to adjust (for multicolour graphs etc.)
     /// @retval true graph data was returned; subindex+1 graph may or may not be available
     /// @retval false graph data was not returned; subindex+1 graph does not exist either
-    virtual bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context) { return false; }
+    virtual bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context) const { return false; }
     
     /// Return which graphs need to be redrawn and which can be cached for later reuse
     /// @param index Parameter/graph number (usually tied to particular plugin control port)
@@ -198,7 +198,7 @@ struct line_graph_iface
     /// @param subindex_dot First dot that has to be redrawn
     /// @param subindex_gridline First gridline/legend that has to be redrawn
     /// @retval Current generation (to pass when calling the function next time); if different than passed generation value, call the function again to retrieve which graph offsets should be put into cache
-    virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) { subindex_graph = subindex_dot = subindex_gridline = 0; return 0; }
+    virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { subindex_graph = subindex_dot = subindex_gridline = 0; return 0; }
     
     /// Standard destructor to make compiler happy
     virtual ~line_graph_iface() {}
@@ -229,22 +229,22 @@ struct table_column_info
 struct table_edit_iface
 {
     /// retrieve the table layout for specific parameter
-    virtual const table_column_info *get_table_columns(int param) = 0;
+    virtual const table_column_info *get_table_columns(int param) const = 0;
 
     /// return the current number of rows
-    virtual uint32_t get_table_rows(int param) = 0;
+    virtual uint32_t get_table_rows(int param) const = 0;
     
     /// retrieve data item from the plugin
-    virtual std::string get_cell(int param, int row, int column) { return calf_utils::i2s(row)+":"+calf_utils::i2s(column); }
+    virtual std::string get_cell(int param, int row, int column) const { return calf_utils::i2s(row)+":"+calf_utils::i2s(column); }
 
     /// set data item to the plugin
-    virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) { error.clear(); }
+    virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const { error.clear(); }
     
     /// return a line graph interface for a specific parameter/column (unused for now)
-    virtual line_graph_iface *get_graph_iface(int param, int column) { return NULL; }
+    virtual const line_graph_iface *get_graph_iface(int param, int column) const { return NULL; }
     
     /// return an editor name for a specific grid cell (unused for now - I don't even know how editors be implemented)
-    virtual const char *get_cell_editor(int param, int column) { return NULL; }
+    virtual const char *get_cell_editor(int param, int column) const { return NULL; }
     
     virtual ~table_edit_iface() {}
 };
@@ -294,53 +294,53 @@ struct ladspa_plugin_info
 struct plugin_metadata_iface
 {
     /// @return plugin long name
-    virtual const char *get_name() = 0;
+    virtual const char *get_name() const = 0;
     /// @return plugin LV2 label
-    virtual const char *get_id() = 0;
+    virtual const char *get_id() const = 0;
     /// @return plugin human-readable label
-    virtual const char *get_label() = 0;
+    virtual const char *get_label() const = 0;
     /// @return total number of parameters
-    virtual int get_param_count() = 0;
+    virtual int get_param_count() const = 0;
     /// Return custom XML
-    virtual const char *get_gui_xml() = 0;
+    virtual const char *get_gui_xml() const = 0;
     /// @return number of audio inputs
-    virtual int get_input_count()=0;
+    virtual int get_input_count() const =0;
     /// @return number of audio outputs
-    virtual int get_output_count()=0;
+    virtual int get_output_count() const =0;
     /// @return number of optional inputs
-    virtual int get_inputs_optional()=0;
+    virtual int get_inputs_optional() const =0;
     /// @return number of optional outputs
-    virtual int get_outputs_optional()=0;
+    virtual int get_outputs_optional() const =0;
     /// @return true if plugin can work in hard-realtime conditions
-    virtual bool is_rt_capable()=0;
+    virtual bool is_rt_capable() const =0;
     /// @return true if plugin has MIDI input
-    virtual bool get_midi()=0;
+    virtual bool get_midi() const =0;
     /// @return true if plugin has MIDI input
-    virtual bool requires_midi()=0;
+    virtual bool requires_midi() const =0;
     /// @return port offset of first control (parameter) port (= number of audio inputs + number of audio outputs in all existing plugins as for 1 Aug 2008)
-    virtual int get_param_port_offset() = 0;
+    virtual int get_param_port_offset() const  = 0;
     /// @return line_graph_iface if any
-    virtual line_graph_iface *get_line_graph_iface() = 0;
+    virtual const line_graph_iface *get_line_graph_iface() const = 0;
     /// @return table_edit_iface if any
-    virtual table_edit_iface *get_table_edit_iface() = 0;
+    virtual const table_edit_iface *get_table_edit_iface() const = 0;
     /// @return NULL-terminated list of menu commands
-    virtual plugin_command_info *get_commands() { return NULL; }
+    virtual plugin_command_info *get_commands() const { return NULL; }
     /// @return description structure for given parameter
-    virtual parameter_properties *get_param_props(int param_no) = 0;
+    virtual parameter_properties *get_param_props(int param_no) const = 0;
     /// @return retrieve names of audio ports (@note control ports are named in parameter_properties, not here)
-    virtual const char **get_port_names() = 0;
+    virtual const char **get_port_names() const = 0;
     /// @return description structure for the plugin
-    virtual const ladspa_plugin_info &get_plugin_info() = 0;
+    virtual const ladspa_plugin_info &get_plugin_info() const = 0;
     /// is a given parameter a control voltage?
-    virtual bool is_cv(int param_no) = 0;
+    virtual bool is_cv(int param_no) const = 0;
     /// is the given parameter non-interpolated?
-    virtual bool is_noisy(int param_no) = 0;
+    virtual bool is_noisy(int param_no) const = 0;
     /// does the plugin require message context? (or DSSI configure) may be slow
-    virtual bool requires_message_context() = 0;
+    virtual bool requires_message_context() const = 0;
     /// does the plugin require string port extension? (or DSSI configure) may be slow
-    virtual bool requires_string_ports() = 0;
+    virtual bool requires_string_ports() const = 0;
     /// add all message context parameter numbers to the ports vector
-    virtual void get_message_context_parameters(std::vector<int> &ports) = 0;
+    virtual void get_message_context_parameters(std::vector<int> &ports) const = 0;
 
     /// Do-nothing destructor to silence compiler warning
     virtual ~plugin_metadata_iface() {}
@@ -377,8 +377,20 @@ struct plugin_ctl_iface: public virtual plugin_metadata_iface
 
 struct plugin_list_info_iface;
 
-/// Get a list of all "large" (effect/synthesizer) plugins
-extern void get_all_plugins(std::vector<plugin_metadata_iface *> &plugins);
+class plugin_registry
+{
+public:
+    typedef std::vector<plugin_metadata_iface *> plugin_vector;    
+private:
+    plugin_vector plugins;
+    plugin_registry();
+public:
+    static plugin_registry &instance();
+
+    const plugin_vector &get_all() { return plugins; }
+    plugin_metadata_iface *get_by_uri(const char *URI);
+};
+
 /// Get a list of all "small" (module) plugins
 extern void get_all_small_plugins(plugin_list_info_iface *plii);
 /// Load and strdup a text file with GUI definition
@@ -489,30 +501,30 @@ public:
     // These below are stock implementations based on enums and static members in Metadata classes
     // they may be overridden to provide more interesting functionality
 
-    const char *get_name() { return Metadata::impl_get_name(); } 
-    const char *get_id() { return Metadata::impl_get_id(); } 
-    const char *get_label() { return Metadata::impl_get_label(); } 
-    int get_input_count() { return Metadata::in_count; }
-    int get_output_count() { return Metadata::out_count; }
-    int get_inputs_optional() { return Metadata::ins_optional; }
-    int get_outputs_optional() { return Metadata::outs_optional; }
-    int get_param_count() { return Metadata::param_count; }
-    bool get_midi() { return Metadata::support_midi; }
-    bool requires_midi() { return Metadata::require_midi; }
-    bool is_rt_capable() { return Metadata::rt_capable; }
-    line_graph_iface *get_line_graph_iface() { return dynamic_cast<line_graph_iface *>(this); }    
-    table_edit_iface *get_table_edit_iface() { return dynamic_cast<table_edit_iface *>(this); }    
-    int get_param_port_offset()  { return Metadata::in_count + Metadata::out_count; }
-    const char *get_gui_xml() { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; }
-    plugin_command_info *get_commands() { return NULL; }
-    parameter_properties *get_param_props(int param_no) { return &param_props[param_no]; }
-    const char **get_port_names() { return port_names; }
-    bool is_cv(int param_no) { return true; }
-    bool is_noisy(int param_no) { return false; }
-    const ladspa_plugin_info &get_plugin_info() { return plugin_info; }
-    bool requires_message_context() { return check_for_message_context_ports(param_props, Metadata::param_count); }
-    bool requires_string_ports() { return check_for_string_ports(param_props, Metadata::param_count); }
-    void get_message_context_parameters(std::vector<int> &ports) {
+    const char *get_name() const { return Metadata::impl_get_name(); } 
+    const char *get_id() const { return Metadata::impl_get_id(); } 
+    const char *get_label() const { return Metadata::impl_get_label(); } 
+    int get_input_count() const { return Metadata::in_count; }
+    int get_output_count() const { return Metadata::out_count; }
+    int get_inputs_optional() const { return Metadata::ins_optional; }
+    int get_outputs_optional() const { return Metadata::outs_optional; }
+    int get_param_count() const { return Metadata::param_count; }
+    bool get_midi() const { return Metadata::support_midi; }
+    bool requires_midi() const { return Metadata::require_midi; }
+    bool is_rt_capable() const { return Metadata::rt_capable; }
+    const line_graph_iface *get_line_graph_iface() const { return dynamic_cast<const line_graph_iface *>(this); }    
+    const table_edit_iface *get_table_edit_iface() const { return dynamic_cast<const table_edit_iface *>(this); }    
+    int get_param_port_offset()  const { return Metadata::in_count + Metadata::out_count; }
+    const char *get_gui_xml() const { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; }
+    plugin_command_info *get_commands() const { return NULL; }
+    parameter_properties *get_param_props(int param_no) const { return &param_props[param_no]; }
+    const char **get_port_names() const { return port_names; }
+    bool is_cv(int param_no) const { return true; }
+    bool is_noisy(int param_no) const { return false; }
+    const ladspa_plugin_info &get_plugin_info() const { return plugin_info; }
+    bool requires_message_context() const { return check_for_message_context_ports(param_props, Metadata::param_count); }
+    bool requires_string_ports() const { return check_for_string_ports(param_props, Metadata::param_count); }
+    void get_message_context_parameters(std::vector<int> &ports) const {
         for (int i = 0; i < get_param_count(); ++i) {
             if (get_param_props(i)->flags & PF_PROP_MSGCONTEXT)
                 ports.push_back(i);
@@ -530,30 +542,30 @@ public:
     plugin_metadata_iface *impl;
 public:
     plugin_metadata_proxy(plugin_metadata_iface *_impl) { impl = _impl; }
-    const char *get_name() { return impl->get_name(); } 
-    const char *get_id() { return impl->get_id(); } 
-    const char *get_label() { return impl->get_label(); } 
-    int get_input_count() { return impl->get_input_count(); }
-    int get_output_count() { return impl->get_output_count(); }
-    int get_inputs_optional() { return impl->get_inputs_optional(); }
-    int get_outputs_optional() { return impl->get_outputs_optional(); }
-    int get_param_count() { return impl->get_param_count(); }
-    bool get_midi() { return impl->get_midi(); }
-    bool requires_midi() { return impl->requires_midi(); }
-    bool is_rt_capable() { return impl->is_rt_capable(); }
-    line_graph_iface *get_line_graph_iface() { return impl->get_line_graph_iface(); }    
-    table_edit_iface *get_table_edit_iface() { return impl->get_table_edit_iface(); }    
-    int get_param_port_offset()  { return impl->get_param_port_offset(); }
-    const char *get_gui_xml() { return impl->get_gui_xml(); }
-    plugin_command_info *get_commands() { return impl->get_commands(); }
-    parameter_properties *get_param_props(int param_no) { return impl->get_param_props(param_no); }
-    const char **get_port_names() { return impl->get_port_names(); }
-    bool is_cv(int param_no) { return impl->is_cv(param_no); }
-    bool is_noisy(int param_no) { return impl->is_noisy(param_no); }
-    const ladspa_plugin_info &get_plugin_info() { return impl->get_plugin_info(); }
-    bool requires_message_context() { return impl->requires_message_context(); }
-    bool requires_string_ports() { return impl->requires_string_ports(); }
-    void get_message_context_parameters(std::vector<int> &ports) { impl->get_message_context_parameters(ports); }
+    const char *get_name() const { return impl->get_name(); } 
+    const char *get_id() const { return impl->get_id(); } 
+    const char *get_label() const { return impl->get_label(); } 
+    int get_input_count() const { return impl->get_input_count(); }
+    int get_output_count() const { return impl->get_output_count(); }
+    int get_inputs_optional() const { return impl->get_inputs_optional(); }
+    int get_outputs_optional() const { return impl->get_outputs_optional(); }
+    int get_param_count() const { return impl->get_param_count(); }
+    bool get_midi() const { return impl->get_midi(); }
+    bool requires_midi() const { return impl->requires_midi(); }
+    bool is_rt_capable() const { return impl->is_rt_capable(); }
+    const line_graph_iface *get_line_graph_iface() const { return impl->get_line_graph_iface(); }    
+    const table_edit_iface *get_table_edit_iface() const { return impl->get_table_edit_iface(); }    
+    int get_param_port_offset() const { return impl->get_param_port_offset(); }
+    const char *get_gui_xml() const { return impl->get_gui_xml(); }
+    plugin_command_info *get_commands() const { return impl->get_commands(); }
+    parameter_properties *get_param_props(int param_no) const { return impl->get_param_props(param_no); }
+    const char **get_port_names() const { return impl->get_port_names(); }
+    bool is_cv(int param_no) const { return impl->is_cv(param_no); }
+    bool is_noisy(int param_no) const { return impl->is_noisy(param_no); }
+    const ladspa_plugin_info &get_plugin_info() const { return impl->get_plugin_info(); }
+    bool requires_message_context() const { return impl->requires_message_context(); }
+    bool requires_string_ports() const { return impl->requires_string_ports(); }
+    void get_message_context_parameters(std::vector<int> &ports) const { impl->get_message_context_parameters(ports); }
 };
 
 #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
diff --git a/src/calf/gui_controls.h b/src/calf/gui_controls.h
index 150f9a3..7a97432 100644
--- a/src/calf/gui_controls.h
+++ b/src/calf/gui_controls.h
@@ -271,7 +271,7 @@ struct listview_param_control: public param_control, public send_configure_iface
 {
     GtkTreeView *tree;
     GtkListStore *lstore;
-    calf_plugins::table_edit_iface *teif;
+    const calf_plugins::table_edit_iface *teif;
     int cols;
     std::vector<GtkTreeIter> positions;
     
diff --git a/src/calf/ladspa_wrap.h b/src/calf/ladspa_wrap.h
index 73c3969..2f98dcf 100644
--- a/src/calf/ladspa_wrap.h
+++ b/src/calf/ladspa_wrap.h
@@ -99,9 +99,9 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
     virtual const char *get_gui_xml() {
         return Module::get_gui_xml();
     }
-    virtual line_graph_iface *get_line_graph_iface()
+    virtual const line_graph_iface *get_line_graph_iface() const
     {
-        return dynamic_cast<line_graph_iface *>(this);
+        return dynamic_cast<const 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 8d2f172..fcbff10 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -96,28 +96,28 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface, publ
     virtual const char *get_gui_xml() {
         return Module::get_gui_xml();
     }
-    virtual line_graph_iface *get_line_graph_iface()
+    virtual const line_graph_iface *get_line_graph_iface() const
     {
-        return dynamic_cast<line_graph_iface *>(this);
+        return dynamic_cast<const line_graph_iface *>(this);
     }
     virtual bool activate_preset(int bank, int program) { 
         return false;
     }
-    virtual const char *get_name()
+    virtual const char *get_name() const
     {
         return Module::get_name();
     }
-    virtual const char *get_id()
+    virtual const char *get_id() const
     {
         return Module::get_id();
     }
-    virtual const char *get_label()
+    virtual const char *get_label() const
     {
         return Module::get_label();
     }
-    virtual int get_input_count() { return Module::in_count; }
-    virtual int get_output_count() { return Module::out_count; }
-    virtual bool get_midi() { return Module::support_midi; }
+    virtual int get_input_count() const { return Module::in_count; }
+    virtual int get_output_count() const { return Module::out_count; }
+    virtual bool get_midi() const { return Module::support_midi; }
     virtual float get_level(unsigned int port) { return 0.f; }
     virtual void execute(int cmd_no) {
         Module::execute(cmd_no);
diff --git a/src/calf/modmatrix.h b/src/calf/modmatrix.h
index e43e09f..5db95fc 100644
--- a/src/calf/modmatrix.h
+++ b/src/calf/modmatrix.h
@@ -84,10 +84,10 @@ protected:
 
     mod_matrix(dsp::modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names);
 public:
-    virtual const table_column_info *get_table_columns(int param);
-    virtual uint32_t get_table_rows(int param);
-    virtual std::string get_cell(int param, int row, int column);
-    virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error);
+    virtual const table_column_info *get_table_columns(int param) const;
+    virtual uint32_t get_table_rows(int param) const;
+    virtual std::string get_cell(int param, int row, int column) const;
+    virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const;
 
     /// Process modulation matrix, calculate outputs from inputs
     inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc)
diff --git a/src/calf/modules.h b/src/calf/modules.h
index ee89067..b3ed83b 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -65,8 +65,8 @@ public:
 class frequency_response_line_graph: public line_graph_iface 
 {
 public:
-    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 class flanger_audio_module: public audio_module<flanger_metadata>, public frequency_response_line_graph
@@ -126,8 +126,8 @@ public:
         right.process(outs[1] + offset, ins[1] + offset, nsamples);
         return outputs_mask; // XXXKF allow some delay after input going blank
     }
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    float freq_gain(int subindex, float freq, float srate);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    float freq_gain(int subindex, float freq, float srate) const;
 };
 
 class phaser_audio_module: public audio_module<phaser_metadata>, public frequency_response_line_graph
@@ -189,9 +189,9 @@ public:
         right.process(outs[1] + offset, ins[1] + offset, nsamples);
         return outputs_mask; // XXXKF allow some delay after input going blank
     }
-    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);
-    float freq_gain(int subindex, float freq, float srate);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    float freq_gain(int subindex, float freq, float srate) const;
 };
 
 class reverb_audio_module: public audio_module<reverb_metadata>
@@ -571,74 +571,6 @@ public:
     virtual void control_change(int ctl, int val);
 };
 
-/// Compose two filters in series
-template<class F1, class F2>
-class filter_compose {
-public:
-    typedef std::complex<float> cfloat;
-    F1 f1;
-    F2 f2;
-public:
-    float process(float value) {
-        return f2.process(f1.process(value));
-    }
-    
-    cfloat h_z(const cfloat &z) {
-        return f1.h_z(z) * f2.h_z(z);
-    }
-    
-    /// Return the filter's gain at frequency freq
-    /// @param freq   Frequency to look up
-    /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
-    float freq_gain(float freq, float sr)
-    {
-        typedef std::complex<double> cfloat;
-        freq *= 2.0 * M_PI / sr;
-        cfloat z = 1.0 / exp(cfloat(0.0, freq));
-        
-        return std::abs(h_z(z));
-    }
-    
-    void sanitize() {
-        f1.sanitize();
-        f2.sanitize();
-    }
-};
-
-/// Compose two filters in parallel
-template<class F1, class F2>
-class filter_sum {
-public:
-    typedef std::complex<double> cfloat;
-    F1 f1;
-    F2 f2;
-public:
-    float process(float value) {
-        return f2.process(value) + f1.process(value);
-    }
-    
-    inline cfloat h_z(const cfloat &z) {
-        return f1.h_z(z) + f2.h_z(z);
-    }
-    
-    /// Return the filter's gain at frequency freq
-    /// @param freq   Frequency to look up
-    /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
-    float freq_gain(float freq, float sr)
-    {
-        typedef std::complex<double> cfloat;
-        freq *= 2.0 * M_PI / sr;
-        cfloat z = 1.0 / exp(cfloat(0.0, freq));
-        
-        return std::abs(h_z(z));
-    }
-    
-    void sanitize() {
-        f1.sanitize();
-        f2.sanitize();
-    }
-};
-
 template<typename FilterClass, typename Metadata>
 class filter_module_with_inertia: public FilterClass
 {
@@ -652,7 +584,7 @@ public:
     inertia<exponential_ramp> inertia_cutoff, inertia_resonance, inertia_gain;
     once_per_n timer;
     bool is_active;    
-    volatile int last_generation, last_calculated_generation;
+    mutable volatile int last_generation, last_calculated_generation;
     
     filter_module_with_inertia()
     : inertia_cutoff(exponential_ramp(128), 20)
@@ -749,7 +681,7 @@ class filter_audio_module:
     public filter_module_with_inertia<biquad_filter_module, filter_metadata>, 
     public frequency_response_line_graph
 {
-    float old_cutoff, old_resonance, old_mode;
+    mutable float old_cutoff, old_resonance, old_mode;
 public:    
     filter_audio_module()
     {
@@ -778,8 +710,8 @@ public:
         inertia_filter_module::deactivate();
     }
     
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// A multitap stereo chorus thing - processing
@@ -840,10 +772,10 @@ public:
     void activate();
     void deactivate();
     void set_sample_rate(uint32_t sr);
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    float freq_gain(int subindex, float freq, float srate);
-    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    float freq_gain(int subindex, float freq, float srate) const;
+    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
 };
 
 class gain_reduction_audio_module {
@@ -851,12 +783,12 @@ private:
     float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop;
     float compressedKneeStop, adjKneeStart, thres;
     float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp;
-    float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link;
-    int last_generation;
+    mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link;
+    mutable volatile int last_generation;
     uint32_t srate;
     bool is_active;
-    inline float output_level(float slope);
-    inline float output_gain(float linSlope, bool rms);
+    inline float output_level(float slope) const;
+    inline float output_gain(float linSlope, bool rms) const;
 public:
     gain_reduction_audio_module();
     void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu);
@@ -867,10 +799,10 @@ public:
     void set_sample_rate(uint32_t sr);
     float get_output_level();
     float get_comp_level();
-    virtual bool get_graph(int subindex, float *data, int points, cairo_iface *context);
-    virtual bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context);
-    virtual bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    virtual int  get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    virtual bool get_graph(int subindex, float *data, int points, cairo_iface *context) const;
+    virtual bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    virtual bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    virtual int  get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// Compressor by Thor
@@ -886,17 +818,17 @@ public:
     float *params[param_count];
     uint32_t srate;
     bool is_active;
-    volatile int last_generation, last_calculated_generation;
+    mutable volatile int last_generation, last_calculated_generation;
     compressor_audio_module();
     void activate();
     void deactivate();
     void params_changed();
     void set_sample_rate(uint32_t sr);
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters)
@@ -914,9 +846,10 @@ private:
         BANDPASS_1,
         BANDPASS_2
     };
-    float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old;
-    float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1;
-    CalfScModes sc_mode, sc_mode_old, sc_mode_old1;
+    mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old;
+    mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1;
+    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;
@@ -929,12 +862,12 @@ public:
     float *params[param_count];
     uint32_t srate;
     bool is_active;
-    volatile int last_generation, last_calculated_generation;
+    mutable volatile int last_generation, last_calculated_generation;
     sidechaincompressor_audio_module();
     void activate();
     void deactivate();
     void params_changed();
-    inline cfloat h_z(const cfloat &z) {
+    inline cfloat h_z(const cfloat &z) const {
         switch (sc_mode) {
             default:
             case WIDEBAND:
@@ -958,7 +891,7 @@ public:
         }
                 
     }
-    float freq_gain(int index, double freq, uint32_t sr)
+    float freq_gain(int index, double freq, uint32_t sr) const
     {
         typedef std::complex<double> cfloat;
         freq *= 2.0 * M_PI / sr;
@@ -968,10 +901,10 @@ public:
     }
     void set_sample_rate(uint32_t sr);
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// Multibandcompressor by Markus Schmidt
@@ -996,10 +929,10 @@ public:
     void params_changed();
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
     void set_sample_rate(uint32_t sr);
-    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    virtual int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    virtual int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// Deesser by Markus Schmidt (based on Thor's compressor and Krzysztof's filters)
@@ -1009,8 +942,8 @@ private:
         WIDE,
         SPLIT
     };
-    float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old;
-    float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1;
+    mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old;
+    mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1;
     uint32_t detected_led;
     float detected, clip_out;
     uint32_t clip_led;
@@ -1022,20 +955,20 @@ public:
     float *params[param_count];
     uint32_t srate;
     bool is_active;
-    volatile int last_generation, last_calculated_generation;
+    mutable volatile int last_generation, last_calculated_generation;
     deesser_audio_module();
     void activate();
     void deactivate();
     void params_changed();
-    float freq_gain(int index, double freq, uint32_t sr)
+    float freq_gain(int index, double freq, uint32_t sr) const
     {
         return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr);
     }
     void set_sample_rate(uint32_t sr);
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    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);
-    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 /// Equalizer N Band by Markus Schmidt (based on Krzysztof's filters)
@@ -1054,7 +987,7 @@ private:
     float ls_level_old, ls_freq_old;
     float hs_level_old, hs_freq_old;
     float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands];
-    float old_params_for_graph[graph_param_count];
+    mutable float old_params_for_graph[graph_param_count];
     uint32_t clip_inL, clip_outL, clip_inR, clip_outR;
     float meter_inL, meter_outL, meter_inR, meter_outR;
     CalfEqMode hp_mode, lp_mode;
@@ -1070,21 +1003,21 @@ public:
     float *params[param_count];
     uint32_t srate;
     bool is_active;
-    volatile int last_generation, last_calculated_generation;
+    mutable volatile int last_generation, last_calculated_generation;
     equalizerNband_audio_module();
     void activate();
     void deactivate();
 
     void params_changed();
-    float freq_gain(int index, double freq, uint32_t sr);
+    float freq_gain(int index, double freq, uint32_t sr) const;
     void set_sample_rate(uint32_t sr)
     {
         srate = sr;
     }
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    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);
-    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
 };
 
 typedef equalizerNband_audio_module<equalizer5band_metadata, false> equalizer5band_audio_module;
@@ -1106,9 +1039,9 @@ public:
     void set_phase(float ph);
     void activate();
     void deactivate();
-    float get_value_from_phase(float ph, float off);
-    virtual bool get_graph(float *data, int points, cairo_iface *context);
-    virtual bool get_dot(float &x, float &y, int &size, cairo_iface *context);
+    float get_value_from_phase(float ph, float off) const;
+    virtual bool get_graph(float *data, int points, cairo_iface *context) const;
+    virtual bool get_dot(float &x, float &y, int &size, cairo_iface *context) const;
 };
 
 /// Pulsator by Markus Schmidt
@@ -1139,9 +1072,9 @@ public:
         }
     }
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
 };
 
 /// Filterclavier --- MIDI controlled filter by Hans Baier
@@ -1229,7 +1162,7 @@ public:
         }
     }
 
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
     
 private:
     void adjust_gain_according_to_filter_mode(int velocity) {
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index 090acbd..d57f61f 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -132,7 +132,7 @@ public:
     /// Run two filters (one per channel) to produce stereo output samples.
     void calculate_buffer_stereo();
     /// Retrieve filter graph (which is 'live' so it cannot be generated by get_static_graph), or fall back to get_static_graph.
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
     /// @retval true if the filter 1 is to be used for the left channel and filter 2 for the right channel
     /// @retval false if filters are to be connected in series and sent (mono) to both channels    
     inline bool is_stereo_filter() const
@@ -140,9 +140,9 @@ public:
         return filter_type == flt_2lp12 || filter_type == flt_2bp6;
     }
     /// No CV inputs for now
-    bool is_cv(int param_no) { return false; }
+    bool is_cv(int param_no) const { return false; }
     /// Practically all the stuff here is noisy
-    bool is_noisy(int param_no) { return param_no != par_cutoff; }
+    bool is_noisy(int param_no) const { return param_no != par_cutoff; }
     /// Calculate control signals and produce step_size samples of output.
     void calculate_step();
     /// Main processing function
diff --git a/src/calf/multichorus.h b/src/calf/multichorus.h
index 23a1f4f..b954603 100644
--- a/src/calf/multichorus.h
+++ b/src/calf/multichorus.h
@@ -80,7 +80,7 @@ public:
         voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling);
     }
     /// Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close)
-    inline int get_value(uint32_t voice) {
+    inline int get_value(uint32_t voice) const {
         // find this voice's phase (= phase + voice * 360 degrees / number of voices)
         chorus_phase voice_phase = phase + vphase * (int)voice;
         // find table offset
@@ -178,7 +178,7 @@ public:
         }
         post.sanitize();
     }
-    float freq_gain(float freq, float sr)
+    float freq_gain(float freq, float sr) const
     {
         typedef std::complex<double> cfloat;
         freq *= 2.0 * M_PI / sr;
diff --git a/src/calf/onepole.h b/src/calf/onepole.h
index 2bc2325..5fdc669 100644
--- a/src/calf/onepole.h
+++ b/src/calf/onepole.h
@@ -144,7 +144,7 @@ public:
         return out;
     }
     
-    inline bool empty() {
+    inline bool empty() const {
         return y1 == 0;
     }
     
@@ -171,7 +171,7 @@ public:
     /// Return the filter's gain at frequency freq
     /// @param freq   Frequency to look up
     /// @param sr     Filter sample rate (used to convert frequency to angular frequency)
-    float freq_gain(float freq, float sr)
+    float freq_gain(float freq, float sr) const
     {
         freq *= 2.0 * M_PI / sr;
         cfloat z = 1.0 / exp(cfloat(0.0, freq));
@@ -181,7 +181,7 @@ public:
     
     /// Return H(z) the filter's gain at frequency freq
     /// @param z   Z variable (e^jw)
-    cfloat h_z(const cfloat &z)
+    cfloat h_z(const cfloat &z) const
     {
         return (cfloat(a0) + double(a1) * z) / (cfloat(1.0) + double(b1) * z);
     }
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 4ec9cc2..927bdcf 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -207,18 +207,18 @@ struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy, publ
         for (map<string, string>::iterator i = cfg_vars.begin(); i != cfg_vars.end(); i++)
             sci->send_configure(i->first.c_str(), i->second.c_str());
     }
-    virtual line_graph_iface *get_line_graph_iface() { return this; }
-    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-    void update_cairo_context(cairo_iface *context, cairo_params &item);
+    virtual const line_graph_iface *get_line_graph_iface() const { return this; }
+    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+    void update_cairo_context(cairo_iface *context, cairo_params &item) const;
 };
 
-bool plugin_proxy::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool plugin_proxy::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!graphs.count(index))
         return false;
-    param_line_graphs &g = graphs[index];
+    const param_line_graphs &g = graphs.find(index)->second;
     if (subindex < (int)g.graphs.size())
     {
         float *sdata = g.graphs[subindex]->data;
@@ -233,11 +233,11 @@ bool plugin_proxy::get_graph(int index, int subindex, float *data, int points, c
     return false;
 }
 
-bool plugin_proxy::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool plugin_proxy::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!graphs.count(index))
         return false;
-    param_line_graphs &g = graphs[index];
+    const param_line_graphs &g = graphs.find(index)->second;
     if (subindex < (int)g.dots.size())
     {
         dot_item &item = *g.dots[subindex];
@@ -250,11 +250,11 @@ bool plugin_proxy::get_dot(int index, int subindex, float &x, float &y, int &siz
     return false;
 }
 
-bool plugin_proxy::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool plugin_proxy::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     if (!graphs.count(index))
         return false;
-    param_line_graphs &g = graphs[index];
+    const param_line_graphs &g = graphs.find(index)->second;
     if (subindex < (int)g.gridlines.size())
     {
         gridline_item &item = *g.gridlines[subindex];
@@ -267,7 +267,7 @@ bool plugin_proxy::get_gridline(int index, int subindex, float &pos, bool &verti
     return false;
 }
 
-void plugin_proxy::update_cairo_context(cairo_iface *context, cairo_params &item)
+void plugin_proxy::update_cairo_context(cairo_iface *context, cairo_params &item) const
 {
     if (item.flags & cairo_params::HAS_COLOR)
         context->set_source_rgba(item.r, item.g, item.b, item.a);
@@ -317,8 +317,7 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
     void create_window()
     {
         plugin = NULL;
-        vector<plugin_metadata_iface *> plugins;
-        get_all_plugins(plugins);
+        const plugin_registry::plugin_vector &plugins = plugin_registry::instance().get_all();
         for (unsigned int i = 0; i < plugins.size(); i++)
         {
             if (!strcmp(plugins[i]->get_id(), effect_name.c_str()))
diff --git a/src/giface.cpp b/src/giface.cpp
index bc04077..f950256 100644
--- a/src/giface.cpp
+++ b/src/giface.cpp
@@ -292,6 +292,30 @@ void calf_plugins::set_channel_color(cairo_iface *context, int channel)
     context->set_line_width(1.5);
 }
 
+///////////////////////////////////////////////////////////////////////////////////////
+
+calf_plugins::plugin_registry &calf_plugins::plugin_registry::instance()
+{
+    static calf_plugins::plugin_registry registry;
+    return registry;
+}
+
+plugin_metadata_iface *calf_plugins::plugin_registry::get_by_uri(const char *plugin_uri)
+{
+    static const char prefix[] = "http://calf.sourceforge.net/plugins/";
+    if (strncmp(plugin_uri, prefix, sizeof(prefix) - 1))
+        return NULL;
+    const char *label = plugin_uri + sizeof(prefix) - 1;
+    for (unsigned int i = 0; i < plugins.size(); i++)
+    {
+        if (!strcmp(plugins[i]->get_plugin_info().label, label))
+            return plugins[i];
+    }    
+    return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
 #if USE_DSSI
 struct osc_cairo_control: public cairo_iface
 {
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index 6f4454a..6cb9cf3 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -29,6 +29,7 @@
 #include <calf/lv2_string_port.h>
 #include <calf/lv2_ui.h>
 #include <calf/lv2_uri_map.h>
+#include <calf/lv2_external_ui.h>
 #include <calf/preset_gui.h>
 #include <calf/utils.h>
 #include <calf/lv2helpers.h>
@@ -112,7 +113,7 @@ struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy
         return false;
     }
     
-    virtual line_graph_iface *get_line_graph_iface() {
+    virtual const line_graph_iface *get_line_graph_iface() const {
         if (instance)
             return instance->get_line_graph_iface();
         return NULL;
@@ -187,18 +188,11 @@ LV2UI_Handle gui_instantiate(const struct _LV2UI_Descriptor* descriptor,
                           LV2UI_Widget*                   widget,
                           const LV2_Feature* const*       features)
 {
-    vector<plugin_metadata_iface *> plugins;
-    get_all_plugins(plugins);
-    const char *label = plugin_uri + sizeof("http://calf.sourceforge.net/plugins/") - 1;
     plugin_proxy *proxy = NULL;
-    for (unsigned int i = 0; i < plugins.size(); i++)
-    {
-        if (!strcmp(plugins[i]->get_plugin_info().label, label))
-        {
-            proxy = new plugin_proxy(plugins[i]);
-            break;
-        }
-    }
+    plugin_metadata_iface *md = plugin_registry::instance().get_by_uri(plugin_uri);
+    if (!md)
+        return NULL;
+    proxy = new plugin_proxy(md);
     if (!proxy)
         return NULL;
     for (int i = 0; features[i]; i++)
@@ -405,9 +399,69 @@ const void *sgui_extension(const char *uri)
 
 ///////////////////////////////////////////////////////////////////////////////////////
 
+class ext_plugin_gui: public lv2_external_ui
+{
+public:
+    LV2UI_Write_Function write_function;
+    LV2UI_Controller controller;
+
+    ext_plugin_gui(LV2UI_Write_Function wf, LV2UI_Controller c);
+
+    void show_impl() { printf("show\n"); }
+    void hide_impl() { printf("hide\n"); }
+    void run_impl()  { printf("run\n"); }
+
+    virtual ~ext_plugin_gui() {}
+        
+    static void show_(lv2_external_ui *h) { (static_cast<ext_plugin_gui *>(h))->show_impl(); }
+    static void hide_(lv2_external_ui *h) { (static_cast<ext_plugin_gui *>(h))->hide_impl(); }
+    static void run_(lv2_external_ui *h) { (static_cast<ext_plugin_gui *>(h))->run_impl(); }
+    
+};
+
+ext_plugin_gui::ext_plugin_gui(LV2UI_Write_Function wf, LV2UI_Controller c)
+{
+    write_function = wf;
+    controller = c;
+    
+    show = show_;
+    hide = hide_;
+    run = run_;
+}
+
+LV2UI_Handle extgui_instantiate(const struct _LV2UI_Descriptor* descriptor,
+                          const char*                     plugin_uri,
+                          const char*                     bundle_path,
+                          LV2UI_Write_Function            write_function,
+                          LV2UI_Controller                controller,
+                          LV2UI_Widget*                   widget,
+                          const LV2_Feature* const*       features)
+{
+    ext_plugin_gui *ui = new ext_plugin_gui(write_function, controller);
+    *widget = (LV2UI_Widget)ui;
+    return (LV2UI_Handle)ui;
+}
+
+void extgui_cleanup(LV2UI_Handle handle)
+{
+    ext_plugin_gui *gui = (ext_plugin_gui *)handle;
+    delete gui;
+}
+
+void extgui_port_event(LV2UI_Handle handle, uint32_t port, uint32_t buffer_size, uint32_t format, const void *buffer)
+{
+}
+
+const void *extgui_extension(const char *uri)
+{
+    return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
 const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
 {
-    static LV2UI_Descriptor gui, sgui;
+    static LV2UI_Descriptor gui, sgui, extgui;
     gui.URI = "http://calf.sourceforge.net/plugins/gui/gtk2-gui";
     gui.instantiate = gui_instantiate;
     gui.cleanup = gui_cleanup;
@@ -418,11 +472,18 @@ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
     sgui.cleanup = sgui_cleanup;
     sgui.port_event = sgui_port_event;
     sgui.extension_data = sgui_extension;
+    extgui.URI = "http://calf.sourceforge.net/plugins/gui/ext-gui";
+    extgui.instantiate = extgui_instantiate;
+    extgui.cleanup = extgui_cleanup;
+    extgui.port_event = extgui_port_event;
+    extgui.extension_data = extgui_extension;
     switch(index) {
         case 0:
             return &gui;
         case 1:
             return &sgui;
+        case 2:
+            return &extgui;
         default:
             return NULL;
     }
diff --git a/src/main_win.cpp b/src/main_win.cpp
index e420c3c..96bf725 100644
--- a/src/main_win.cpp
+++ b/src/main_win.cpp
@@ -432,18 +432,15 @@ void main_window::new_plugin(const char *plugin)
 std::string main_window::make_plugin_list(GtkActionGroup *actions)
 {
     string s = plugin_pre_xml;
-    std::vector<plugin_metadata_iface *> plugins;
-    calf_plugins::get_all_plugins(plugins);
+    const plugin_registry::plugin_vector &plugins = plugin_registry::instance().get_all();
     for(unsigned int i = 0; i < plugins.size(); i++)
     {
-        plugin_metadata_iface *p = plugins[i];
+        const plugin_metadata_iface *p = plugins[i];
         string action_name = "Add" + string(p->get_id())+"Action";
         s += string("<menuitem action=\"") + action_name + "\" />";
         GtkActionEntry ae = { action_name.c_str(), NULL, p->get_label(), NULL, NULL, (GCallback)add_plugin_action };
         gtk_action_group_add_actions_full(actions, &ae, 1, (gpointer)new add_plugin_params(this, p->get_id()), action_destroy_notify);
-        delete p;
     }
-    plugins.clear();
     return s + plugin_post_xml;
 }
 
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index e239850..54b501b 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -131,8 +131,7 @@ void make_rdf()
     
     rdf += "<rdf:RDF xmlns:rdf=\"&rdf;\" xmlns:rdfs=\"&rdfs;\" xmlns:dc=\"&dc;\" xmlns:ladspa=\"&ladspa;\">\n";
 
-    vector<calf_plugins::plugin_metadata_iface *> plugins;
-    calf_plugins::get_all_plugins(plugins);
+    const plugin_registry::plugin_vector &plugins = plugin_registry::instance().get_all();
     set<int> used_ids;
     for (unsigned int i = 0; i < plugins.size(); i++)
     {
@@ -151,7 +150,6 @@ void make_rdf()
         }
         delete p;
     }    
-    plugins.clear();
     rdf += "</rdf:RDF>\n";
     
     printf("%s\n", rdf.c_str());
@@ -491,8 +489,7 @@ void make_ttl(string path_prefix)
         "\n"
     ;
     
-    vector<plugin_metadata_iface *> plugins;
-    calf_plugins::get_all_plugins(plugins);
+    const plugin_registry::plugin_vector &plugins = plugin_registry::instance().get_all();
     
     map<string, string> classes;
     
@@ -750,8 +747,7 @@ void make_gui(string path_prefix)
         fprintf(stderr, "Path parameter is required for GUI mode\n");
         exit(1);
     }
-    vector<plugin_metadata_iface *> plugins;
-    calf_plugins::get_all_plugins(plugins);
+    const plugin_registry::plugin_vector &plugins = plugin_registry::instance().get_all();
     path_prefix += "/gui-";
     for (unsigned int i = 0; i < plugins.size(); i++)
     {
diff --git a/src/modmatrix.cpp b/src/modmatrix.cpp
index cba6ced..c3bb4f7 100644
--- a/src/modmatrix.cpp
+++ b/src/modmatrix.cpp
@@ -59,17 +59,17 @@ mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char
         matrix[i].reset();
 }
 
-const table_column_info *mod_matrix::get_table_columns(int param)
+const table_column_info *mod_matrix::get_table_columns(int param) const
 {
     return table_columns;
 }
 
-uint32_t mod_matrix::get_table_rows(int param)
+uint32_t mod_matrix::get_table_rows(int param) const
 {
     return matrix_rows;
 }
 
-std::string mod_matrix::get_cell(int param, int row, int column)
+std::string mod_matrix::get_cell(int param, int row, int column) const
 {
     assert(row >= 0 && row < (int)matrix_rows);
     modulation_entry &slot = matrix[row];
@@ -90,7 +90,7 @@ std::string mod_matrix::get_cell(int param, int row, int column)
     }
 }
     
-void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error)
+void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error) const
 {
     assert(row >= 0 && row < (int)matrix_rows);
     modulation_entry &slot = matrix[row];
diff --git a/src/modules.cpp b/src/modules.cpp
index b9bc039..4008373 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -890,7 +890,7 @@ CALF_PORT_PROPS(wavetable) = {
 
 ////////////////////////////////////////////////////////////////////////////
 
-void calf_plugins::get_all_plugins(std::vector<plugin_metadata_iface *> &plugins)
+calf_plugins::plugin_registry::plugin_registry()
 {
     #define PER_MODULE_ITEM(name, isSynth, jackname) plugins.push_back(new name##_metadata);
     #define PER_SMALL_MODULE_ITEM(...)
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index d7afa93..450a78c 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -34,12 +34,12 @@ using namespace calf_plugins;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 { 
     return get_freq_gridline(subindex, pos, vertical, legend, context);
 }
 
-int frequency_response_line_graph::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int frequency_response_line_graph::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     subindex_graph = 0;
     subindex_dot = 0;
@@ -68,7 +68,7 @@ void flanger_audio_module::deactivate() {
     is_active = false;
 }
 
-bool flanger_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool flanger_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -80,7 +80,7 @@ bool flanger_audio_module::get_graph(int index, int subindex, float *data, int p
     return false;
 }
 
-float flanger_audio_module::freq_gain(int subindex, float freq, float srate)
+float flanger_audio_module::freq_gain(int subindex, float freq, float srate) const
 {
     return (subindex ? right : left).freq_gain(freq, srate);                
 }
@@ -109,7 +109,7 @@ void phaser_audio_module::deactivate()
     is_active = false;
 }
 
-bool phaser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool phaser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -121,12 +121,12 @@ bool phaser_audio_module::get_graph(int index, int subindex, float *data, int po
     return false;
 }
 
-float phaser_audio_module::freq_gain(int subindex, float freq, float srate)
+float phaser_audio_module::freq_gain(int subindex, float freq, float srate) const
 {
     return (subindex ? right : left).freq_gain(freq, srate);                
 }
 
-bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     return get_freq_gridline(subindex, pos, vertical, legend, context);
 }
@@ -151,7 +151,7 @@ void reverb_audio_module::set_sample_rate(uint32_t sr)
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -162,7 +162,7 @@ bool filter_audio_module::get_graph(int index, int subindex, float *data, int po
     return false;
 }
 
-int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     if (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f)
     {
@@ -186,7 +186,7 @@ int filter_audio_module::get_changed_offsets(int index, int generation, int &sub
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active || index != par_mode) {
         return false;
@@ -269,7 +269,7 @@ void multichorus_audio_module::set_sample_rate(uint32_t sr) {
     right.setup(sr);
 }
 
-bool multichorus_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool multichorus_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -285,7 +285,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
         return ::get_graph(*this, subindex, data, points);
     }
     if (index == par_rate && subindex < nvoices) {
-        sine_multi_lfo<float, 8> &lfo = left.lfo;
+        const sine_multi_lfo<float, 8> &lfo = left.lfo;
         for (int i = 0; i < points; i++) {
             float phase = i * 2 * M_PI / points;
             // original -65536 to 65535 value
@@ -298,7 +298,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
     return false;
 }
 
-bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     int voice = subindex >> 1;
     int nvoices = (int)*params[par_voices];
@@ -308,7 +308,7 @@ bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float
     float unit = (1 - *params[par_overlap]);
     float scw = 1 + unit * (nvoices - 1);
     set_channel_color(context, subindex);
-    sine_multi_lfo<float, 8> &lfo = (subindex & 1 ? right : left).lfo;
+    const sine_multi_lfo<float, 8> &lfo = (subindex & 1 ? right : left).lfo;
     if (index == par_rate)
     {
         x = (double)(lfo.phase + lfo.vphase * voice) / 4096.0;
@@ -325,7 +325,7 @@ bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float
     return true;
 }
 
-bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     if (index == par_rate && !subindex)
     {
@@ -338,7 +338,7 @@ bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos,
     return false;
 }
 
-float multichorus_audio_module::freq_gain(int subindex, float freq, float srate)
+float multichorus_audio_module::freq_gain(int subindex, float freq, float srate) const
 {
     if (subindex == 2)
         return *params[par_amount] * left.post.freq_gain(freq, srate);
@@ -678,7 +678,7 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num
     // whatever has to be returned x)
     return outputs_mask;
 }
-bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     // let's handle by the corresponding strip
     switch (index) {
@@ -698,7 +698,7 @@ bool multibandcompressor_audio_module::get_graph(int index, int subindex, float
     return false;
 }
 
-bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     // let's handle by the corresponding strip
     switch (index) {
@@ -718,8 +718,8 @@ bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x
     return false;
 }
 
-bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
-{
+bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
+{ 
     // let's handle by the corresponding strip
     switch (index) {
         case param_compression0:
@@ -738,7 +738,7 @@ bool multibandcompressor_audio_module::get_gridline(int index, int subindex, flo
     return false;
 }
 
-int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     // let's handle by the corresponding strip
     switch (index) {
@@ -885,28 +885,28 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples,
     // whatever has to be returned x)
     return outputs_mask;
 }
-bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
     return compressor.get_graph(subindex, data, points, context);
 }
 
-bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!is_active)
         return false;
     return compressor.get_dot(subindex, x, y, size, context);
 }
 
-bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     if (!is_active)
         return false;
     return compressor.get_gridline(subindex, pos, vertical, legend, context);
 }
 
-int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     if (!is_active)
         return false;
@@ -1203,7 +1203,7 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
     // whatever has to be returned x)
     return outputs_mask;
 }
-bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1216,7 +1216,7 @@ bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float
     return false;
 }
 
-bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1226,7 +1226,7 @@ bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x
     return false;
 }
 
-bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1238,7 +1238,7 @@ bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, flo
 //    return false;
 }
 
-int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     if (!is_active)
         return false;
@@ -1452,7 +1452,7 @@ uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uin
     // whatever has to be returned x)
     return outputs_mask;
 }
-bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1463,14 +1463,14 @@ bool deesser_audio_module::get_graph(int index, int subindex, float *data, int p
     return false;
 }
 
-bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     return get_freq_gridline(subindex, pos, vertical, legend, context);
     
 //    return false;
 }
 
-int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     if (!is_active) {
         return false;
@@ -1577,11 +1577,11 @@ void gain_reduction_audio_module::process(float &left, float &right, float det_l
     }
 }
 
-float gain_reduction_audio_module::output_level(float slope) {
+float gain_reduction_audio_module::output_level(float slope) const {
     return slope * output_gain(slope, false) * makeup;
 }
 
-float gain_reduction_audio_module::output_gain(float linSlope, bool rms) {
+float gain_reduction_audio_module::output_gain(float linSlope, bool rms) const {
     //this calculation is also thor's work
     if(linSlope > (rms ? adjKneeStart : linKneeStart)) {
         float slope = log(linSlope);
@@ -1638,7 +1638,7 @@ float gain_reduction_audio_module::get_comp_level() {
     return meter_comp;
 }
 
-bool gain_reduction_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context)
+bool gain_reduction_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1663,7 +1663,7 @@ bool gain_reduction_audio_module::get_graph(int subindex, float *data, int point
     return true;
 }
 
-bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context)
+bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -1682,7 +1682,7 @@ bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int
     return false;
 }
 
-bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     bool tmp;
     vertical = (subindex & 1) != 0;
@@ -1701,7 +1701,7 @@ bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &v
     return result;
 }
 
-int gain_reduction_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int gain_reduction_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     subindex_graph = 0;
     subindex_dot = 0;
@@ -1989,7 +1989,7 @@ uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offs
 #undef SET_IF_CONNECTED
 
 template<class BaseClass, bool has_lphp>
-bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -2001,7 +2001,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int
 }
 
 template<class BaseClass, bool has_lphp>
-bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
     if (!is_active) {
         return false;
@@ -2011,7 +2011,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, i
 }
 
 template<class BaseClass, bool has_lphp>
-int equalizerNband_audio_module<BaseClass, has_lphp>::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+int equalizerNband_audio_module<BaseClass, has_lphp>::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
 {
     if (!is_active) {
         return false;
@@ -2043,7 +2043,7 @@ int equalizerNband_audio_module<BaseClass, has_lphp>::get_changed_offsets(int in
     return false;
 }
 
-static inline float adjusted_lphp_gain(float **params, int param_active, int param_mode, biquad_d2<float> filter, float freq, float srate)
+static inline float adjusted_lphp_gain(const float *const *params, int param_active, int param_mode, const biquad_d2<float> &filter, float freq, float srate)
 {
     if(*params[param_active] > 0.f) {
         float gain = filter.freq_gain(freq, srate);
@@ -2060,7 +2060,7 @@ static inline float adjusted_lphp_gain(float **params, int param_active, int par
 }
 
 template<class BaseClass, bool use_hplp>
-float equalizerNband_audio_module<BaseClass, use_hplp>::freq_gain(int index, double freq, uint32_t sr)
+float equalizerNband_audio_module<BaseClass, use_hplp>::freq_gain(int index, double freq, uint32_t sr) const
 {
     float ret = 1.f;
     if (use_hplp)
@@ -2105,7 +2105,7 @@ float lfo_audio_module::get_value()
     return get_value_from_phase(phase, offset) * amount;
 }
 
-float lfo_audio_module::get_value_from_phase(float ph, float off)
+float lfo_audio_module::get_value_from_phase(float ph, float off) const
 {
     float val = 0.f;
     float phs = ph + off;
@@ -2172,7 +2172,7 @@ void lfo_audio_module::set_params(float f, int m, float o, uint32_t sr, float a)
     amount = a;
 }
 
-bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context)
+bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -2183,7 +2183,7 @@ bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context)
     return true;
 }
 
-bool lfo_audio_module::get_dot(float &x, float &y, int &size, cairo_iface *context)
+bool lfo_audio_module::get_dot(float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!is_active)
         return false;
@@ -2378,7 +2378,8 @@ uint32_t pulsator_audio_module::process(uint32_t offset, uint32_t numsamples, ui
     // whatever has to be returned x)
     return outputs_mask;
 }
-bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+
+bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     if (!is_active) {
         return false;
@@ -2394,7 +2395,8 @@ bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int
     }
     return false;
 }
-bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+
+bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const
 {
     if (!is_active) {
         return false;
@@ -2411,7 +2413,8 @@ bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y,
     }
     return false;
 }
-bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+
+bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
 {
    if (index == param_freq && !subindex)
     {
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 5fdb993..fef489c 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -205,7 +205,7 @@ void monosynth_audio_module::precalculate_waves(progress_report_iface *reporter)
     
 }
 
-bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
 {
     monosynth_audio_module::precalculate_waves(NULL);
     // printf("get_graph %d %p %d wave1=%d wave2=%d\n", index, data, points, wave1, wave2);
@@ -240,7 +240,7 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int
             typedef complex<double> cfloat;
             double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
             
-            dsp::biquad_d1_lerp<float> &f = subindex ? filter2 : filter;
+            const dsp::biquad_d1_lerp<float> &f = subindex ? filter2 : filter;
             float level = f.freq_gain(freq, srate);
             if (!is_stereo_filter())
                 level *= filter2.freq_gain(freq, srate);

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list