[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