[SCM] calf/master: Reimplement modulation matrix (and tables in general) using configure variables. Slow and most likely incomplete, but a good start.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:40:29 UTC 2013


The following commit has been merged in the master branch:
commit 4fddfdf66dc7ae05a5f6141ec4918037287c615b
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Thu Dec 2 21:06:45 2010 +0000

    Reimplement modulation matrix (and tables in general) using configure variables. Slow and most likely incomplete, but a good start.

diff --git a/src/calf/giface.h b/src/calf/giface.h
index 3ee1309..f930a0a 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -222,27 +222,15 @@ struct table_column_info
 };
 
 /// 'has string parameters containing tabular data' interface
-struct table_edit_iface
+struct table_metadata_iface
 {
     /// retrieve the table layout for specific parameter
     virtual const table_column_info *get_table_columns() const = 0;
 
-    /// return the current number of rows
+    /// return the fixed number of rows, or 0 if the number of rows is variable
     virtual uint32_t get_table_rows() const = 0;
     
-    /// retrieve data item from the plugin
-    virtual std::string get_cell(int row, int column) const;
-
-    /// set data item to the plugin
-    virtual void set_cell(int row, int column, const std::string &src, std::string &error) { error.clear(); }
-    
-    /// return a line graph interface for a specific parameter/column (unused for now)
-    virtual const line_graph_iface *get_graph_iface(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 column) const { return NULL; }
-    
-    virtual ~table_edit_iface() {}
+    virtual ~table_metadata_iface() {}
 };
 
 /// 'may receive configure variables' interface
@@ -331,6 +319,8 @@ struct plugin_metadata_iface
     virtual bool requires_configure() const = 0;
     /// obtain array of names of configure variables (or NULL is none needed)
     virtual const char *const *get_configure_vars() const { return NULL; }
+    /// @return table_metadata_iface if any
+    virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { return NULL; }
 
     /// Do-nothing destructor to silence compiler warning
     virtual ~plugin_metadata_iface() {}
@@ -365,8 +355,6 @@ struct plugin_ctl_iface
     virtual const plugin_metadata_iface *get_metadata_iface() const = 0;
     /// @return line_graph_iface if any
     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(const char *key) = 0;
     /// Do-nothing destructor to silence compiler warning
     virtual ~plugin_ctl_iface() {}
 };
@@ -447,8 +435,6 @@ struct audio_module_iface
     virtual uint32_t message_run(const void *valid_ports, void *output_ports) = 0;
     /// @return line_graph_iface if any
     virtual const line_graph_iface *get_line_graph_iface() const = 0;
-    /// @return table_edit_iface if any for given parameter
-    virtual table_edit_iface *get_table_edit_iface(const char *key) = 0;
     virtual ~audio_module_iface() {}
 };
 
@@ -548,8 +534,6 @@ public:
     }
     /// @return line_graph_iface if any
     virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast<const line_graph_iface *>(this); }
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { const char *key_us = get_table_edit_iface_key(); return (key_us && !strcmp(key, key_us)) ? dynamic_cast<table_edit_iface *>(this) : NULL; }
-    virtual const char *get_table_edit_iface_key() const { return NULL; }
 };
 
 #if USE_EXEC_GUI || USE_DSSI
@@ -678,8 +662,46 @@ struct preset_access_iface
     virtual ~preset_access_iface() {} 
 };
 
+/// Implementation of table_metadata_iface providing metadata for mod matrices
+class mod_matrix_metadata: public table_metadata_iface
+{
+public:
+    /// Mapping modes
+    enum mapping_mode {
+        map_positive, ///< 0..100%
+        map_bipolar, ///< -100%..100%
+        map_negative, ///< -100%..0%
+        map_squared, ///< x^2
+        map_squared_bipolar, ///< x^2 scaled to -100%..100%
+        map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
+        map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
+        map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
+        map_type_count
+    };
+    const char **mod_src_names, **mod_dest_names;
+
+    mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names);
+    virtual const table_column_info *get_table_columns() const;
+    virtual uint32_t get_table_rows() const;
+
+protected:
+    /// Column descriptions for table widget
+    table_column_info table_columns[6];
+    
+    unsigned int matrix_rows;
+};
+
+/// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column)
+/// @arg key key to parse
+/// @arg prefix table prefix (e.g. "modmatrix:")
+/// @arg is_rows[out] set to true if key == prefix + "rows"
+/// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
+/// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
+/// @retval true if this is one of the recognized string forms
+extern bool parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column);
+
 #if USE_EXEC_GUI
-class table_via_configure: public table_edit_iface
+class table_via_configure
 {
 protected:
     typedef std::pair<int, int> coord;
@@ -689,13 +711,6 @@ protected:
 public:
     table_via_configure();
     void configure(const char *key, const char *value);
-    
-    virtual const table_column_info *get_table_columns() const;
-    virtual uint32_t get_table_rows() const;
-    virtual std::string get_cell(int row, int column) const;
-    virtual void set_cell(int row, int column, const std::string &src, std::string &error);
-    virtual const line_graph_iface *get_graph_iface(int column) const;
-    virtual const char *get_cell_editor(int column) const;
     virtual ~table_via_configure();
 };
 #endif
diff --git a/src/calf/gui_controls.h b/src/calf/gui_controls.h
index f087ea2..15cca8e 100644
--- a/src/calf/gui_controls.h
+++ b/src/calf/gui_controls.h
@@ -275,7 +275,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_metadata_iface *tmif;
     int cols;
     std::vector<GtkTreeIter> positions;
     
@@ -283,9 +283,10 @@ struct listview_param_control: public param_control, public send_configure_iface
     virtual void get() {}
     virtual void set() {}
     virtual void send_configure(const char *key, const char *value);
-    void update_store();
+protected:
+    void set_rows(unsigned int needed_rows);
     static void on_edited(GtkCellRenderer *renderer, gchar *path, gchar *new_text, listview_param_control *pThis);
-    static void on_editing_canceled(GtkCellRenderer *renderer, listview_param_control *pThis);
+    static void on_editing_canceled(GtkCellRenderer *renderer, listview_param_control *pThis);    
 };
 
 };
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index 83913e3..5057fee 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -128,7 +128,6 @@ public:
     virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); }
     virtual const plugin_metadata_iface *get_metadata_iface() const { return module->get_metadata_iface(); }
     virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); }
 };
 
 extern jack_host *create_jack_host(const char *name, const std::string &instance_name, calf_plugins::progress_report_iface *priface);
diff --git a/src/calf/ladspa_wrap.h b/src/calf/ladspa_wrap.h
index 7908ab1..d94ebce 100644
--- a/src/calf/ladspa_wrap.h
+++ b/src/calf/ladspa_wrap.h
@@ -48,7 +48,6 @@ struct ladspa_instance: public plugin_ctl_iface
     
     ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate);
     virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); }
     virtual float get_param_value(int param_no);
     virtual void set_param_value(int param_no, float value);
     virtual bool activate_preset(int bank, int program);
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index ec43e9a..7729330 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -164,7 +164,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
     }
     virtual const plugin_metadata_iface *get_metadata_iface() const { return metadata; }
     virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); }
     virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); }
 };
 
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index f170bc2..ecf84e3 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -118,6 +118,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
         param_count };
     enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64, step_shift = 6 };
+    enum { mod_matrix_slots = 10 };
     enum {
         modsrc_none,
         modsrc_velocity,
@@ -143,6 +144,12 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
         moddest_count,
     };
     PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
+    
+    mod_matrix_metadata mm_metadata;
+    
+    monosynth_metadata();
+    /// Lookup of table edit interface
+    virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
 };
 
 /// Thor's compressor - metadata
@@ -482,8 +489,14 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
         par_pwhlrange, 
         param_count };
     enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
+    enum { mod_matrix_slots = 10 };
     enum { step_size = 64 };
     PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable")
+    mod_matrix_metadata mm_metadata;
+    
+    wavetable_metadata();
+    /// Lookup of table edit interface
+    virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
 };
     
 };
diff --git a/src/calf/modmatrix.h b/src/calf/modmatrix.h
index 17ebfd6..d66c323 100644
--- a/src/calf/modmatrix.h
+++ b/src/calf/modmatrix.h
@@ -25,26 +25,13 @@
 
 namespace dsp {
 
-/// Mapping modes
-enum mapping_mode {
-    map_positive, ///< 0..100%
-    map_bipolar, ///< -100%..100%
-    map_negative, ///< -100%..0%
-    map_squared, ///< x^2
-    map_squared_bipolar, ///< x^2 scaled to -100%..100%
-    map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
-    map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
-    map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
-    map_type_count
-};
-
 /// Single entry in modulation matrix
 struct modulation_entry
 {
     /// Mapped source
     int src1;
     /// Source mapping mode
-    mapping_mode mapping;
+    calf_plugins::mod_matrix_metadata::mapping_mode mapping;
     /// Unmapped modulating source
     int src2;
     /// Modulation amount
@@ -60,7 +47,7 @@ struct modulation_entry
     void reset() {
         src1 = 0;
         src2 = 0;
-        mapping = map_positive;
+        mapping = calf_plugins::mod_matrix_metadata::map_positive;
         amount = 0.f;
         dest = 0;
     }
@@ -70,24 +57,17 @@ struct modulation_entry
 
 namespace calf_plugins {
 
-class mod_matrix: public table_edit_iface
+class mod_matrix_impl
 {
 protected:
-    /// Polynomials for different scaling modes (1, x, x^2)
-    static const float scaling_coeffs[dsp::map_type_count][3];
-    /// Column descriptions for table widget
-    table_column_info table_columns[6];
-    
     dsp::modulation_entry *matrix;
+    mod_matrix_metadata *metadata;
     unsigned int matrix_rows;
-    const char **mod_src_names, **mod_dest_names;
+    /// Polynomials for different scaling modes (1, x, x^2)
+    static const float scaling_coeffs[calf_plugins::mod_matrix_metadata::map_type_count][3];
 
-    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() const;
-    virtual uint32_t get_table_rows() const;
-    virtual std::string get_cell(int row, int column) const;
-    virtual void set_cell(int row, int column, const std::string &src, std::string &error);
+    mod_matrix_impl(dsp::modulation_entry *_matrix, calf_plugins::mod_matrix_metadata *_metadata);
 
     /// Process modulation matrix, calculate outputs from inputs
     inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc)
@@ -105,8 +85,14 @@ public:
             }
         }
     }
-};
+    void send_configures(send_configure_iface *);
+    char *configure(const char *key, const char *value);
     
+private:
+    std::string get_cell(int row, int column) const;
+    void set_cell(int row, int column, const std::string &src, std::string &error);
+};
+
 };
 
 #endif
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index f847a2c..2e8dc8e 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -37,10 +37,9 @@ namespace calf_plugins {
     
 /// 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 line_graph_iface, public mod_matrix
+class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface, public mod_matrix_impl
 {
 public:
-    enum { mod_matrix_slots = 10 };
     uint32_t srate, crate;
     static dsp::waveform_family<MONOSYNTH_WAVE_BITS> *waves;
     dsp::waveform_oscillator<MONOSYNTH_WAVE_BITS> osc1, osc2;
@@ -178,8 +177,9 @@ public:
     void apply_fadeout();
     /// Main processing function
     uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    /// Lookup of table edit interface
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { if (!strcmp(key, "mod_matrix")) return static_cast<mod_matrix *>(this); else return NULL; }
+    /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands)
+    virtual void send_configures(send_configure_iface *sci) { return mod_matrix_impl::send_configures(sci); }
+    virtual char *configure(const char *key, const char *value) { return mod_matrix_impl::configure(key, value); }
 };
 
 };
diff --git a/src/calf/wavetable.h b/src/calf/wavetable.h
index d861b44..5c4492c 100644
--- a/src/calf/wavetable.h
+++ b/src/calf/wavetable.h
@@ -88,7 +88,7 @@ public:
     }
 };    
 
-class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth, public mod_matrix
+class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth, public mod_matrix_impl
 {
 public:
     using dsp::basic_synth::note_on;
@@ -101,7 +101,6 @@ protected:
     bool panic_flag;
 
 public:
-    enum { mod_matrix_slots = 10 };
     int16_t tables[wt_count][129][256]; // one dummy level for interpolation
     /// Rows of the modulation matrix
     dsp::modulation_entry mod_matrix_data[mod_matrix_slots];
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 81c6736..5e59ae6 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -205,7 +205,6 @@ struct plugin_proxy: public plugin_ctl_iface, public line_graph_iface
         }
     }
     virtual const line_graph_iface *get_line_graph_iface() const { return this; }
-    virtual table_edit_iface *get_table_edit_iface(const char *key) { return NULL; } // not supported in external UIs yet
     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;
diff --git a/src/giface.cpp b/src/giface.cpp
index baa962e..9e31668 100644
--- a/src/giface.cpp
+++ b/src/giface.cpp
@@ -317,11 +317,67 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char
     }
     return NULL;
 }
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+bool calf_plugins::parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column)
+{
+    is_rows = false;
+    row = -1;
+    column = -1;
+    if (0 != strncmp(key, prefix, strlen(prefix)))
+        return false;
+    
+    key += strlen(prefix);
+    
+    if (!strcmp(key, "rows"))
+    {
+        is_rows = true;
+        return true;
+    }
+    
+    const char *comma = strchr(key, ',');
+    if (comma)
+    {
+        row = atoi(string(key, comma - key).c_str());
+        column = atoi(comma + 1);
+        return true;
+    }
+    
+    printf("Unknown key %s under prefix %s", key, prefix);
+    
+    return false;
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////
 
-std::string table_edit_iface::get_cell(int row, int column) const
+const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
+
+mod_matrix_metadata::mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names)
+: mod_src_names(_src_names)
+, mod_dest_names(_dest_names)
+, matrix_rows(_rows)
+{
+    table_column_info tci[6] = {
+        { "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
+        { "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
+        { "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
+        { "Amount", TCT_FLOAT, 0, 1, 1, NULL},
+        { "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names  },
+        { NULL }
+    };
+    assert(sizeof(table_columns) == sizeof(tci));
+    memcpy(table_columns, tci, sizeof(table_columns));
+}
+
+const table_column_info *mod_matrix_metadata::get_table_columns() const
+{
+    return table_columns;
+}
+
+uint32_t mod_matrix_metadata::get_table_rows() const
 {
-    return calf_utils::i2s(row)+":"+calf_utils::i2s(column);
+    return matrix_rows;
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////
@@ -433,45 +489,6 @@ table_via_configure::table_via_configure()
     rows = 0;
 }
 
-const table_column_info *table_via_configure::get_table_columns() const
-{
-    return &columns[0];
-}
-
-uint32_t table_via_configure::get_table_rows() const
-{
-    return rows;
-}
-
-string table_via_configure::get_cell(int row, int column) const
-{
-    if (row >= rows)
-        return string();
-    coord c = make_pair(row, column);
-    std::map<coord, std::string>::const_iterator i = values.find(c);
-    if (i == values.end())
-        return std::string();
-    else
-        return i->second;
-}
-
-void table_via_configure::set_cell(int row, int column, const std::string &src, std::string &error)
-{
-    coord c = make_pair(row, column);
-    values[c] = src;
-    error = "";
-}
-
-const line_graph_iface *table_via_configure::get_graph_iface(int column) const
-{
-    return NULL;
-}
-
-const char *table_via_configure::get_cell_editor(int column) const
-{
-    return NULL;
-}
-
 table_via_configure::~table_via_configure()
 {
 }
diff --git a/src/gui_controls.cpp b/src/gui_controls.cpp
index 48bac24..17e123b 100644
--- a/src/gui_controls.cpp
+++ b/src/gui_controls.cpp
@@ -32,6 +32,7 @@
 #include <gdk/gdk.h>
 
 using namespace calf_plugins;
+using namespace calf_utils;
 using namespace std;
 
 /******************************** control/container base class **********************/
@@ -939,10 +940,14 @@ GtkWidget *listview_param_control::create(plugin_gui *_gui, int _param_no)
     param_no = _param_no;
     
     string key = attribs["key"];
-    teif = gui->plugin->get_table_edit_iface(key.c_str());
-    if (!teif)
-        g_error("Missing table_edit_iface for variable '%s'", key.c_str());
-    const table_column_info *tci = teif->get_table_columns();
+    tmif = gui->plugin->get_metadata_iface()->get_table_metadata_iface(key.c_str());
+    if (!tmif)
+    {
+        g_error("Missing table_metadata_iface for variable '%s'", key.c_str());
+        return NULL;
+    }
+    positions.clear();
+    const table_column_info *tci = tmif->get_table_columns();
     assert(tci);
     cols = 0;
     while (tci[cols].name != NULL)
@@ -952,11 +957,11 @@ GtkWidget *listview_param_control::create(plugin_gui *_gui, int _param_no)
     for (int i = 0; i < cols; i++)
         p[i] = G_TYPE_STRING;
     lstore = gtk_list_store_newv(cols, p);
-    update_store();
+    if (tmif->get_table_rows() != 0)
+        set_rows(tmif->get_table_rows());
     widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(lstore));
     delete []p;
     tree = GTK_TREE_VIEW (widget);
-    assert(teif);
     g_object_set (G_OBJECT (tree), "enable-search", FALSE, "rules-hint", TRUE, "enable-grid-lines", TRUE, NULL);
     
     for (int i = 0; i < cols; i++)
@@ -986,17 +991,15 @@ GtkWidget *listview_param_control::create(plugin_gui *_gui, int _param_no)
     return widget;
 }
 
-void listview_param_control::update_store()
+void listview_param_control::set_rows(unsigned int needed_rows)
 {
-    gtk_list_store_clear(lstore);
-    uint32_t rows = teif->get_table_rows();
-    for (uint32_t i = 0; i < rows; i++)
+    while(positions.size() < needed_rows)
     {
         GtkTreeIter iter;
-        gtk_list_store_insert(lstore, &iter, i);
+        gtk_list_store_insert(lstore, &iter, positions.size());
         for (int j = 0; j < cols; j++)
         {
-            gtk_list_store_set(lstore, &iter, j, teif->get_cell(i, j).c_str(), -1);
+            gtk_list_store_set(lstore, &iter, j, "", -1);
         }
         positions.push_back(iter);
     }
@@ -1004,27 +1007,58 @@ void listview_param_control::update_store()
 
 void listview_param_control::send_configure(const char *key, const char *value)
 {
-    if (attribs["key"] == key)
+    string orig_key = attribs["key"] + ":";
+    bool is_rows = false;
+    int row = -1, col = -1;
+    if (parse_table_key(key, orig_key.c_str(), is_rows, row, col))
     {
-        update_store();
+        string suffix = string(key + orig_key.length());
+        if (is_rows && tmif->get_table_rows() == 0)
+        {
+            int rows = atoi(value);
+            set_rows(rows);
+            return;
+        }
+        else
+        if (row != -1 && col != -1)
+        {
+            int max_rows = tmif->get_table_rows();
+            if (col < 0 || col >= cols)
+            {
+                g_warning("Invalid column %d in key %s", col, key);
+                return;
+            }
+            if (max_rows && (row < 0 || row >= max_rows))
+            {
+                g_warning("Invalid row %d in key %s, this is a fixed table with row count = %d", row, key, max_rows);
+                return;
+            }
+            
+            if (row >= (int)positions.size())
+                set_rows(row + 1);
+            
+            gtk_list_store_set(lstore, &positions[row], col, value, -1);
+            return;
+        }
     }
 }
 
 void listview_param_control::on_edited(GtkCellRenderer *renderer, gchar *path, gchar *new_text, listview_param_control *pThis)
 {
-    const table_column_info *tci = pThis->teif->get_table_columns();
+    const table_column_info *tci = pThis->tmif->get_table_columns();
     int column = ((table_column_info *)g_object_get_data(G_OBJECT(renderer), "column")) - tci;
+    string key = pThis->attribs["key"] + ":" + i2s(atoi(path)) + "," + i2s(column);
     string error;
-    pThis->teif->set_cell(atoi(path), column, new_text, error);
+    const char *error_or_null = pThis->gui->plugin->configure(key.c_str(), new_text);
+    if (error_or_null)
+        error = error_or_null;
+    
     if (error.empty()) {
-        pThis->update_store();
+        pThis->send_configure(key.c_str(), new_text);
         gtk_widget_grab_focus(pThis->widget);
-        if (atoi(path) < (int)pThis->teif->get_table_rows())
-        {
-            GtkTreePath *gpath = gtk_tree_path_new_from_string (path);
-            gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (pThis->widget), gpath, NULL, NULL, FALSE);
-            gtk_tree_path_free (gpath);
-        }
+        GtkTreePath *gpath = gtk_tree_path_new_from_string (path);
+        gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (pThis->widget), gpath, NULL, NULL, FALSE);
+        gtk_tree_path_free (gpath);
     }
     else
     {
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index f75fa68..d35b337 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -92,9 +92,6 @@ struct plugin_proxy_base
     /// Obtain line graph interface if available
     const line_graph_iface *get_line_graph_iface() const;
     
-    /// Obtain line graph interface if available
-    const table_edit_iface *get_table_edit_iface(const char *key) const;
-    
     /// Map an URI to an integer value using a given URI map
     uint32_t map_uri(const char *mapURI, const char *keyURI);
 
@@ -177,13 +174,6 @@ const line_graph_iface *plugin_proxy_base::get_line_graph_iface() const
     return NULL;
 }
 
-const table_edit_iface *plugin_proxy_base::get_table_edit_iface(const char *key) const
-{
-    if (instance)
-        return instance->get_table_edit_iface(key);
-    return NULL;
-}
-
 char *plugin_proxy_base::configure(const char *key, const char *value)
 {
     if (instance)
@@ -249,8 +239,6 @@ struct lv2_plugin_proxy: public plugin_ctl_iface, public plugin_proxy_base, publ
     virtual const plugin_metadata_iface *get_metadata_iface() const { return plugin_metadata; }
     /// Override for a method in plugin_ctl_iface - trivial delegation to base class
     virtual const line_graph_iface *get_line_graph_iface() const { return plugin_proxy_base::get_line_graph_iface(); }
-    /// Override for a method in plugin_ctl_iface - trivial delegation to base class
-    virtual const table_edit_iface *get_table_edit_iface(const char *key) const { return plugin_proxy_base::get_table_edit_iface(key); }
 };
 
 static gboolean plugin_on_idle(void *data)
diff --git a/src/metadata.cpp b/src/metadata.cpp
index c14206a..2a76fc5 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -777,6 +777,37 @@ CALF_PORT_PROPS(monosynth) = {
     {}
 };
 
+static const char *monosynth_mod_src_names[] = {
+    "None", 
+    "Velocity",
+    "Pressure",
+    "ModWheel",
+    "Envelope 1",
+    "Envelope 2",
+    "LFO 1",
+    "LFO 2",
+    NULL
+};
+
+static const char *monosynth_mod_dest_names[] = {
+    "None",
+    "Attenuation",
+    "Osc Mix Ratio (%)",
+    "Cutoff [ct]",
+    "Resonance",
+    "O1: Detune [ct]",
+    "O2: Detune [ct]",
+    "O1: PW (%)",
+    "O2: PW (%)",
+    "O1: Stretch",
+    NULL
+};
+
+monosynth_metadata::monosynth_metadata()
+: mm_metadata(mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
+{
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" };
@@ -1037,7 +1068,29 @@ const char *wavetable_names[] = {
     "Multi 2",
 };
 
-const char *wavetable_init_soundfont = "";
+static const char *wavetable_mod_src_names[] = {
+    "None", 
+    "Velocity",
+    "Pressure",
+    "ModWheel",
+    "Env 1",
+    "Env 2",
+    "Env 3",
+    NULL
+};
+
+static const char *wavetable_mod_dest_names[] = {
+    "None",
+    "Attenuation",
+    "Osc Mix Ratio (%)",
+    "Cutoff [ct]",
+    "Resonance",
+    "O1: Shift (%)",
+    "O2: Shift (%)",
+    "O1: Detune [ct]",
+    "O2: Detune [ct]",
+    NULL
+};
 
 CALF_PORT_NAMES(wavetable) = {
     "Out L", "Out R", 
@@ -1083,6 +1136,11 @@ CALF_PORT_PROPS(wavetable) = {
     {}
 };
 
+wavetable_metadata::wavetable_metadata()
+: mm_metadata(mod_matrix_slots, wavetable_mod_src_names, wavetable_mod_dest_names)
+{
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 calf_plugins::plugin_registry::plugin_registry()
diff --git a/src/modmatrix.cpp b/src/modmatrix.cpp
index 64ef330..670051b 100644
--- a/src/modmatrix.cpp
+++ b/src/modmatrix.cpp
@@ -26,10 +26,18 @@
 using namespace std;
 using namespace dsp;
 using namespace calf_plugins;
+using namespace calf_utils;
 
-const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
+mod_matrix_impl::mod_matrix_impl(dsp::modulation_entry *_matrix, mod_matrix_metadata *_metadata)
+: matrix(_matrix)
+, metadata(_metadata)
+{
+    matrix_rows = metadata->get_table_rows();
+    for (unsigned int i = 0; i < matrix_rows; i++)
+        matrix[i].reset();
+}
 
-const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
+const float mod_matrix_impl::scaling_coeffs[mod_matrix_metadata::map_type_count][3] = {
     { 0, 1, 0 },
     { -1, 2, 0 },
     { -1, 1, 0 },
@@ -40,66 +48,33 @@ const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
     { 0, 4, -4 },
 };
 
-mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names)
-: matrix(_matrix)
-, matrix_rows(_rows)
-, mod_src_names(_src_names)
-, mod_dest_names(_dest_names)
-{
-    table_column_info tci[6] = {
-        { "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
-        { "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
-        { "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
-        { "Amount", TCT_FLOAT, 0, 1, 1, NULL},
-        { "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names  },
-        { NULL }
-    };
-    assert(sizeof(table_columns) == sizeof(tci));
-    memcpy(table_columns, tci, sizeof(table_columns));
-    for (unsigned int i = 0; i < matrix_rows; i++)
-        matrix[i].reset();
-}
-
-const table_column_info *mod_matrix::get_table_columns() const
-{
-    return table_columns;
-}
-
-uint32_t mod_matrix::get_table_rows() const
-{
-    return matrix_rows;
-}
-
-std::string mod_matrix::get_cell(int row, int column) const
+std::string mod_matrix_impl::get_cell(int row, int column) const
 {
     assert(row >= 0 && row < (int)matrix_rows);
     modulation_entry &slot = matrix[row];
+    const char **arr = metadata->get_table_columns()[column].values;
     switch(column) {
         case 0: // source 1
-            return mod_src_names[slot.src1];
+            return arr[slot.src1];
         case 1: // mapping mode
-            return mod_mapping_names[slot.mapping];
+            return arr[slot.mapping];
         case 2: // source 2
-            return mod_src_names[slot.src2];
+            return arr[slot.src2];
         case 3: // amount
             return calf_utils::f2s(slot.amount);
         case 4: // destination
-            return mod_dest_names[slot.dest];
+            return arr[slot.dest];
         default: 
             assert(0);
             return "";
     }
 }
     
-void mod_matrix::set_cell(int row, int column, const std::string &src, std::string &error)
+void mod_matrix_impl::set_cell(int row, int column, const std::string &src, std::string &error)
 {
     assert(row >= 0 && row < (int)matrix_rows);
     modulation_entry &slot = matrix[row];
-    const char **arr = mod_src_names;
-    if (column == 1) 
-        arr = mod_mapping_names;
-    if (column == 4) 
-        arr = mod_dest_names;
+    const char **arr = metadata->get_table_columns()[column].values;
     switch(column) {
         case 0:
         case 1:
@@ -113,7 +88,7 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri
                     if (column == 0)
                         slot.src1 = i;
                     else if (column == 1)
-                        slot.mapping = (mapping_mode)i;
+                        slot.mapping = (mod_matrix_metadata::mapping_mode)i;
                     else if (column == 2)
                         slot.src2 = i;
                     else if (column == 4)
@@ -135,3 +110,33 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri
     }
 }
 
+void mod_matrix_impl::send_configures(send_configure_iface *sci)
+{
+    for (int i = 0; i < (int)matrix_rows; i++)
+    {
+        for (int j = 0; j < 5; j++)
+        {
+            string key = "mod_matrix:" + i2s(i) + "," + i2s(j);
+            sci->send_configure(key.c_str(), get_cell(i, j).c_str());
+        }
+    }
+}
+
+char *mod_matrix_impl::configure(const char *key, const char *value)
+{
+    bool is_rows;
+    int row, column;
+    if (!parse_table_key(key, "mod_matrix:", is_rows, row, column))
+        return NULL;
+    if (is_rows)
+        return strdup("Unexpected key");
+    
+    if (row != -1 && column != -1)
+    {
+        string error;
+        set_cell(row, column, value, error);
+        if (!error.empty())
+            return strdup(error.c_str());
+    }
+    return NULL;
+}
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 2f2b731..a277ae1 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -27,34 +27,8 @@ using namespace std;
 
 float silence[4097];
 
-static const char *monosynth_mod_src_names[] = {
-    "None", 
-    "Velocity",
-    "Pressure",
-    "ModWheel",
-    "Envelope 1",
-    "Envelope 2",
-    "LFO 1",
-    "LFO 2",
-    NULL
-};
-
-static const char *monosynth_mod_dest_names[] = {
-    "None",
-    "Attenuation",
-    "Osc Mix Ratio (%)",
-    "Cutoff [ct]",
-    "Resonance",
-    "O1: Detune [ct]",
-    "O2: Detune [ct]",
-    "O1: PW (%)",
-    "O2: PW (%)",
-    "O1: Stretch",
-    NULL
-};
-
 monosynth_audio_module::monosynth_audio_module()
-: mod_matrix(mod_matrix_data, mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
+: mod_matrix_impl(mod_matrix_data, &mm_metadata)
 , inertia_cutoff(1)
 , inertia_pitchbend(1)
 , inertia_pressure(64)
diff --git a/src/wavetable.cpp b/src/wavetable.cpp
index 4d41f9b..e5ef259 100644
--- a/src/wavetable.cpp
+++ b/src/wavetable.cpp
@@ -30,30 +30,6 @@
 using namespace dsp;
 using namespace calf_plugins;
 
-static const char *mod_src_names[] = {
-    "None", 
-    "Velocity",
-    "Pressure",
-    "ModWheel",
-    "Env 1",
-    "Env 2",
-    "Env 3",
-    NULL
-};
-
-static const char *mod_dest_names[] = {
-    "None",
-    "Attenuation",
-    "Osc Mix Ratio (%)",
-    "Cutoff [ct]",
-    "Resonance",
-    "O1: Shift (%)",
-    "O2: Shift (%)",
-    "O1: Detune [ct]",
-    "O2: Detune [ct]",
-    NULL
-};
-
 wavetable_voice::wavetable_voice()
 {
     sample_rate = -1;
@@ -187,7 +163,7 @@ static void interpolate_wt(int16_t table[129][256], int step)
 }
 
 wavetable_audio_module::wavetable_audio_module()
-: mod_matrix(mod_matrix_data, mod_matrix_slots, ::mod_src_names, ::mod_dest_names)
+: mod_matrix_impl(mod_matrix_data, &mm_metadata)
 , inertia_cutoff(1)
 , inertia_pitchbend(1)
 , inertia_pressure(64)

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list