[SCM] calf/master: + DSSI: basic version of live graphs (still doesn't serialize cairo attributes, compressor doesn't work, resolution is poor, and there may be more bugs)
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:38:58 UTC 2013
The following commit has been merged in the master branch:
commit e64e70700208b9cd5a73ba789987752f4cb899f5
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Thu Jan 22 01:36:47 2009 +0000
+ DSSI: basic version of live graphs (still doesn't serialize cairo attributes, compressor doesn't work, resolution is poor, and there may be more bugs)
diff --git a/src/calf/giface.h b/src/calf/giface.h
index 445f5fc..b983ecc 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -380,8 +380,11 @@ struct dssi_feedback_sender
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;
- dssi_feedback_sender(const char *URI, line_graph_iface *graph, calf_plugins::parameter_properties *props, int num_params);
+ dssi_feedback_sender(const char *URI, line_graph_iface *_graph, calf_plugins::parameter_properties *props, int num_params);
+ void update();
~dssi_feedback_sender();
};
#endif
diff --git a/src/calf/ladspa_wrap.h b/src/calf/ladspa_wrap.h
index e2becd2..f313ed1 100644
--- a/src/calf/ladspa_wrap.h
+++ b/src/calf/ladspa_wrap.h
@@ -144,6 +144,13 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
return NULL;
}
else
+ if (!strcmp(key, "OSC:UPDATE"))
+ {
+ if (feedback_sender)
+ feedback_sender->update();
+ return NULL;
+ }
+ else
#endif
if (!strcmp(key, "ExecCommand"))
{
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 64552c9..902c0f3 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -69,7 +69,32 @@ void osctl_test()
}
#endif
-struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy
+struct graph_item
+{
+ float data[128];
+};
+
+struct dot_item
+{
+ float x, y;
+ int32_t size;
+};
+
+struct gridline_item
+{
+ float pos;
+ int32_t vertical;
+ std::string text;
+};
+
+struct param_line_graphs
+{
+ vector<graph_item *> graphs;
+ vector<dot_item *> dots;
+ vector<gridline_item *> gridlines;
+};
+
+struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy, public line_graph_iface
{
osc_client *client;
bool send_osc;
@@ -77,6 +102,7 @@ struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy
map<string, string> cfg_vars;
int param_count;
float *params;
+ map<int, param_line_graphs> graphs;
plugin_proxy(plugin_metadata_iface *md)
: plugin_metadata_proxy(md)
@@ -140,23 +166,65 @@ struct plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy
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 help(char *argv[])
+bool plugin_proxy::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
{
- printf("GTK+ user interface for Calf DSSI plugins\nSyntax: %s [--help] [--version] <osc-url> <so-file> <plugin-label> <instance-name>\n", argv[0]);
+ if (!graphs.count(index))
+ return false;
+ param_line_graphs &g = graphs[index];
+ if (subindex < (int)g.graphs.size())
+ {
+ float *sdata = g.graphs[subindex]->data;
+ for (int i = 0; i < points; i++) {
+ float pos = i * 127.0 / points;
+ int ipos = i * 127 / points;
+ data[i] = sdata[ipos] + (sdata[ipos + 1] - sdata[ipos]) * (pos-ipos);
+ }
+ return true;
+ }
+ return false;
}
-static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"debug", 0, 0, 'd'},
- {0,0,0,0},
-};
+bool plugin_proxy::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+{
+ if (!graphs.count(index))
+ return false;
+ param_line_graphs &g = graphs[index];
+ if (subindex < (int)g.dots.size())
+ {
+ x = g.dots[subindex]->x;
+ y = g.dots[subindex]->y;
+ size = g.dots[subindex]->size;
+ return true;
+ }
+ return false;
+}
+
+bool plugin_proxy::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+{
+ if (!graphs.count(index))
+ return false;
+ param_line_graphs &g = graphs[index];
+ if (subindex < (int)g.gridlines.size())
+ {
+ pos = g.gridlines[subindex]->pos;
+ vertical = g.gridlines[subindex]->vertical != 0;
+ legend = g.gridlines[subindex]->text;
+ return true;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
GMainLoop *mainloop;
-static bool osc_debug = true;
+static bool osc_debug = false;
struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream>
{
@@ -167,6 +235,8 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
osc_client cli;
bool in_program, enable_dump;
vector<plugin_preset> presets;
+ /// Timeout callback source ID
+ int source_id;
dssi_osc_server()
: plugin(NULL)
@@ -174,6 +244,7 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
, window(new plugin_gui_window(main_win))
{
sink = this;
+ source_id = 0;
}
static void on_destroy(GtkWindow *window, dssi_osc_server *self)
@@ -207,6 +278,7 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
plugin->client = &cli;
plugin->send_osc = true;
((main_window *)window->main)->conditions.insert("dssi");
+ ((main_window *)window->main)->conditions.insert("directlink");
window->create(plugin, title.c_str(), effect_name.c_str());
plugin->gui = window->gui;
gtk_signal_connect(GTK_OBJECT(window->toplevel), "destroy", G_CALLBACK(on_destroy), this);
@@ -214,6 +286,13 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
get_builtin_presets().get_for_plugin(presets, effect_name.c_str());
get_user_presets().get_for_plugin(tmp_presets, effect_name.c_str());
presets.insert(presets.end(), tmp_presets.begin(), tmp_presets.end());
+ source_id = g_timeout_add_full(G_PRIORITY_LOW, 1000/30, on_idle, this, NULL);
+ }
+
+ static gboolean on_idle(void *self)
+ {
+ ((dssi_osc_server *)(self))->send_osc_update();
+ return TRUE;
}
void set_osc_update(bool enabled)
@@ -223,98 +302,188 @@ struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream
data << (enabled ? get_uri() : "");
cli.send("/configure", data);
}
-
- virtual void receive_osc_message(std::string address, std::string args, osc_strstream &buffer)
+ void send_osc_update()
{
- if (osc_debug)
- dump.receive_osc_message(address, args, buffer);
- if (address == prefix + "/update" && args == "s")
- {
- string str;
- buffer >> str;
- debug_printf("UPDATE: %s\n", str.c_str());
- return;
- }
- else if (address == prefix + "/quit")
- {
- set_osc_update(false);
- debug_printf("QUIT\n");
- g_main_loop_quit(mainloop);
- return;
- }
- else if (address == prefix + "/configure"&& args == "ss")
+ static int serial_no = 0;
+ osc_inline_typed_strstream data;
+ data << "OSC:UPDATE";
+ data << calf_utils::i2s(serial_no++);
+ cli.send("/configure", data);
+ }
+
+ virtual void receive_osc_message(std::string address, std::string args, osc_strstream &buffer);
+ void unmarshal_line_graph(osc_strstream &buffer);
+};
+
+void dssi_osc_server::unmarshal_line_graph(osc_strstream &buffer)
+{
+ uint32_t cmd;
+
+ do {
+ buffer >> cmd;
+ if (cmd == LGI_GRAPH)
{
- string key, value;
- buffer >> key >> value;
- plugin->cfg_vars[key] = value;
- // XXXKF perhaps this should be queued !
- window->gui->refresh();
- return;
+ uint32_t param;
+ buffer >> param;
+ param_line_graphs &graphs = plugin->graphs[param];
+
+ for (size_t i = 0; i < graphs.graphs.size(); i++)
+ delete graphs.graphs[i];
+ graphs.graphs.clear();
+
+ for (size_t i = 0; i < graphs.dots.size(); i++)
+ delete graphs.dots[i];
+ graphs.dots.clear();
+
+ for (size_t i = 0; i < graphs.gridlines.size(); i++)
+ delete graphs.gridlines[i];
+ graphs.gridlines.clear();
+
+ do {
+ buffer >> cmd;
+ if (cmd == LGI_SUBGRAPH)
+ {
+ buffer >> param; // ignore number of points
+ graph_item *gi = new graph_item;
+ for (int i = 0; i < 128; i++)
+ buffer >> gi->data[i];
+ graphs.graphs.push_back(gi);
+ }
+ else
+ if (cmd == LGI_DOT)
+ {
+ dot_item *di = new dot_item;
+ buffer >> di->x >> di->y >> di->size;
+ graphs.dots.push_back(di);
+ }
+ else
+ if (cmd == LGI_LEGEND)
+ {
+ gridline_item *li = new gridline_item;
+ buffer >> li->pos >> li->vertical >> li->text;
+ graphs.gridlines.push_back(li);
+ }
+ else
+ break;
+ } while(1);
+
}
- else if (address == prefix + "/program"&& args == "ii")
+ else
+ break;
+ } while(1);
+}
+
+void dssi_osc_server::receive_osc_message(std::string address, std::string args, osc_strstream &buffer)
+{
+ if (osc_debug)
+ dump.receive_osc_message(address, args, buffer);
+ if (address == prefix + "/update" && args == "s")
+ {
+ string str;
+ buffer >> str;
+ debug_printf("UPDATE: %s\n", str.c_str());
+ return;
+ }
+ else if (address == prefix + "/quit")
+ {
+ set_osc_update(false);
+ debug_printf("QUIT\n");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+ else if (address == prefix + "/configure"&& args == "ss")
+ {
+ string key, value;
+ buffer >> key >> value;
+ plugin->cfg_vars[key] = value;
+ // XXXKF perhaps this should be queued !
+ window->gui->refresh();
+ return;
+ }
+ else if (address == prefix + "/program"&& args == "ii")
+ {
+ uint32_t bank, program;
+
+ buffer >> bank >> program;
+
+ unsigned int nr = bank * 128 + program;
+ debug_printf("PROGRAM %d\n", nr);
+ if (nr == 0)
{
- uint32_t bank, program;
-
- buffer >> bank >> program;
-
- unsigned int nr = bank * 128 + program;
- debug_printf("PROGRAM %d\n", nr);
- if (nr == 0)
- {
- bool sosc = plugin->send_osc;
- plugin->send_osc = false;
- int count = plugin->get_param_count();
- for (int i =0 ; i < count; i++)
- plugin->set_param_value(i, plugin->get_param_props(i)->def_value);
- plugin->send_osc = sosc;
- window->gui->refresh();
- // special handling for default preset
- return;
- }
- nr--;
- if (nr >= presets.size())
- return;
bool sosc = plugin->send_osc;
plugin->send_osc = false;
- presets[nr].activate(plugin);
+ int count = plugin->get_param_count();
+ for (int i =0 ; i < count; i++)
+ plugin->set_param_value(i, plugin->get_param_props(i)->def_value);
plugin->send_osc = sosc;
window->gui->refresh();
-
- // cli.send("/update", data);
+ // special handling for default preset
return;
}
- else if (address == prefix + "/control" && args == "if")
- {
- uint32_t port;
- float val;
-
- buffer >> port >> val;
-
- int idx = port - plugin->get_param_port_offset();
- debug_printf("CONTROL %d %f\n", idx, val);
- bool sosc = plugin->send_osc;
- plugin->send_osc = false;
- window->gui->set_param_value(idx, val);
- plugin->send_osc = sosc;
+ nr--;
+ if (nr >= presets.size())
return;
- }
- else if (address == prefix + "/show")
- {
- set_osc_update(true);
+ bool sosc = plugin->send_osc;
+ plugin->send_osc = false;
+ presets[nr].activate(plugin);
+ plugin->send_osc = sosc;
+ window->gui->refresh();
+
+ // cli.send("/update", data);
+ return;
+ }
+ else if (address == prefix + "/control" && args == "if")
+ {
+ uint32_t port;
+ float val;
+
+ buffer >> port >> val;
+
+ int idx = port - plugin->get_param_port_offset();
+ debug_printf("CONTROL %d %f\n", idx, val);
+ bool sosc = plugin->send_osc;
+ plugin->send_osc = false;
+ window->gui->set_param_value(idx, val);
+ plugin->send_osc = sosc;
+ set_osc_update(false);
+ set_osc_update(true);
+ return;
+ }
+ else if (address == prefix + "/show")
+ {
+ set_osc_update(true);
- gtk_widget_show_all(GTK_WIDGET(window->toplevel));
- return;
- }
- else if (address == prefix + "/hide")
- {
- set_osc_update(false);
+ gtk_widget_show_all(GTK_WIDGET(window->toplevel));
+ return;
+ }
+ else if (address == prefix + "/hide")
+ {
+ set_osc_update(false);
- gtk_widget_hide(GTK_WIDGET(window->toplevel));
- return;
- }
- else
- printf("Unknown OSC address: %s\n", address.c_str());
+ gtk_widget_hide(GTK_WIDGET(window->toplevel));
+ return;
+ }
+ else if (address == prefix + "/lineGraph")
+ {
+ unmarshal_line_graph(buffer);
+ return;
}
+ else
+ printf("Unknown OSC address: %s\n", address.c_str());
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void help(char *argv[])
+{
+ printf("GTK+ user interface for Calf DSSI plugins\nSyntax: %s [--help] [--version] <osc-url> <so-file> <plugin-label> <instance-name>\n", argv[0]);
+}
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {"debug", 0, 0, 'd'},
+ {0,0,0,0},
};
int main(int argc, char *argv[])
@@ -384,6 +553,8 @@ int main(int argc, char *argv[])
}
g_main_loop_run(mainloop);
+ if (srv.source_id)
+ g_source_remove(srv.source_id);
srv.set_osc_update(false);
debug_printf("exited\n");
diff --git a/src/giface.cpp b/src/giface.cpp
index 21d9bf9..19773e0 100644
--- a/src/giface.cpp
+++ b/src/giface.cpp
@@ -268,7 +268,7 @@ static void send_graph_via_osc(osctl::osc_client &client, const std::string &add
os << (uint32_t)LGI_SUBGRAPH;
os << (uint32_t)128;
for (int p = 0; p < 128; p++)
- os << data[i];
+ os << data[p];
}
else
break;
@@ -298,17 +298,21 @@ static void send_graph_via_osc(osctl::osc_client &client, const std::string &add
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, line_graph_iface *_graph, calf_plugins::parameter_properties *props, int num_params)
{
+ graph = _graph;
client = new osctl::osc_client;
client->bind("0.0.0.0", 0);
client->set_url(URI);
- client->send("/iAmHere");
for (int i = 0; i < num_params; i++)
{
if (props[i].flags & PF_PROP_GRAPH)
indices.push_back(i);
}
+}
+
+void calf_plugins::dssi_feedback_sender::update()
+{
send_graph_via_osc(*client, "/lineGraph", graph, indices);
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list