#include "ardour/debug.h"
#include "ardour/event_type_map.h"
#include "ardour/ladspa_plugin.h"
+#include "ardour/luaproc.h"
#include "ardour/plugin.h"
#include "ardour/plugin_insert.h"
can_automate (param);
boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
- add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
+ boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
+ add_control (c);
+ _plugins.front()->set_automation_control (i->id(), c);
} else if (i->type() == PluginPropertyAutomation) {
Evoral::Parameter param(*i);
const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
}
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));
return;
}
- if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
+ if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
/* no events have a time within the relevant range */
continue;
}
- ac->set_value (dflt);
+ ac->set_value (dflt, Controllable::NoGroup);
}
return all;
}
PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
{
boost::shared_ptr<LadspaPlugin> lp;
+ boost::shared_ptr<LuaProc> lua;
#ifdef LV2_SUPPORT
boost::shared_ptr<LV2Plugin> lv2p;
#endif
if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
+ } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new LuaProc (*lua));
#ifdef LV2_SUPPORT
} else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
+ _plugins[0]->set_insert_id(this->id());
node.add_child_nocopy (_plugins[0]->get_state());
for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
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 */
type = ARDOUR::LXVST;
} else if (prop->value() == X_("audiounit")) {
type = ARDOUR::AudioUnit;
+ } else if (prop->value() == X_("luaproc")) {
+ type = ARDOUR::Lua;
} else {
error << string_compose (_("unknown plugin type %1 in plugin insert state"),
prop->value())
return -1;
}
+ if (type == ARDOUR::Lua) {
+ XMLNode *ls = node.child (plugin->state_node_name().c_str());
+ // we need to load the script to set the name and parameters.
+ boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
+ if (ls && lp) {
+ lp->set_script_from_state (*ls);
+ }
+ }
+
// The name of the PluginInsert comes from the plugin, nothing else
_name = plugin->get_info()->name;
Processor::set_state (node, version);
+ PBD::ID new_id = this->id();
+ PBD::ID old_id = this->id();
+
+ if ((prop = node.property ("id")) != 0) {
+ old_id = prop->value ();
+ }
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
/* find the node with the type-specific node name ("lv2", "ladspa", etc)
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 (new_id);
+ } else {
+ (*i)->set_insert_id (old_id);
+ }
+
(*i)->set_state (**niter, version);
+
+ if (regenerate_xml_or_string_ids ()) {
+ (*i)->set_insert_id (new_id);
+ }
}
break;
}
}
+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)
{
/** @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.. */
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&
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;
}
}
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);
}
_value = value;
- AutomationControl::set_value(user_val);
+ AutomationControl::set_value (user_val, Controllable::NoGroup);
}
XMLNode&