[SCM] calf/master: Incomplete implementation of the plugin reordering option based on JACK graph.

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


The following commit has been merged in the master branch:
commit 0592be000becfed1ba52aa311e40c45c0acaf4a4
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Mon Dec 27 00:15:47 2010 +0000

    Incomplete implementation of the plugin reordering option based on JACK graph.

diff --git a/src/calf/gui.h b/src/calf/gui.h
index 68c1f39..b090fd2 100644
--- a/src/calf/gui.h
+++ b/src/calf/gui.h
@@ -191,6 +191,7 @@ struct main_window_owner_iface
     virtual void remove_plugin(plugin_ctl_iface *plugin) = 0;
     virtual char *open_file(const char *name) = 0;
     virtual char *save_file(const char *name) = 0;
+    virtual void reorder_plugins() = 0;
     virtual ~main_window_owner_iface() {}
 };
 
diff --git a/src/calf/host_session.h b/src/calf/host_session.h
index 01e570f..1085ebd 100644
--- a/src/calf/host_session.h
+++ b/src/calf/host_session.h
@@ -76,6 +76,7 @@ public:
     virtual void new_plugin(const char *name);    
     virtual void remove_plugin(plugin_ctl_iface *plugin);
     void remove_all_plugins();
+    void reorder_plugins();
     std::string get_next_instance_name(const std::string &effect_name);
     
     /// Create a toplevel window with progress bar
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index 5057fee..bc0ffe7 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -54,6 +54,8 @@ public:
     void delete_plugins();
     void connect(const std::string &p1, const std::string &p2);
     void close();
+    void apply_plugin_order(const std::vector<int> &indices);
+    void calculate_plugin_order(std::vector<int> &indices);
     const char **get_ports(const char *name_re, const char *type_re, unsigned long flags);
     
     static int do_jack_process(jack_nframes_t nframes, void *p);
@@ -65,7 +67,7 @@ public:
     struct port {
         jack_port_t *handle;
         float *data;
-        std::string name;
+        std::string name, nice_name;
         dsp::vumeter meter;
         port() : handle(NULL), data(NULL) {}
         ~port() { }
@@ -105,6 +107,10 @@ public:
     int process(jack_nframes_t nframes);
     /// Retrieve and cache output port buffers
     void cache_ports();
+    /// Retrieve the full list of input ports, audio+MIDI (the pointers are temporary, may point to nowhere after any changes etc.)
+    void get_all_input_ports(std::vector<port *> &ports);
+    /// Retrieve the full list of output ports (the pointers are temporary, may point to nowhere after any changes etc.)
+    void get_all_output_ports(std::vector<port *> &ports);
     
 public:
     // Port access
diff --git a/src/calf/main_win.h b/src/calf/main_win.h
index 6d17aaf..8e03358 100644
--- a/src/calf/main_win.h
+++ b/src/calf/main_win.h
@@ -95,6 +95,7 @@ namespace calf_plugins {
         static void on_save_action(GtkWidget *widget, main_window *main);
         static void on_save_as_action(GtkWidget *widget, main_window *main);
         static void on_preferences_action(GtkWidget *widget, main_window *main);
+        static void on_reorder_action(GtkWidget *widget, main_window *main);
         static void on_exit_action(GtkWidget *widget, main_window *main);
     };
 };
diff --git a/src/host_session.cpp b/src/host_session.cpp
index 9969043..9721dea 100644
--- a/src/host_session.cpp
+++ b/src/host_session.cpp
@@ -499,6 +499,13 @@ void host_session::set_ladish_handler()
     sa.sa_handler = sigusr1handler;
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESTART;
-    sigaction(SIGUSR1, &sa, NULL);
-    
+    sigaction(SIGUSR1, &sa, NULL);    
 }
+
+void host_session::reorder_plugins()
+{
+    vector<int> order;
+    client.calculate_plugin_order(order);
+    client.apply_plugin_order(order);
+}
+
diff --git a/src/jack_client.cpp b/src/jack_client.cpp
index 010e69a..af380d1 100644
--- a/src/jack_client.cpp
+++ b/src/jack_client.cpp
@@ -23,6 +23,7 @@
 #include <jack/jack.h>
 #include <calf/giface.h>
 #include <calf/jackhost.h>
+#include <set>
 
 using namespace std;
 using namespace calf_utils;
@@ -123,3 +124,83 @@ void jack_client::delete_plugins()
     plugins.clear();
 }
 
+void jack_client::calculate_plugin_order(std::vector<int> &indices)
+{
+    map<string, int> port_to_plugin;
+    multimap<int, int> run_before;
+    for (unsigned int i = 0; i < plugins.size(); i++)
+    {
+        vector<jack_host::port *> ports;
+        plugins[i]->get_all_input_ports(ports);
+        for (unsigned int j = 0; j < ports.size(); j++)
+            port_to_plugin[ports[j]->nice_name] = i;
+    }
+    
+    for (unsigned int i = 0; i < plugins.size(); i++)
+    {
+        vector<jack_host::port *> ports;
+        plugins[i]->get_all_output_ports(ports);
+        for (unsigned int j = 0; j < ports.size(); j++)
+        {
+            const char **conns = jack_port_get_connections(ports[j]->handle);
+            if (!conns)
+                continue;
+            for (const char **k = conns; *k; k++)
+            {
+                int cnlen = name.length();
+                if (0 != strncmp(*k, name.c_str(), cnlen))
+                    continue;
+                if ((*k)[cnlen] != ':')
+                    continue;
+                map<string, int>::const_iterator p = port_to_plugin.find((*k) + cnlen + 1);
+                if (p != port_to_plugin.end())
+                {
+                    run_before.insert(make_pair<int, int>(p->second, i));
+                }
+            }
+            jack_free(conns);
+        }
+    }
+    
+    struct deptracker
+    {
+        vector<int> &indices;
+        const multimap<int, int> &run_before;
+        set<int> already_added;
+        int count;
+        
+        deptracker(vector<int> &i, const multimap<int, int> &rb, int c)
+        : indices(i)
+        , run_before(rb)
+        , count(c)
+        {
+        }
+        void add_with_dependent(int item)
+        {
+            if (already_added.count(item))
+                return;
+            already_added.insert(item);
+            for(multimap<int, int>::const_iterator i = run_before.find(item); i != run_before.end() && i->first == item; i++)
+                add_with_dependent(i->second);
+            indices.push_back(item);
+        }
+        void run()
+        {
+            for (int i = 0; i < count; i++)
+                add_with_dependent(i);                    
+        }
+    };
+    indices.clear();
+    deptracker(indices, run_before, plugins.size()).run();
+}
+
+void jack_client::apply_plugin_order(const std::vector<int> &indices)
+{
+    std::vector<jack_host *> plugins_new;
+    assert(indices.size() == plugins.size());
+    for (unsigned int i = 0; i < indices.size(); i++)
+        plugins_new.push_back(plugins[indices[i]]);
+    ptlock lock(mutex);
+    plugins.swap(plugins_new);
+}
+
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index bb7807e..d717d8a 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -96,6 +96,7 @@ void jack_host::create_ports() {
     for (int i=0; i<in_count; i++) {
         sprintf(buf, "%s_in_%s", instance_name.c_str(), suffixes[i]);
         sprintf(buf2, client->input_name.c_str(), client->input_nr++);
+        inputs[i].nice_name = buf;
         inputs[i].name = buf2;
         inputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput , 0);
         inputs[i].data = NULL;
@@ -107,6 +108,7 @@ void jack_host::create_ports() {
     if (metadata->get_midi()) {
         sprintf(buf, "%s_midi_in", instance_name.c_str());
         sprintf(buf2, client->midi_name.c_str(), client->midi_nr++);
+        midi_port.nice_name = buf;
         midi_port.name = buf2;
         midi_port.handle = jack_port_register(client->client, buf, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
         if (!midi_port.handle)
@@ -116,6 +118,7 @@ void jack_host::create_ports() {
     for (int i=0; i<out_count; i++) {
         sprintf(buf, "%s_out_%s", instance_name.c_str(), suffixes[i]);
         sprintf(buf2, client->output_name.c_str(), client->output_nr++);
+        outputs[i].nice_name = buf;
         outputs[i].name = buf2;
         outputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput , 0);
         outputs[i].data = NULL;
@@ -263,6 +266,20 @@ void jack_host::cache_ports()
     }
 }
 
+void jack_host::get_all_input_ports(std::vector<port *> &ports)
+{
+    for (int i = 0; i < in_count; i++)
+        ports.push_back(&inputs[i]);
+    if (metadata->get_midi())
+        ports.push_back(&midi_port);
+}
+
+void jack_host::get_all_output_ports(std::vector<port *> &ports)
+{
+    for (int i = 0; i < out_count; i++)
+        ports.push_back(&outputs[i]);
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 static const char *short_options = "c:i:l:o:m:M:s:ehv";
diff --git a/src/main_win.cpp b/src/main_win.cpp
index 3a1dce9..fbbcb59 100644
--- a/src/main_win.cpp
+++ b/src/main_win.cpp
@@ -44,7 +44,9 @@ static const char *ui_xml =
 "      <menuitem action=\"FileSave\"/>\n"
 "      <menuitem action=\"FileSaveAs\"/>\n"
 "      <separator/>\n"
-"      <menuitem action=\"Preferences\"/>\n"
+"      <menuitem action=\"FileReorder\"/>\n"
+"      <separator/>\n"
+"      <menuitem action=\"FilePreferences\"/>\n"
 "      <separator/>\n"
 "      <menuitem action=\"FileQuit\"/>\n"
 "    </menu>\n"
@@ -60,7 +62,8 @@ const GtkActionEntry main_window::actions[] = {
     { "FileSaveAs", GTK_STOCK_SAVE_AS, "Save _as...", NULL, "Save a rack file as", (GCallback)on_save_as_action },
     { "HostMenuAction", NULL, "_Host", NULL, "Host-related operations", NULL },
     { "AddPluginMenuAction", NULL, "_Add plugin", NULL, "Add a plugin to the rack", NULL },
-    { "Preferences", GTK_STOCK_PREFERENCES, "_Preferences...", NULL, "Adjust preferences", (GCallback)on_preferences_action },
+    { "FileReorder", NULL, "_Reorder plugins", NULL, "Reorder plugins to minimize latency", (GCallback)on_reorder_action },
+    { "FilePreferences", GTK_STOCK_PREFERENCES, "_Preferences...", NULL, "Adjust preferences", (GCallback)on_preferences_action },
     { "FileQuit", GTK_STOCK_QUIT, "_Quit", "<Ctrl>Q", "Exit application", (GCallback)on_exit_action },
 };
 
@@ -79,6 +82,11 @@ void main_window::on_save_as_action(GtkWidget *widget, main_window *main)
     main->save_file_as();
 }
 
+void main_window::on_reorder_action(GtkWidget *widget, main_window *main)
+{
+    main->owner->reorder_plugins();
+}
+
 void main_window::on_preferences_action(GtkWidget *widget, main_window *main)
 {
     GtkBuilder *prefs_builder = gtk_builder_new();

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list