summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/audio_unit.h2
-rw-r--r--libs/ardour/ardour/luaproc.h2
-rw-r--r--libs/ardour/ardour/plugin.h2
-rw-r--r--libs/ardour/audio_unit.cc95
-rw-r--r--libs/ardour/luaproc.cc61
-rw-r--r--libs/ardour/plugin_insert.cc28
6 files changed, 124 insertions, 66 deletions
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index e9a5622ea9..42e74b37da 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -103,7 +103,7 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
bool has_editor () const;
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise);
ChanCount output_streams() const;
ChanCount input_streams() const;
bool configure_io (ChanCount in, ChanCount out);
diff --git a/libs/ardour/ardour/luaproc.h b/libs/ardour/ardour/luaproc.h
index 1908ab8c33..0956bdf213 100644
--- a/libs/ardour/ardour/luaproc.h
+++ b/libs/ardour/ardour/luaproc.h
@@ -93,7 +93,7 @@ public:
bool load_preset (PresetRecord) { return false; }
bool has_editor() const { return false; }
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise);
bool configure_io (ChanCount in, ChanCount out);
ChanCount output_streams() const { return _configured_out; }
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 28bc7169da..65cb1f6c36 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -210,7 +210,7 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
/* specific types of plugins can overload this. As of September 2008, only
AUPlugin does this.
*/
- virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return false; }
+ virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/, ChanCount* imprecise = 0) { return false; }
virtual ChanCount output_streams() const;
virtual ChanCount input_streams() const;
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index bcc8c2c310..b08d122e7e 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -1129,21 +1129,18 @@ AUPlugin::output_streams() const
}
bool
-AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise)
{
// Note: We never attempt to multiply-instantiate plugins to meet io configurations.
- int32_t audio_in = in.n_audio();
+ const int32_t audio_in = in.n_audio();
int32_t audio_out;
- bool found = false;
AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
/* lets check MIDI first */
- if (in.n_midi() > 0) {
- if (!_has_midi_input) {
- return false;
- }
+ if (in.n_midi() > 0 && !_has_midi_input && !imprecise) {
+ return false;
}
vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
@@ -1201,13 +1198,13 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
out.set (DataType::MIDI, 0);
out.set (DataType::AUDIO, audio_out);
- return 1;
+ return true;
}
}
/* now allow potentially "imprecise" matches */
-
audio_out = -1;
+ bool found = false;
for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
@@ -1223,26 +1220,17 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
if (possible_in == 0) {
-
- /* instrument plugin, always legal but throws away inputs ...
- */
-
+ /* no inputs, generators & instruments */
if (possible_out == -1) {
/* any configuration possible, provide stereo output */
audio_out = 2;
found = true;
} else if (possible_out == -2) {
- /* plugins shouldn't really use (0,-2) but might.
- any configuration possible, provide stereo output
- */
+ /* invalid, should be (0, -1) */
audio_out = 2;
found = true;
} else if (possible_out < -2) {
- /* explicitly variable number of outputs.
- *
- * We really need to ask the user in this case.
- * stereo will be correct in 99.9% of all cases.
- */
+ /* explicitly variable number of outputs. */
audio_out = 2;
found = true;
} else {
@@ -1253,11 +1241,9 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
if (possible_in == -1) {
-
/* wildcard for input */
-
if (possible_out == -1) {
- /* out much match in */
+ /* out must match in */
audio_out = audio_in;
found = true;
} else if (possible_out == -2) {
@@ -1276,15 +1262,12 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
if (possible_in == -2) {
-
if (possible_out == -1) {
/* any configuration possible, pick matching */
audio_out = audio_in;
found = true;
} else if (possible_out == -2) {
- /* plugins shouldn't really use (-2,-2) but might.
- interpret as (-1,-1).
- */
+ /* invalid. interpret as (-1, -1) */
audio_out = audio_in;
found = true;
} else if (possible_out < -2) {
@@ -1299,30 +1282,24 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
if (possible_in < -2) {
-
/* explicit variable number of inputs */
-
- if (audio_in > -possible_in) {
- /* request is too large */
+ if (audio_in > -possible_in && imprecise != NULL) {
+ // hide inputs ports
+ imprecise->set (DataType::AUDIO, -possible_in);
}
-
- if (possible_out == -1) {
+ if (audio_in > -possible_in && imprecise == NULL) {
+ /* request is too large */
+ } else if (possible_out == -1) {
/* any output configuration possible, provide stereo out */
audio_out = 2;
found = true;
} else if (possible_out == -2) {
- /* plugins shouldn't really use (<-2,-2) but might.
- interpret as (<-2,-1): any configuration possible, provide stereo output
- */
+ /* invalid. interpret as (<-2, -1) */
audio_out = 2;
found = true;
} else if (possible_out < -2) {
- /* explicitly variable number of outputs.
- *
- * We really need to ask the user in this case.
- * stereo will be correct in 99.9% of all cases.
- */
+ /* explicitly variable number of outputs, pick stereo */
audio_out = 2;
found = true;
} else {
@@ -1333,9 +1310,7 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
if (possible_in && (possible_in == audio_in)) {
-
/* exact number of inputs ... must match obviously */
-
if (possible_out == -1) {
/* any output configuration possible, provide stereo output */
audio_out = 2;
@@ -1368,6 +1343,38 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
}
+ if (!found && imprecise) {
+ /* try harder */
+ for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
+ int possible_in = io["audio_in"];
+ int possible_out = io["audio_out"];
+
+ assert (possible_in > 0); // all other cases will have been matched above
+ assert (possible_out !=0 || possible_in !=0); // already handled above
+
+ imprecise->set (DataType::AUDIO, possible_in);
+ if (possible_out == -1 || possible_out == -2) {
+ audio_out = 2;
+ found = true;
+ } else if (possible_out < -2) {
+ /* explicitly variable number of outputs, pick maximum */
+ audio_out = -possible_out;
+ found = true;
+ } else {
+ /* exact number of outputs */
+ audio_out = possible_out;
+ found = true;
+ }
+
+ if (found) {
+ // ideally we'll keep iterating and take the "best match"
+ // whatever "best" means:
+ // least unconnected inputs, least silenced inputs,
+ // closest match of inputs == outputs
+ break;
+ }
+ }
+ }
if (found) {
out.set (DataType::MIDI, 0); /// XXX
diff --git a/libs/ardour/luaproc.cc b/libs/ardour/luaproc.cc
index 5c6df71999..71278a0658 100644
--- a/libs/ardour/luaproc.cc
+++ b/libs/ardour/luaproc.cc
@@ -305,9 +305,11 @@ LuaProc::load_script ()
}
bool
-LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
+LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise)
{
- if (in.n_midi() > 0 && !_has_midi_input) {
+ // caller must hold process lock (no concurrent calls to interpreter
+
+ if (in.n_midi() > 0 && !_has_midi_input && !imprecise) {
return false;
}
@@ -344,8 +346,9 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
return false;
}
- int32_t audio_in = in.n_audio ();
+ const int32_t audio_in = in.n_audio ();
int32_t audio_out;
+ int32_t midi_out = 0; // TODO handle _has_midi_output
if (in.n_midi() > 0 && audio_in == 0) {
audio_out = 2; // prefer stereo version if available.
@@ -353,6 +356,7 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
audio_out = audio_in;
}
+
for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
assert (i.value ().type () == LUA_TTABLE);
luabridge::LuaRef io (i.value ());
@@ -406,7 +410,7 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
if (possible_in == -1) {
/* wildcard for input */
if (possible_out == -1) {
- /* out much match in */
+ /* out must match in */
audio_out = audio_in;
found = true;
} else if (possible_out == -2) {
@@ -447,10 +451,14 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
if (possible_in < -2) {
/* explicit variable number of inputs */
- if (audio_in > -possible_in) {
- /* request is too large */
+ if (audio_in > -possible_in && imprecise != NULL) {
+ // hide inputs ports
+ imprecise->set (DataType::AUDIO, -possible_in);
}
- if (possible_out == -1) {
+
+ if (audio_in > -possible_in && imprecise == NULL) {
+ /* request is too large */
+ } else if (possible_out == -1) {
/* any output configuration possible, provide stereo out */
audio_out = 2;
found = true;
@@ -495,11 +503,48 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
}
}
+ if (!found && imprecise) {
+ /* try harder */
+ for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
+ assert (i.value ().type () == LUA_TTABLE);
+ luabridge::LuaRef io (i.value ());
+
+ int possible_in = io["audio_in"];
+ int possible_out = io["audio_out"];
+
+ assert (possible_in > 0); // all other cases will have been matched above
+ assert (possible_out !=0 || possible_in !=0); // already handled above
+
+ imprecise->set (DataType::AUDIO, possible_in);
+ if (possible_out == -1 || possible_out == -2) {
+ audio_out = 2;
+ found = true;
+ } else if (possible_out < -2) {
+ /* explicitly variable number of outputs, pick maximum */
+ audio_out = -possible_out;
+ found = true;
+ } else {
+ /* exact number of outputs */
+ audio_out = possible_out;
+ found = true;
+ }
+
+ if (found) {
+ // ideally we'll keep iterating and take the "best match"
+ // whatever "best" means:
+ // least unconnected inputs, least silenced inputs,
+ // closest match of inputs == outputs
+ break;
+ }
+ }
+ }
+
+
if (!found) {
return false;
}
- out.set (DataType::MIDI, 0);
+ out.set (DataType::MIDI, midi_out); // currently always zero
out.set (DataType::AUDIO, audio_out);
return true;
}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index fb6434e388..21debe1d80 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -915,18 +915,22 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
}
break;
case Delegate:
- if (_match.strict_io) {
+ {
ChanCount dout;
- bool const r = _plugins.front()->can_support_io_configuration (in, dout);
+ ChanCount useins;
+ bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
assert (r);
- if (_plugins.front()->configure_io (in, dout) == false) {
+ assert (_match.strict_io || dout.n_audio() == out.n_audio()); // sans midi bypass
+ if (useins.n_audio() == 0) {
+ useins = in;
+ }
+ if (_plugins.front()->configure_io (useins, dout) == false) {
PluginIoReConfigure (); /* EMIT SIGNAL */
_configured = false;
return false;
}
- break;
}
- // no break -- fall through
+ break;
default:
if (_plugins.front()->configure_io (in, out) == false) {
PluginIoReConfigure (); /* EMIT SIGNAL */
@@ -1003,7 +1007,7 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
if (mapping_changed) {
PluginMapChanged (); /* EMIT SIGNAL */
-#if 1
+#ifndef NDEBUG
uint32_t pc = 0;
cout << "----<<----\n";
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
@@ -1126,10 +1130,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
}
if (info->reconfigurable_io()) {
- // houston, we have a problem.
- // TODO: match closest closes available config.
- // also handle strict_io
- return Match (Impossible, 0);
+ ChanCount useins;
+ bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
+ if (!r) {
+ // houston, we have a problem.
+ return Match (Impossible, 0);
+ }
+ return Match (Delegate, 1);
}
// add at least as many plugins so that output count matches input count
@@ -1175,7 +1182,6 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha
if (!r) {
return Match (Impossible, 0);
}
-
return Match (Delegate, 1);
}