summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/plugin_insert.h2
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h2
-rw-r--r--libs/ardour/ardour/route.h9
-rw-r--r--libs/ardour/plugin_insert.cc14
-rw-r--r--libs/ardour/route.cc67
5 files changed, 94 insertions, 0 deletions
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index db052f0f0d..4b5f38964a 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -93,6 +93,8 @@ class LIBARDOUR_API PluginInsert : public Processor
return _thru_map;
}
+ bool pre_seed (const ChanCount&, const ChanCount&, const ChanMapping&, const ChanMapping&, const ChanMapping&);
+
ChanMapping input_map () const; ///< combined (all instances) input map
ChanMapping output_map () const; ///< combined (all instances) output map
bool has_midi_bypass () const;
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index d0b9ca457f..4bd89e2514 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -239,6 +239,8 @@ CONFIG_VARIABLE (bool, discover_vst_on_start, "discover-vst-on-start", false)
CONFIG_VARIABLE (bool, verbose_plugin_scan, "verbose-plugin-scan", true)
CONFIG_VARIABLE (int, vst_scan_timeout, "vst-scan-timeout", 600) /* deciseconds, per plugin, <= 0 no timeout */
CONFIG_VARIABLE (bool, discover_audio_units, "discover-audio-units", false)
+CONFIG_VARIABLE (bool, ask_replace_instrument, "ask-replace-instrument", true)
+CONFIG_VARIABLE (bool, ask_setup_instrument, "ask-setup-instrument", true)
/* custom user plugin paths */
CONFIG_VARIABLE (std::string, plugin_path_vst, "plugin-path-vst", "@default@")
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 3c06018e1b..3ade22319d 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -64,6 +64,7 @@ class Panner;
class PannerShell;
class PortSet;
class Processor;
+class PluginInsert;
class RouteGroup;
class Send;
class InternalReturn;
@@ -372,6 +373,14 @@ public:
PropertyChanged (ARDOUR::Properties::name);
}
+ enum PluginSetupOptions {
+ None = 0x0,
+ CanReplace = 0x1,
+ MultiOut = 0x2,
+ };
+
+ static PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, PluginSetupOptions > PluginSetup;
+
/** the processors have changed; the parameter indicates what changed */
PBD::Signal1<void,RouteProcessorChange> processors_changed;
PBD::Signal1<void,void*> record_enable_changed;
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index f6f620e883..a72412a868 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -1192,6 +1192,20 @@ PluginInsert::set_thru_map (ChanMapping m) {
}
}
+bool
+PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
+ const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
+{
+ if (_configured) { return false; }
+ _configured_in = in;
+ _configured_out = out;
+ _in_map[0] = im;
+ _out_map[0] = om;
+ _thru_map = tm;
+ _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
+ return true;
+}
+
ChanMapping
PluginInsert::input_map () const
{
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 8a98149fa0..3442d0ec8a 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -78,6 +78,7 @@ using namespace PBD;
PBD::Signal0<void> Route::SyncOrderKeys;
PBD::Signal0<void> Route::RemoteControlIDChange;
+PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, Route::PluginSetupOptions > Route::PluginSetup;
/** Base class for all routable/mixable objects (tracks and busses) */
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
@@ -1369,6 +1370,15 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
}
}
+
+inline Route::PluginSetupOptions operator|= (Route::PluginSetupOptions& a, const Route::PluginSetupOptions& b) {
+ return a = static_cast<Route::PluginSetupOptions> (static_cast <int>(a) | static_cast<int> (b));
+}
+
+inline Route::PluginSetupOptions operator&= (Route::PluginSetupOptions& a, const Route::PluginSetupOptions& b) {
+ return a = static_cast<Route::PluginSetupOptions> (static_cast <int>(a) & static_cast<int> (b));
+}
+
int
Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
{
@@ -1392,6 +1402,59 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
return 0;
}
+ ProcessorList to_skip;
+
+ // check if there's an instrument to replace or configure
+ for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
+ boost::shared_ptr<PluginInsert> pi;
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) == 0) {
+ continue;
+ }
+ if (!pi->plugin ()->get_info ()->is_instrument ()) {
+ continue;
+ }
+ boost::shared_ptr<Processor> instrument = the_instrument ();
+ ChanCount in (DataType::MIDI, 1);
+ ChanCount out (DataType::AUDIO, 2); // XXX route's out?!
+
+ PluginSetupOptions flags = None;
+ if (instrument) {
+ flags |= CanReplace;
+ in = instrument->input_streams ();
+ out = instrument->output_streams ();
+ }
+ if (pi->has_output_presets (in, out)) {
+ flags |= MultiOut;
+ }
+
+ pi->set_strict_io (_strict_io);
+
+ PluginSetupOptions mask = None;
+ if (Config->get_ask_replace_instrument ()) {
+ mask |= CanReplace;
+ }
+ if (Config->get_ask_setup_instrument ()) {
+ mask |= MultiOut;
+ }
+
+ flags &= mask;
+
+ if (flags != None) {
+ boost::optional<int> rv = PluginSetup (shared_from_this (), pi, flags); /* EMIT SIGNAL */
+ switch (rv.get_value_or (0)) {
+ case 1:
+ to_skip.push_back (*i); // don't add this one;
+ break;
+ case 2:
+ replace_processor (instrument, *i, err);
+ to_skip.push_back (*i);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
{
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
@@ -1402,6 +1465,10 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
if (*i == _meter) {
continue;
}
+ ProcessorList::iterator check = find (to_skip.begin(), to_skip.end(), *i);
+ if (check != to_skip.end()) {
+ continue;
+ }
boost::shared_ptr<PluginInsert> pi;