diff --git a/SConstruct b/SConstruct index ff5df46321..caa88a7a9a 100644 --- a/SConstruct +++ b/SConstruct @@ -591,7 +591,7 @@ else: if env['LV2']: conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion}) - if conf.CheckPKGVersion('slv2', '0.6.0'): + if conf.CheckPKGVersion('slv2', '0.6.1'): libraries['slv2'] = LibraryInfo() libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2') env.Append (CCFLAGS="-DHAVE_LV2") diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index cbb4677ab0..d18f7d80ce 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -21,6 +21,7 @@ #include #include +#include "ardour_ui.h" #include "lv2_plugin_ui.h" using namespace Gtk; @@ -51,6 +52,38 @@ LV2PluginUI::parameter_changed (uint32_t port_index, float val) } } +bool +LV2PluginUI::start_updating(GdkEventAny* event) +{ + if (!_output_ports.empty()) { + _screen_update_connection.disconnect(); + _screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect + (mem_fun(*this, &LV2PluginUI::output_update)); + } + return false; +} + +bool +LV2PluginUI::stop_updating(GdkEventAny* event) +{ + if (!_output_ports.empty()) { + _screen_update_connection.disconnect(); + } + return false; +} + +void +LV2PluginUI::output_update() +{ + /* FIXME only works with control output ports (which is all we support now anyway) */ + uint32_t nports = _output_ports.size(); + for (uint32_t i = 0; i < nports; ++i) { + uint32_t index = _output_ports[i]; + parameter_changed(index, _lv2->get_parameter(index)); + } + +} + LV2PluginUI::LV2PluginUI (boost::shared_ptr pi, boost::shared_ptr lv2p) : PlugUIBase (pi) , _lv2(lv2p) @@ -59,12 +92,18 @@ LV2PluginUI::LV2PluginUI (boost::shared_ptr pi, boost::shared_ptr< _lv2->slv2_plugin(), _lv2->slv2_ui(), LV2PluginUI::lv2_ui_write, this, _lv2->features()); + uint32_t num_ports = slv2_plugin_get_num_ports(lv2p->slv2_plugin()); + for (uint32_t i = 0; i < num_ports; ++i) { + if (lv2p->parameter_is_output(i) && lv2p->parameter_is_control(i) && is_update_wanted(i)) { + _output_ports.push_back(i); + } + } + GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_inst); _gui_widget = Glib::wrap(c_widget); _gui_widget->show_all(); pack_start(*_gui_widget, true, true); - uint32_t num_ports = slv2_plugin_get_num_ports(lv2p->slv2_plugin()); _values = new float[num_ports]; for (uint32_t i = 0; i < num_ports; ++i) { bool ok; @@ -101,6 +140,8 @@ LV2PluginUI::package (Gtk::Window& win) { /* forward configure events to plugin window */ win.signal_configure_event().connect (mem_fun (*this, &LV2PluginUI::configure_handler)); + win.signal_map_event().connect (mem_fun (*this, &LV2PluginUI::start_updating)); + win.signal_unmap_event().connect (mem_fun (*this, &LV2PluginUI::stop_updating)); return 0; } @@ -111,3 +152,9 @@ LV2PluginUI::configure_handler (GdkEventConfigure* ev) return false; } +bool +LV2PluginUI::is_update_wanted(uint32_t index) +{ + /* FIXME this should check the port notification properties, which nobody sets now anyway :) */ + return true; +} diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h index 5946d8bd77..1af023974c 100644 --- a/gtk2_ardour/lv2_plugin_ui.h +++ b/gtk2_ardour/lv2_plugin_ui.h @@ -47,13 +47,15 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox gint get_preferred_height (); gint get_preferred_width (); - bool start_updating(GdkEventAny*) {return false;} - bool stop_updating(GdkEventAny*) {return false;} + bool start_updating(GdkEventAny*); + bool stop_updating(GdkEventAny*); int package (Gtk::Window&); private: boost::shared_ptr _lv2; + std::vector _output_ports; + sigc::connection _screen_update_connection; Gtk::Widget* _gui_widget; SLV2UIInstance _inst; @@ -69,6 +71,8 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox void parameter_changed(uint32_t, float); bool configure_handler (GdkEventConfigure*); void save_plugin_setting (); + void output_update(); + bool is_update_wanted(uint32_t index); }; #endif // HAVE_LV2 diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index 978e52b446..7114428626 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -65,6 +65,8 @@ class LV2Plugin : public ARDOUR::Plugin SLV2Plugin slv2_plugin() { return _plugin; } SLV2UI slv2_ui() { return _ui; } SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); } + + const char* port_symbol(uint32_t port); const LV2_Feature* const* features() { return _features; } diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 0260e02560..3b0a61b4f0 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -187,6 +187,19 @@ LV2Plugin::default_value (uint32_t port) return _defaults[port]; } +const char* +LV2Plugin::port_symbol (uint32_t index) +{ + SLV2Port port = slv2_plugin_get_port_by_index(_plugin, index); + if (!port) { + error << name() << ": Invalid port index " << index << endmsg; + } + + SLV2Value sym = slv2_port_get_symbol(_plugin, port); + return slv2_value_as_string(sym); +} + + void LV2Plugin::set_parameter (uint32_t which, float val) { @@ -251,6 +264,7 @@ LV2Plugin::get_state() child = new XMLNode("port"); snprintf(buf, sizeof(buf), "%u", i); child->add_property("number", string(buf)); + child->add_property("symbol", port_symbol(i)); snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]); child->add_property("value", string(buf)); root->add_child_nocopy (*child); diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 7ed35dd1a7..e199dbcec5 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -816,7 +816,7 @@ PluginInsert::set_state(const XMLNode& node) if ((cprop = child->property("number")) != 0) { port = cprop->value().c_str(); } else { - warning << _("PluginInsert: Auto: no ladspa port number") << endmsg; + warning << _("PluginInsert: Auto: no plugin port number") << endmsg; continue; }