summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-10-20 09:07:51 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2015-10-20 09:07:58 -0400
commit336b2eb9a4a8634bae84a15e952d20335aa28c12 (patch)
treeab171341dd5ab7915ae77c937673ae586116ecb9 /gtk2_ardour
parentf1a6d7816d13d3eca5885494f711b88a8270c899 (diff)
rename ParameterChanged signal in Plugin to ParameterChangedExternally to reflect its intent, and clean up the result.
The signal exists to notify listeners that something outside of the host's control (e.g. a plugin's own GUI for AU or VST) has modified a plugin parameter. Previous code had strange feedback loops and ambiguous semantics. Significant modification of LV2 GUI updating was required. Still to be tested for feedback loop issues: AudioUnits
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/lv2_plugin_ui.cc54
-rw-r--r--gtk2_ardour/lv2_plugin_ui.h5
-rw-r--r--gtk2_ardour/plugin_ui.cc8
-rw-r--r--gtk2_ardour/plugin_ui.h1
4 files changed, 31 insertions, 37 deletions
diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc
index 141f437f4c..e2c446ef20 100644
--- a/gtk2_ardour/lv2_plugin_ui.cc
+++ b/gtk2_ardour/lv2_plugin_ui.cc
@@ -20,7 +20,9 @@
#include "ardour/lv2_plugin.h"
#include "ardour/session.h"
#include "pbd/error.h"
+#include "pbd/stacktrace.h"
+#include "gui_thread.h"
#include "lv2_plugin_ui.h"
#include "timers.h"
@@ -53,6 +55,9 @@ LV2PluginUI::write_from_ui(void* controller,
}
boost::shared_ptr<AutomationControl> ac = me->_controllables[port_index];
+ /* Cache our local copy of the last value received from the GUI */
+ me->_values[port_index] = *(const float*) buffer;
+ /* Now update the control itself */
if (ac) {
ac->set_value(*(const float*)buffer);
}
@@ -120,26 +125,18 @@ LV2PluginUI::on_external_ui_closed(void* controller)
}
void
-LV2PluginUI::parameter_changed(uint32_t port_index, float val)
+LV2PluginUI::control_changed (uint32_t port_index)
{
- PlugUIBase::parameter_changed(port_index, val);
-
- if (val != _values[port_index]) {
- parameter_update(port_index, val);
+ /* Must run in GUI thread because we modify _updates with no lock */
+ if (_lv2->get_parameter (port_index) != _values[port_index]) {
+ /* current plugin parameter does not match last value received
+ from GUI, so queue an update to push it to the GUI during
+ our regular timeout.
+ */
+ _updates.insert (port_index);
}
}
-void
-LV2PluginUI::parameter_update(uint32_t port_index, float val)
-{
- if (!_inst) {
- return;
- }
-
- suil_instance_port_event((SuilInstance*)_inst, port_index, 4, 0, &val);
- _values[port_index] = val;
-}
-
bool
LV2PluginUI::start_updating(GdkEventAny*)
{
@@ -183,13 +180,14 @@ 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));
+ if (_inst) {
+ for (Updates::iterator i = _updates.begin(); i != _updates.end(); ++i) {
+ float val = _lv2->get_parameter (*i);
+ /* push current value to the GUI */
+ suil_instance_port_event ((SuilInstance*)_inst, (*i), 4, 0, &val);
+ }
+ _updates.clear ();
}
-
}
LV2PluginUI::LV2PluginUI(boost::shared_ptr<PluginInsert> pi,
@@ -358,12 +356,14 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
bool ok;
uint32_t port = _lv2->nth_parameter(i, ok);
if (ok) {
- _values[port] = _lv2->get_parameter(port);
_controllables[port] = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (
insert->control(Evoral::Parameter(PluginAutomation, 0, port)));
- if (_lv2->parameter_is_control(port) && _lv2->parameter_is_input(port)) {
- parameter_update(port, _values[port]);
+ /* FIXME only works with control output ports (which is all we support now anyway) */
+ if (_controllables[port] && _lv2->parameter_is_control(port) && _lv2->parameter_is_input(port)) {
+ _controllables[port]->Changed.connect (control_connections, invalidator (*this), boost::bind (&LV2PluginUI::control_changed, this, port), gui_context());
+ /* queue for first update ("push") to GUI */
+ _updates.insert (port);
}
}
}
@@ -401,9 +401,7 @@ LV2PluginUI::lv2ui_free()
LV2PluginUI::~LV2PluginUI ()
{
- if (_values) {
- delete[] _values;
- }
+ delete [] _values;
_message_update_connection.disconnect();
_screen_update_connection.disconnect();
diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h
index 6a8acf9cf5..25ab4b9e30 100644
--- a/gtk2_ardour/lv2_plugin_ui.h
+++ b/gtk2_ardour/lv2_plugin_ui.h
@@ -26,6 +26,7 @@
#include <list>
#include <map>
+#include <set>
#include <vector>
#include <gtkmm/widget.h>
@@ -64,7 +65,7 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
private:
- void parameter_changed (uint32_t, float);
+ void control_changed (uint32_t);
typedef boost::shared_ptr<ARDOUR::AutomationControl> ControllableRef;
@@ -85,6 +86,8 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
LV2_Feature _parent_feature;
Gtk::Window* _win_ptr;
void* _inst;
+ typedef std::set<uint32_t> Updates;
+ Updates _updates;
static void on_external_ui_closed(void* controller);
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index 37c01462b2..19dbee422f 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -484,7 +484,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
plugin->PresetAdded.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::preset_added_or_removed, this), gui_context ());
plugin->PresetRemoved.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::preset_added_or_removed, this), gui_context ());
plugin->PresetLoaded.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::update_preset, this), gui_context ());
- plugin->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::parameter_changed, this, _1, _2), gui_context ());
+ plugin->PresetDirty.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::update_preset_modified, this), gui_context ());
insert->AutomationStateChanged.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::automation_state_changed, this), gui_context());
@@ -814,12 +814,6 @@ PlugUIBase::update_preset_modified ()
}
void
-PlugUIBase::parameter_changed (uint32_t, float)
-{
- update_preset_modified ();
-}
-
-void
PlugUIBase::preset_added_or_removed ()
{
/* Update both the list and the currently-displayed preset */
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index 41f4ef39f1..d2e5e21cca 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -170,7 +170,6 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
void plugin_going_away ();
void automation_state_changed ();
- virtual void parameter_changed (uint32_t, float);
void preset_added_or_removed ();
void update_preset_modified ();