mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-22 14:46:34 +01:00
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
6 changed files with 124 additions and 66 deletions
|
|
@ -103,7 +103,7 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
|
||||||
|
|
||||||
bool has_editor () const;
|
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 output_streams() const;
|
||||||
ChanCount input_streams() const;
|
ChanCount input_streams() const;
|
||||||
bool configure_io (ChanCount in, ChanCount out);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ public:
|
||||||
bool load_preset (PresetRecord) { return false; }
|
bool load_preset (PresetRecord) { return false; }
|
||||||
bool has_editor() const { 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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
ChanCount output_streams() const { return _configured_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
|
/* specific types of plugins can overload this. As of September 2008, only
|
||||||
AUPlugin does this.
|
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 output_streams() const;
|
||||||
virtual ChanCount input_streams() const;
|
virtual ChanCount input_streams() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1129,21 +1129,18 @@ AUPlugin::output_streams() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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.
|
// 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;
|
int32_t audio_out;
|
||||||
bool found = false;
|
|
||||||
AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
|
AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
|
||||||
|
|
||||||
/* lets check MIDI first */
|
/* lets check MIDI first */
|
||||||
|
|
||||||
if (in.n_midi() > 0) {
|
if (in.n_midi() > 0 && !_has_midi_input && !imprecise) {
|
||||||
if (!_has_midi_input) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
|
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::MIDI, 0);
|
||||||
out.set (DataType::AUDIO, audio_out);
|
out.set (DataType::AUDIO, audio_out);
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now allow potentially "imprecise" matches */
|
/* now allow potentially "imprecise" matches */
|
||||||
|
|
||||||
audio_out = -1;
|
audio_out = -1;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
|
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) {
|
if (possible_in == 0) {
|
||||||
|
/* no inputs, generators & instruments */
|
||||||
/* instrument plugin, always legal but throws away inputs ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (possible_out == -1) {
|
if (possible_out == -1) {
|
||||||
/* any configuration possible, provide stereo output */
|
/* any configuration possible, provide stereo output */
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out == -2) {
|
} else if (possible_out == -2) {
|
||||||
/* plugins shouldn't really use (0,-2) but might.
|
/* invalid, should be (0, -1) */
|
||||||
any configuration possible, provide stereo output
|
|
||||||
*/
|
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out < -2) {
|
} else if (possible_out < -2) {
|
||||||
/* explicitly variable number of outputs.
|
/* 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.
|
|
||||||
*/
|
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1253,11 +1241,9 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (possible_in == -1) {
|
if (possible_in == -1) {
|
||||||
|
|
||||||
/* wildcard for input */
|
/* wildcard for input */
|
||||||
|
|
||||||
if (possible_out == -1) {
|
if (possible_out == -1) {
|
||||||
/* out much match in */
|
/* out must match in */
|
||||||
audio_out = audio_in;
|
audio_out = audio_in;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out == -2) {
|
} 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_in == -2) {
|
||||||
|
|
||||||
if (possible_out == -1) {
|
if (possible_out == -1) {
|
||||||
/* any configuration possible, pick matching */
|
/* any configuration possible, pick matching */
|
||||||
audio_out = audio_in;
|
audio_out = audio_in;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out == -2) {
|
} else if (possible_out == -2) {
|
||||||
/* plugins shouldn't really use (-2,-2) but might.
|
/* invalid. interpret as (-1, -1) */
|
||||||
interpret as (-1,-1).
|
|
||||||
*/
|
|
||||||
audio_out = audio_in;
|
audio_out = audio_in;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out < -2) {
|
} else if (possible_out < -2) {
|
||||||
|
|
@ -1299,30 +1282,24 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (possible_in < -2) {
|
if (possible_in < -2) {
|
||||||
|
|
||||||
/* explicit variable number of inputs */
|
/* explicit variable number of inputs */
|
||||||
|
if (audio_in > -possible_in && imprecise != NULL) {
|
||||||
if (audio_in > -possible_in) {
|
// hide inputs ports
|
||||||
/* request is too large */
|
imprecise->set (DataType::AUDIO, -possible_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (audio_in > -possible_in && imprecise == NULL) {
|
||||||
if (possible_out == -1) {
|
/* request is too large */
|
||||||
|
} else if (possible_out == -1) {
|
||||||
/* any output configuration possible, provide stereo out */
|
/* any output configuration possible, provide stereo out */
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out == -2) {
|
} else if (possible_out == -2) {
|
||||||
/* plugins shouldn't really use (<-2,-2) but might.
|
/* invalid. interpret as (<-2, -1) */
|
||||||
interpret as (<-2,-1): any configuration possible, provide stereo output
|
|
||||||
*/
|
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out < -2) {
|
} else if (possible_out < -2) {
|
||||||
/* explicitly variable number of outputs.
|
/* explicitly variable number of outputs, pick stereo */
|
||||||
*
|
|
||||||
* We really need to ask the user in this case.
|
|
||||||
* stereo will be correct in 99.9% of all cases.
|
|
||||||
*/
|
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1333,9 +1310,7 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (possible_in && (possible_in == audio_in)) {
|
if (possible_in && (possible_in == audio_in)) {
|
||||||
|
|
||||||
/* exact number of inputs ... must match obviously */
|
/* exact number of inputs ... must match obviously */
|
||||||
|
|
||||||
if (possible_out == -1) {
|
if (possible_out == -1) {
|
||||||
/* any output configuration possible, provide stereo output */
|
/* any output configuration possible, provide stereo output */
|
||||||
audio_out = 2;
|
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) {
|
if (found) {
|
||||||
out.set (DataType::MIDI, 0); /// XXX
|
out.set (DataType::MIDI, 0); /// XXX
|
||||||
|
|
|
||||||
|
|
@ -305,9 +305,11 @@ LuaProc::load_script ()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,8 +346,9 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t audio_in = in.n_audio ();
|
const int32_t audio_in = in.n_audio ();
|
||||||
int32_t audio_out;
|
int32_t audio_out;
|
||||||
|
int32_t midi_out = 0; // TODO handle _has_midi_output
|
||||||
|
|
||||||
if (in.n_midi() > 0 && audio_in == 0) {
|
if (in.n_midi() > 0 && audio_in == 0) {
|
||||||
audio_out = 2; // prefer stereo version if available.
|
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;
|
audio_out = audio_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
|
for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
|
||||||
assert (i.value ().type () == LUA_TTABLE);
|
assert (i.value ().type () == LUA_TTABLE);
|
||||||
luabridge::LuaRef io (i.value ());
|
luabridge::LuaRef io (i.value ());
|
||||||
|
|
@ -406,7 +410,7 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
if (possible_in == -1) {
|
if (possible_in == -1) {
|
||||||
/* wildcard for input */
|
/* wildcard for input */
|
||||||
if (possible_out == -1) {
|
if (possible_out == -1) {
|
||||||
/* out much match in */
|
/* out must match in */
|
||||||
audio_out = audio_in;
|
audio_out = audio_in;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (possible_out == -2) {
|
} else if (possible_out == -2) {
|
||||||
|
|
@ -447,10 +451,14 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
|
|
||||||
if (possible_in < -2) {
|
if (possible_in < -2) {
|
||||||
/* explicit variable number of inputs */
|
/* explicit variable number of inputs */
|
||||||
if (audio_in > -possible_in) {
|
if (audio_in > -possible_in && imprecise != NULL) {
|
||||||
/* request is too large */
|
// 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 */
|
/* any output configuration possible, provide stereo out */
|
||||||
audio_out = 2;
|
audio_out = 2;
|
||||||
found = true;
|
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) {
|
if (!found) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.set (DataType::MIDI, 0);
|
out.set (DataType::MIDI, midi_out); // currently always zero
|
||||||
out.set (DataType::AUDIO, audio_out);
|
out.set (DataType::AUDIO, audio_out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -915,18 +915,22 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Delegate:
|
case Delegate:
|
||||||
if (_match.strict_io) {
|
{
|
||||||
ChanCount dout;
|
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);
|
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 */
|
PluginIoReConfigure (); /* EMIT SIGNAL */
|
||||||
_configured = false;
|
_configured = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// no break -- fall through
|
break;
|
||||||
default:
|
default:
|
||||||
if (_plugins.front()->configure_io (in, out) == false) {
|
if (_plugins.front()->configure_io (in, out) == false) {
|
||||||
PluginIoReConfigure (); /* EMIT SIGNAL */
|
PluginIoReConfigure (); /* EMIT SIGNAL */
|
||||||
|
|
@ -1003,7 +1007,7 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
|
||||||
|
|
||||||
if (mapping_changed) {
|
if (mapping_changed) {
|
||||||
PluginMapChanged (); /* EMIT SIGNAL */
|
PluginMapChanged (); /* EMIT SIGNAL */
|
||||||
#if 1
|
#ifndef NDEBUG
|
||||||
uint32_t pc = 0;
|
uint32_t pc = 0;
|
||||||
cout << "----<<----\n";
|
cout << "----<<----\n";
|
||||||
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
|
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()) {
|
if (info->reconfigurable_io()) {
|
||||||
// houston, we have a problem.
|
ChanCount useins;
|
||||||
// TODO: match closest closes available config.
|
bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
|
||||||
// also handle strict_io
|
if (!r) {
|
||||||
return Match (Impossible, 0);
|
// 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
|
// 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) {
|
if (!r) {
|
||||||
return Match (Impossible, 0);
|
return Match (Impossible, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Match (Delegate, 1);
|
return Match (Delegate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue