deactivate plugin if connect_and_run returns an error
[ardour.git] / libs / ardour / plugin_insert.cc
index b56419096e3bd63f6af5bc7daf5b171a37a32c29..96b8570d8c1c10f32a589d829f88c6660a23290c 100644 (file)
@@ -439,7 +439,9 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
        }
 
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
-               (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
+               if ((*i)->connect_and_run(bufs, in_map, out_map, nframes, offset)) {
+                       deactivate ();
+               }
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
                        in_map.offset_to(*t, natural_input_streams().get(*t));
                        out_map.offset_to(*t, natural_output_streams().get(*t));
@@ -660,7 +662,7 @@ PluginInsert::reset_parameters_to_default ()
                        continue;
                }
 
-               ac->set_value (dflt);
+               ac->set_value (dflt, Controllable::NoGroup);
        }
        return all;
 }
@@ -976,8 +978,20 @@ PluginInsert::set_control_ids (const XMLNode& node, int version)
                if ((*iter)->name() == Controllable::xml_node_name) {
                        const XMLProperty* prop;
 
-                       if ((prop = (*iter)->property (X_("parameter"))) != 0) {
-                               uint32_t p = atoi (prop->value());
+                       uint32_t p = (uint32_t)-1;
+#ifdef LV2_SUPPORT
+                       if ((prop = (*iter)->property (X_("symbol"))) != 0) {
+                               boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
+                               if (lv2plugin) {
+                                       p = lv2plugin->port_index(prop->value().c_str());
+                               }
+                       }
+#endif
+                       if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
+                               p = atoi (prop->value());
+                       }
+
+                       if (p != (uint32_t)-1) {
 
                                /* this may create the new controllable */
 
@@ -1113,19 +1127,14 @@ PluginInsert::set_state(const XMLNode& node, int version)
                }
        }
 
-       PBD::ID this_id =  this->id();
+       Processor::set_state (node, version);
 
-       if (regenerate_xml_or_string_ids ()) {
-               /* when duplicating a track, we need to use the
-                * original ID for loading plugin state (from file)
-                */
-               const XMLProperty* prop;
-               if ((prop = node.property ("id")) != 0) {
-                       plugin->set_insert_id (prop->value ());
-               }
-       }
+       PBD::ID new_id = this->id();
+       PBD::ID old_id = this->id();
 
-       Processor::set_state (node, version);
+       if ((prop = node.property ("id")) != 0) {
+               old_id = prop->value ();
+       }
 
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
 
@@ -1136,12 +1145,26 @@ PluginInsert::set_state(const XMLNode& node, int version)
                if ((*niter)->name() == plugin->state_node_name()) {
 
                        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+                               /* Plugin state can include external files which are named after the ID.
+                                *
+                                * If regenerate_xml_or_string_ids() is set, the ID will already have
+                                * been changed, so we need to use the old ID from the XML to load the
+                                * state and then update the ID.
+                                *
+                                * When copying a plugin-state, route_ui takes care of of updating the ID,
+                                * but we need to call set_insert_id() to clear the cached plugin-state
+                                * and force a change.
+                                */
                                if (!regenerate_xml_or_string_ids ()) {
-                                       (*i)->set_insert_id (this->id());
+                                       (*i)->set_insert_id (new_id);
+                               } else {
+                                       (*i)->set_insert_id (old_id);
                                }
+
                                (*i)->set_state (**niter, version);
+
                                if (regenerate_xml_or_string_ids ()) {
-                                       (*i)->set_insert_id (this_id);
+                                       (*i)->set_insert_id (new_id);
                                }
                        }
 
@@ -1149,10 +1172,6 @@ PluginInsert::set_state(const XMLNode& node, int version)
                }
        }
 
-       if (regenerate_xml_or_string_ids ()) {
-                       plugin->set_insert_id (this_id);
-       }
-
        if (version < 3000) {
 
                /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
@@ -1190,6 +1209,13 @@ PluginInsert::update_id (PBD::ID id)
        }
 }
 
+void
+PluginInsert::set_state_dir (const std::string& d)
+{
+       // state() only saves the state of the first plugin
+       _plugins[0]->set_state_dir (d);
+}
+
 void
 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
 {
@@ -1325,15 +1351,21 @@ PluginInsert::PluginControl::PluginControl (PluginInsert*                     p,
 
 /** @param val `user' value */
 void
-PluginInsert::PluginControl::set_value (double user_val)
+PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
 {
        if (writable()) {
-               set_value_unchecked (user_val);
+               _set_value (user_val, group_override);
        }
 }
-
 void
 PluginInsert::PluginControl::set_value_unchecked (double user_val)
+{
+       /* used only by automation playback */
+       _set_value (user_val, Controllable::NoGroup);
+}
+
+void
+PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
 {
        /* FIXME: probably should be taking out some lock here.. */
 
@@ -1346,13 +1378,13 @@ PluginInsert::PluginControl::set_value_unchecked (double user_val)
                iasp->set_parameter (_list->parameter().id(), user_val);
        }
 
-       AutomationControl::set_value (user_val);
+       AutomationControl::set_value (user_val, group_override);
 }
 
 void
 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
 {
-       AutomationControl::set_value (user_val);
+       AutomationControl::set_value (user_val, Controllable::NoGroup);
 }
 
 XMLNode&
@@ -1363,6 +1395,12 @@ PluginInsert::PluginControl::get_state ()
        XMLNode& node (AutomationControl::get_state());
        ss << parameter().id();
        node.add_property (X_("parameter"), ss.str());
+#ifdef LV2_SUPPORT
+       boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
+       if (lv2plugin) {
+               node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
+       }
+#endif
 
        return node;
 }
@@ -1398,7 +1436,7 @@ PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert*
 }
 
 void
-PluginInsert::PluginPropertyControl::set_value (double user_val)
+PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
 {
        if (writable()) {
                set_value_unchecked (user_val);
@@ -1422,7 +1460,7 @@ PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
        }
 
        _value = value;
-       AutomationControl::set_value(user_val);
+       AutomationControl::set_value (user_val, Controllable::NoGroup);
 }
 
 XMLNode&