13
0

Clean up generic and LV2 plugin GUI to deal with ParameterChanged(Externally) alteration

This commit is contained in:
Paul Davis 2015-10-20 10:12:51 -04:00
parent f806f059b3
commit ac008dac02
4 changed files with 31 additions and 37 deletions

View File

@ -20,7 +20,9 @@
#include "ardour/lv2_plugin.h" #include "ardour/lv2_plugin.h"
#include "ardour/session.h" #include "ardour/session.h"
#include "pbd/error.h" #include "pbd/error.h"
#include "pbd/stacktrace.h"
#include "gui_thread.h"
#include "lv2_plugin_ui.h" #include "lv2_plugin_ui.h"
#include "timers.h" #include "timers.h"
@ -53,6 +55,9 @@ LV2PluginUI::write_from_ui(void* controller,
} }
boost::shared_ptr<AutomationControl> ac = me->_controllables[port_index]; 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) { if (ac) {
ac->set_value(*(const float*)buffer); ac->set_value(*(const float*)buffer);
} }
@ -120,26 +125,18 @@ LV2PluginUI::on_external_ui_closed(void* controller)
} }
void void
LV2PluginUI::parameter_changed(uint32_t port_index, float val) LV2PluginUI::control_changed (uint32_t port_index)
{ {
PlugUIBase::parameter_changed(port_index, val); /* Must run in GUI thread because we modify _updates with no lock */
if (_lv2->get_parameter (port_index) != _values[port_index]) {
if (val != _values[port_index]) { /* current plugin parameter does not match last value received
parameter_update(port_index, val); 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 bool
LV2PluginUI::start_updating(GdkEventAny*) 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) */ if (_inst) {
uint32_t nports = _output_ports.size(); for (Updates::iterator i = _updates.begin(); i != _updates.end(); ++i) {
for (uint32_t i = 0; i < nports; ++i) { float val = _lv2->get_parameter (*i);
uint32_t index = _output_ports[i]; /* push current value to the GUI */
parameter_changed(index, _lv2->get_parameter(index)); suil_instance_port_event ((SuilInstance*)_inst, (*i), 4, 0, &val);
}
_updates.clear ();
} }
} }
LV2PluginUI::LV2PluginUI(boost::shared_ptr<PluginInsert> pi, LV2PluginUI::LV2PluginUI(boost::shared_ptr<PluginInsert> pi,
@ -358,12 +356,14 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
bool ok; bool ok;
uint32_t port = _lv2->nth_parameter(i, ok); uint32_t port = _lv2->nth_parameter(i, ok);
if (ok) { if (ok) {
_values[port] = _lv2->get_parameter(port);
_controllables[port] = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> ( _controllables[port] = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (
insert->control(Evoral::Parameter(PluginAutomation, 0, port))); insert->control(Evoral::Parameter(PluginAutomation, 0, port)));
if (_lv2->parameter_is_control(port) && _lv2->parameter_is_input(port)) { /* FIXME only works with control output ports (which is all we support now anyway) */
parameter_update(port, _values[port]); 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 () LV2PluginUI::~LV2PluginUI ()
{ {
if (_values) { delete [] _values;
delete[] _values;
}
_message_update_connection.disconnect(); _message_update_connection.disconnect();
_screen_update_connection.disconnect(); _screen_update_connection.disconnect();

View File

@ -26,6 +26,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <set>
#include <vector> #include <vector>
#include <gtkmm/widget.h> #include <gtkmm/widget.h>
@ -64,7 +65,7 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
private: private:
void parameter_changed (uint32_t, float); void control_changed (uint32_t);
typedef boost::shared_ptr<ARDOUR::AutomationControl> ControllableRef; typedef boost::shared_ptr<ARDOUR::AutomationControl> ControllableRef;
@ -85,6 +86,8 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
LV2_Feature _parent_feature; LV2_Feature _parent_feature;
Gtk::Window* _win_ptr; Gtk::Window* _win_ptr;
void* _inst; void* _inst;
typedef std::set<uint32_t> Updates;
Updates _updates;
static void on_external_ui_closed(void* controller); static void on_external_ui_closed(void* controller);

View File

@ -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->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->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->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()); insert->AutomationStateChanged.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::automation_state_changed, this), gui_context());
@ -813,12 +813,6 @@ PlugUIBase::update_preset_modified ()
} }
} }
void
PlugUIBase::parameter_changed (uint32_t, float)
{
update_preset_modified ();
}
void void
PlugUIBase::preset_added_or_removed () PlugUIBase::preset_added_or_removed ()
{ {

View File

@ -170,7 +170,6 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p); void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
void plugin_going_away (); void plugin_going_away ();
void automation_state_changed (); void automation_state_changed ();
virtual void parameter_changed (uint32_t, float);
void preset_added_or_removed (); void preset_added_or_removed ();
void update_preset_modified (); void update_preset_modified ();