LV2: fix port/nth-parameter confusion
various LV2 callbacks from plugin DSP/GUI use raw port_index,
not nth_parameter. This lead to incorrectly queued updates
(_values_last_sent_to_ui) and since 7dac8994f6
to
potential crashes (invalid _controllables[idx]).
This commit is contained in:
parent
eac3283b49
commit
190cd657b9
@ -70,7 +70,6 @@ LV2PluginUI::write_from_ui(void* controller,
|
|||||||
|
|
||||||
std::shared_ptr<AutomationControl> ac = me->_controllables[port_index];
|
std::shared_ptr<AutomationControl> ac = me->_controllables[port_index];
|
||||||
|
|
||||||
|
|
||||||
if (ac) {
|
if (ac) {
|
||||||
me->_updates.insert (port_index);
|
me->_updates.insert (port_index);
|
||||||
ac->set_value(*(const float*)buffer, Controllable::NoGroup);
|
ac->set_value(*(const float*)buffer, Controllable::NoGroup);
|
||||||
@ -239,10 +238,8 @@ LV2PluginUI::queue_port_update()
|
|||||||
{
|
{
|
||||||
const uint32_t num_ports = _lv2->num_ports();
|
const uint32_t num_ports = _lv2->num_ports();
|
||||||
for (uint32_t i = 0; i < num_ports; ++i) {
|
for (uint32_t i = 0; i < num_ports; ++i) {
|
||||||
bool ok;
|
if (_lv2->parameter_is_control (i) && _lv2->parameter_is_input(i)) {
|
||||||
uint32_t port = _lv2->nth_parameter(i, ok);
|
_updates.insert (i);
|
||||||
if (ok && _lv2->parameter_is_input (i)) {
|
|
||||||
_updates.insert (port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,9 +271,7 @@ LV2PluginUI::output_update()
|
|||||||
|
|
||||||
/* output ports (values set by DSP) need propagating to GUI */
|
/* output ports (values set by DSP) need propagating to GUI */
|
||||||
|
|
||||||
uint32_t nports = _output_ports.size();
|
for (auto const& index: _output_ports) {
|
||||||
for (uint32_t i = 0; i < nports; ++i) {
|
|
||||||
uint32_t index = _output_ports[i];
|
|
||||||
float val = _pib->control_output (index)->get_parameter ();
|
float val = _pib->control_output (index)->get_parameter ();
|
||||||
|
|
||||||
if (val != _values_last_sent_to_ui[index]) {
|
if (val != _values_last_sent_to_ui[index]) {
|
||||||
@ -288,14 +283,14 @@ LV2PluginUI::output_update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Input ports marked for update because the control value changed
|
/* Input ports marked for update because the control value changed
|
||||||
since the last redisplay.
|
* since the last redisplay.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (Updates::iterator i = _updates.begin(); i != _updates.end(); ++i) {
|
for (auto const& i : _updates) {
|
||||||
float val = _controllables[*i]->get_value ();
|
float val = _controllables[i]->get_value ();
|
||||||
/* push current value to the GUI */
|
/* push current value to the GUI */
|
||||||
suil_instance_port_event ((SuilInstance*)_inst, (*i), 4, 0, &val);
|
suil_instance_port_event ((SuilInstance*)_inst, i, 4, 0, &val);
|
||||||
_values_last_sent_to_ui[(*i)] = val;
|
_values_last_sent_to_ui[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updates.clear ();
|
_updates.clear ();
|
||||||
@ -436,15 +431,6 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
|
|||||||
|
|
||||||
#define GET_WIDGET(inst) suil_instance_get_widget((SuilInstance*)inst);
|
#define GET_WIDGET(inst) suil_instance_get_widget((SuilInstance*)inst);
|
||||||
|
|
||||||
const uint32_t num_ports = _lv2->num_ports();
|
|
||||||
for (uint32_t i = 0; i < num_ports; ++i) {
|
|
||||||
if (_lv2->parameter_is_output(i)
|
|
||||||
&& _lv2->parameter_is_control(i)
|
|
||||||
&& is_update_wanted(i)) {
|
|
||||||
_output_ports.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_external_ui_ptr = NULL;
|
_external_ui_ptr = NULL;
|
||||||
if (!is_external_ui) {
|
if (!is_external_ui) {
|
||||||
GtkWidget* c_widget = (GtkWidget*)GET_WIDGET(_inst);
|
GtkWidget* c_widget = (GtkWidget*)GET_WIDGET(_inst);
|
||||||
@ -465,28 +451,30 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
|
|||||||
_external_ui_ptr = (struct lv2_external_ui*)GET_WIDGET(_inst);
|
_external_ui_ptr = (struct lv2_external_ui*)GET_WIDGET(_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t num_ports = _lv2->num_ports();
|
||||||
|
|
||||||
_values_last_sent_to_ui = new float[num_ports];
|
_values_last_sent_to_ui = new float[num_ports];
|
||||||
_controllables.resize(num_ports);
|
_controllables.resize(num_ports);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_ports; ++i) {
|
for (uint32_t i = 0; i < num_ports; ++i) {
|
||||||
bool ok;
|
if (!_lv2->parameter_is_control (i)) {
|
||||||
uint32_t port = _lv2->nth_parameter(i, ok);
|
continue;
|
||||||
if (ok) {
|
}
|
||||||
/* Cache initial value of the parameter, regardless of
|
|
||||||
whether it is input or output
|
|
||||||
*/
|
|
||||||
|
|
||||||
_values_last_sent_to_ui[port] = _lv2->get_parameter(port);
|
/* Cache initial value of the parameter, regardless of whether it is input or output */
|
||||||
_controllables[port] = std::dynamic_pointer_cast<ARDOUR::AutomationControl> (
|
|
||||||
_pib->control(Evoral::Parameter(PluginAutomation, 0, port)));
|
|
||||||
|
|
||||||
if (_lv2->parameter_is_control(port) && _lv2->parameter_is_input(port)) {
|
_values_last_sent_to_ui[i] = _lv2->get_parameter(i);
|
||||||
if (_controllables[port]) {
|
_controllables[i] = std::dynamic_pointer_cast<ARDOUR::AutomationControl> (_pib->control(Evoral::Parameter(PluginAutomation, 0, i)));
|
||||||
_controllables[port]->Changed.connect (control_connections, invalidator (*this), boost::bind (&LV2PluginUI::control_changed, this, port), gui_context());
|
|
||||||
/* queue for first update ("push") to GUI */
|
if (_lv2->parameter_is_input(i)) {
|
||||||
_updates.insert (port);
|
assert (_controllables[i]);
|
||||||
}
|
_controllables[i]->Changed.connect (control_connections, invalidator (*this), boost::bind (&LV2PluginUI::control_changed, this, i), gui_context());
|
||||||
}
|
/* queue for first update ("push") to GUI */
|
||||||
|
_updates.insert (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lv2->parameter_is_output(i) && is_update_wanted(i)) {
|
||||||
|
_output_ports.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ private:
|
|||||||
|
|
||||||
std::shared_ptr<ARDOUR::PlugInsertBase> _pib;
|
std::shared_ptr<ARDOUR::PlugInsertBase> _pib;
|
||||||
std::shared_ptr<ARDOUR::LV2Plugin> _lv2;
|
std::shared_ptr<ARDOUR::LV2Plugin> _lv2;
|
||||||
std::vector<int> _output_ports;
|
std::vector<uint32_t> _output_ports;
|
||||||
sigc::connection _screen_update_connection;
|
sigc::connection _screen_update_connection;
|
||||||
sigc::connection _message_update_connection;
|
sigc::connection _message_update_connection;
|
||||||
Gtk::Widget* _gui_widget;
|
Gtk::Widget* _gui_widget;
|
||||||
|
Loading…
Reference in New Issue
Block a user