Delegated plugin configuration is now always successful.. except
..in case of outright errors (e.g. data format mismatch) or non-implemented edge-cases e.g. midi generators (no audio in, no midi in, no audio-out) or control-data filters (only control ports).
This commit is contained in:
parent
81a9446533
commit
d73df3d990
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user