[SCM] calf/master: Implement marshalling of waveform and filter response graphs.

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


The following commit has been merged in the master branch:
commit 93bd647104ee8298b1dfb64038f8df1544e0eae1
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Mon Apr 5 10:24:11 2010 +0100

    Implement marshalling of waveform and filter response graphs.
    
    This shares a fair bit of implementation with DSSI. The code has been
    refactored to reuse the same client object that LV2 GUI plugin is using
    for other messages (control, show etc.). Some unused data were removed.
    
    Note that the graphs will only update when instance access/data access
    extensions are implemented, because there is no other way to transfer
    the data from the plugin yet.

diff --git a/src/calf/giface.h b/src/calf/giface.h
index 9dc9e53..0796758 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -459,7 +459,7 @@ public:
 extern bool check_for_message_context_ports(parameter_properties *parameters, int count);
 extern bool check_for_string_ports(parameter_properties *parameters, int count);
 
-#if USE_DSSI
+#if USE_EXEC_GUI || USE_DSSI
 
 enum line_graph_item
 {
@@ -478,16 +478,19 @@ struct dssi_feedback_sender
 {
     /// OSC client object used to send updates
     osctl::osc_client *client;
-    /// Background thread handle
-    pthread_t bg_thread;
+    /// Is client shared with something else?
+    bool is_client_shared;
     /// Quit flag (used to terminate the thread)
     bool quit;
     /// Indices of graphs to send
     std::vector<int> indices;
     /// Source for the graph data (interface to marshal)
-    calf_plugins::line_graph_iface *graph;
+    const calf_plugins::line_graph_iface *graph;
     
-    dssi_feedback_sender(const char *URI, line_graph_iface *_graph, calf_plugins::parameter_properties *props, int num_params);
+    /// Create using a new client
+    dssi_feedback_sender(const char *URI, const line_graph_iface *_graph);
+    dssi_feedback_sender(osctl::osc_client *_client, const line_graph_iface *_graph);
+    void add_graphs(const calf_plugins::parameter_properties *props, int num_params);
     void update();
     ~dssi_feedback_sender();
 };
diff --git a/src/calf/ladspa_wrap.h b/src/calf/ladspa_wrap.h
index 2f98dcf..21800dc 100644
--- a/src/calf/ladspa_wrap.h
+++ b/src/calf/ladspa_wrap.h
@@ -132,7 +132,8 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
                     delete feedback_sender;
                     feedback_sender = NULL;
                 }
-                feedback_sender = new dssi_feedback_sender(value, lgi, get_param_props(0), get_param_count());
+                feedback_sender = new dssi_feedback_sender(value, lgi);
+                feedback_sender->add_graphs(get_param_props(0), get_param_count());
             }
             else
             {
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 555aa6a..d772f67 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -370,7 +370,9 @@ void dssi_osc_server::set_osc_update(bool enabled)
 {
     if (is_lv2)
     {
-        cli.send("/enable_updates");
+        osc_inline_typed_strstream data;
+        data << ((uint32_t)(enabled ? 1 : 0));
+        cli.send("/enable_updates", data);
     }
     else
     {
diff --git a/src/giface.cpp b/src/giface.cpp
index 0e9b573..529e3be 100644
--- a/src/giface.cpp
+++ b/src/giface.cpp
@@ -327,7 +327,7 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char
 }
 ///////////////////////////////////////////////////////////////////////////////////////
 
-#if USE_DSSI
+#if USE_EXEC_GUI
 struct osc_cairo_control: public cairo_iface
 {
     osctl::osc_inline_typed_strstream &os;
@@ -343,9 +343,8 @@ struct osc_cairo_control: public cairo_iface
     }
 };
 
-static void send_graph_via_osc(osctl::osc_client &client, const std::string &address, line_graph_iface *graph, std::vector<int> &params)
+static void serialize_graphs(osctl::osc_inline_typed_strstream &os, const line_graph_iface *graph, std::vector<int> &params)
 {
-    osctl::osc_inline_typed_strstream os;
     osc_cairo_control cairoctl(os);
     for (size_t i = 0; i < params.size(); i++)
     {
@@ -387,15 +386,26 @@ static void send_graph_via_osc(osctl::osc_client &client, const std::string &add
         os << (uint32_t)LGI_END_ITEM;
     }
     os << (uint32_t)LGI_END;
-    client.send(address, os);
 }
 
-calf_plugins::dssi_feedback_sender::dssi_feedback_sender(const char *URI, line_graph_iface *_graph, calf_plugins::parameter_properties *props, int num_params)
+calf_plugins::dssi_feedback_sender::dssi_feedback_sender(const char *URI, const line_graph_iface *_graph)
 {
     graph = _graph;
+    is_client_shared = false;
     client = new osctl::osc_client;
     client->bind("0.0.0.0", 0);
     client->set_url(URI);
+}
+
+calf_plugins::dssi_feedback_sender::dssi_feedback_sender(osctl::osc_client *_client, const line_graph_iface *_graph)
+{
+    graph = _graph;
+    client = _client;
+    is_client_shared = true;
+}
+
+void calf_plugins::dssi_feedback_sender::add_graphs(const calf_plugins::parameter_properties *props, int num_params)
+{
     for (int i = 0; i < num_params; i++)
     {
         if (props[i].flags & PF_PROP_GRAPH)
@@ -405,14 +415,15 @@ calf_plugins::dssi_feedback_sender::dssi_feedback_sender(const char *URI, line_g
 
 void calf_plugins::dssi_feedback_sender::update()
 {
-    send_graph_via_osc(*client, "/lineGraph", graph, indices);
+    osctl::osc_inline_typed_strstream os;
+    serialize_graphs(os, graph, indices);
+    client->send("/lineGraph", os);
 }
 
 calf_plugins::dssi_feedback_sender::~dssi_feedback_sender()
 {
-    // this would not be received by GUI's main loop because it's already been terminated
-    // client->send("/iQuit");
-    delete client;
+    if (!is_client_shared)
+        delete client;
 }
 
 #endif
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index df6ecf5..5febcb5 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -99,6 +99,9 @@ struct plugin_proxy_base
     /// Obtain instance pointers
     void resolve_instance();
 
+    /// Find a line graph interface, if available (via instance access/data access extensions)
+    const line_graph_iface *get_line_graph_iface() const;
+    
     /// Map an URI to an integer value using a given URI map
     uint32_t map_uri(const char *mapURI, const char *keyURI);
 };
@@ -153,6 +156,7 @@ plugin_proxy_base::plugin_proxy_base(const plugin_metadata_iface *metadata, LV2U
             ext_ui_host = (lv2_external_ui_host *)features[i]->data;
         }
     }
+    resolve_instance();
 }
 
 void plugin_proxy_base::send_float_to_host(int param_no, float value)
@@ -160,6 +164,7 @@ void plugin_proxy_base::send_float_to_host(int param_no, float value)
     params[param_no] = value;
     if (sends[param_no]) {
         TempSendSetter _a_(sends[param_no], false);
+        assert(!sends[param_no]);
         write_function(controller, param_no + param_offset, sizeof(float), 0, &params[param_no]);
     }
 }
@@ -183,6 +188,12 @@ uint32_t plugin_proxy_base::map_uri(const char *mapURI, const char *keyURI)
     return uri_map->uri_to_id(uri_map->callback_data, mapURI, keyURI);
 }
 
+const line_graph_iface *plugin_proxy_base::get_line_graph_iface() const
+{
+    if (instance)
+        return instance->get_line_graph_iface();
+    return NULL;
+}
 
 char *plugin_proxy_base::configure(const char *key, const char *value)
 {
@@ -262,18 +273,16 @@ struct lv2_plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy,
         return false;
     }
     
-    virtual const line_graph_iface *get_line_graph_iface() const {
-        if (instance)
-            return instance->get_line_graph_iface();
-        return NULL;
-    }
-    
     virtual char *configure(const char *key, const char *value)
     {
         plugin_proxy_base::configure(key, value);
         return NULL;
     }
     
+    virtual const line_graph_iface *get_line_graph_iface() const {
+        return plugin_proxy_base::get_line_graph_iface();
+    }
+    
     virtual float get_level(unsigned int port) { return 0.f; }
     virtual void execute(int command_no) { assert(0); }
     void send_configures(send_configure_iface *sci) { 
@@ -303,8 +312,6 @@ LV2UI_Handle gui_instantiate(const struct _LV2UI_Descriptor* descriptor,
     if (!proxy)
         return NULL;
     
-    proxy->resolve_instance();
-
     gtk_rc_parse(PKGLIBDIR "calf.rc");
     
     // dummy window
@@ -345,6 +352,7 @@ void gui_port_event(LV2UI_Handle handle, uint32_t port, uint32_t buffer_size, ui
     if (proxy->is_string_param[param])
     {
         TempSendSetter _a_(proxy->sends[param], false);
+        assert(!proxy->sends[param]);
         gui->plugin->configure(gui->plugin->get_param_props(param)->short_name, ((LV2_String_Data *)buffer)->data);
         return;
     }
@@ -352,6 +360,7 @@ void gui_port_event(LV2UI_Handle handle, uint32_t port, uint32_t buffer_size, ui
         return;
     {
         TempSendSetter _a_(proxy->sends[param], false);
+        assert(!proxy->sends[param]);
         gui->set_param_value(param, v);
     }
 }
@@ -385,6 +394,8 @@ public:
     osc_client cli;
     bool confirmed;
     string prefix;
+    dssi_feedback_sender *feedback_sender;
+    bool enable_graph_updates;
 
     ext_plugin_gui(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c, const LV2_Feature* const* f);
 
@@ -396,7 +407,7 @@ public:
     void port_event_impl(uint32_t port, uint32_t buffer_size, uint32_t format, const void *buffer);
 
     virtual void receive_osc_message(std::string address, std::string args, osc_strstream &buffer);
-    virtual ~ext_plugin_gui() {}
+    virtual ~ext_plugin_gui();
         
 private:
     static void show_(lv2_external_ui *h) { ((ext_plugin_gui *)(h))->show_impl(); }
@@ -408,6 +419,7 @@ ext_plugin_gui::ext_plugin_gui(const plugin_metadata_iface *metadata, LV2UI_Writ
 : plugin_proxy_base(metadata, wf, c, f)
 {
     confirmed = false;
+    feedback_sender = NULL;
     
     show = show_;
     hide = hide_;
@@ -443,6 +455,7 @@ void ext_plugin_gui::port_event_impl(uint32_t port, uint32_t buffer_size, uint32
     {
         int param = port - param_offset;
         TempSendSetter _a_(sends[param], false);
+        assert(!sends[param]);
         if (is_string_param[param])
         {
             osc_inline_typed_strstream data;
@@ -463,21 +476,34 @@ void ext_plugin_gui::port_event_impl(uint32_t port, uint32_t buffer_size, uint32
 
 void ext_plugin_gui::run_impl()
 {
+    srv.read_from_socket();
     if (waitpid(child_pid, NULL, WNOHANG) != 0)
     {
         ext_ui_host->ui_closed(controller);
+        return;
     }
-    srv.read_from_socket();
+    if (feedback_sender && enable_graph_updates)
+        feedback_sender->update();
 }
 
 void ext_plugin_gui::receive_osc_message(std::string address, std::string args, osc_strstream &buffer)
 {
     if (address == "/bridge/update" && args == "s")
     {
+        if (confirmed)
+        {
+            g_warning("Update message already received, ignoring");
+            return;
+        }
         string url;
         buffer >> url;
         cli.bind();
         cli.set_url(url.c_str());
+        if (get_line_graph_iface())
+        {
+            feedback_sender = new dssi_feedback_sender(&cli, get_line_graph_iface());
+            feedback_sender->add_graphs(plugin_metadata->get_param_props(0), param_count);
+        }
         confirmed = true;
     }
     else
@@ -490,6 +516,15 @@ void ext_plugin_gui::receive_osc_message(std::string address, std::string args,
         send_float_to_host(port - param_offset, value);
     }
     else
+    if (address == "/bridge/enable_updates" && args == "i")
+    {
+        int updates;
+        buffer >> updates;
+        enable_graph_updates = updates != 0;
+        if (enable_graph_updates && feedback_sender)
+            feedback_sender->update();
+    }
+    else
     if (address == "/bridge/configure" && args == "ss")
     {
         string key, value;
@@ -500,6 +535,12 @@ void ext_plugin_gui::receive_osc_message(std::string address, std::string args,
         srv.dump.receive_osc_message(address, args, buffer);
 }
 
+ext_plugin_gui::~ext_plugin_gui()
+{
+    if (feedback_sender)
+        delete feedback_sender;
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 LV2UI_Handle extgui_instantiate(const struct _LV2UI_Descriptor* descriptor,

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list