// Currently this never triggers because the in_map for "Split" triggeres no_inplace.
if (_match.method == Split && !_no_inplace) {
assert (in_map.size () == 1);
- in_map[0] = ChanMapping (max (natural_input_streams (), _configured_in));
+ in_map[0] = ChanMapping (ChanCount::max (natural_input_streams (), _configured_in));
ChanCount const in_streams = internal_input_streams ();
/* copy the first stream's audio buffer contents to the others */
bool valid;
#ifdef MIXBUS
if (_plugins.front()->is_channelstrip() ) {
if (_configured_in.n_audio() > 0) {
- ChanMapping mb_in_map (min (_configured_in, ChanCount (DataType::AUDIO, 2)));
- ChanMapping mb_out_map (min (_configured_out, ChanCount (DataType::AUDIO, 2)));
+ ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
+ ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
_plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
- for (uint32_t out = _configured_in.n_audio; out < bufs.count().get (DataType::AUDIO); ++out) {
+ for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
bufs.get (DataType::AUDIO, out).silence (nframes, offset);
}
}
/* all instances have completed, now clear outputs that have not been written to.
* (except midi bypass)
*/
- if (bufs.count().n_midi() == 1 && natural_output_streams().get(DataType::MIDI) == 0) {
+ if (has_midi_bypass ()) {
used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
}
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
bool mapped = false;
+ if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
+ mapped = true; // in-place Midi bypass
+ }
for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
bool valid;
}
}
+ChanMapping
+PluginInsert::input_map () const
+{
+ ChanMapping rv;
+ uint32_t pc = 0;
+ for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
+ ChanMapping m (i->second);
+ const ChanMapping::Mappings& mp ((*i).second.mappings());
+ for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+ for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+ rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
+ }
+ }
+ }
+ return rv;
+}
+
+ChanMapping
+PluginInsert::output_map () const
+{
+ ChanMapping rv;
+ uint32_t pc = 0;
+ for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
+ ChanMapping m (i->second);
+ const ChanMapping::Mappings& mp ((*i).second.mappings());
+ for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+ for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+ rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
+ }
+ }
+ }
+ if (has_midi_bypass ()) {
+ rv.set (DataType::MIDI, 0, 0);
+ }
+
+ return rv;
+}
+
+bool
+PluginInsert::has_midi_bypass () const
+{
+ if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1 && natural_output_streams ().n_midi () == 0) {
+ return true;
+ }
+ return false;
+}
+
bool
PluginInsert::configure_io (ChanCount in, ChanCount out)
{
/* get plugin configuration */
_match = private_can_support_io_configuration (in, out);
+#ifndef NDEBUG // XXX
+ cout << "Match '" << name() << "': " << _match;
+#endif
/* set the matching method and number of plugins that we will use to meet this configuration */
if (set_count (_match.plugins) == false) {
}
}
} else {
- _in_map[pc] = ChanMapping (min (natural_input_streams (), in));
+ _in_map[pc] = ChanMapping (ChanCount::min (natural_input_streams (), in));
}
- _out_map[pc] = ChanMapping (min (natural_output_streams(), out));
+ _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), out));
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
_in_map[pc].offset_to(*t, pc * natural_input_streams().get(*t));
if (mapping_changed) {
PluginMapChanged (); /* EMIT SIGNAL */
-#ifndef NDEBUG
+#ifndef NDEBUG // XXX
uint32_t pc = 0;
cout << "----<<----\n";
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
return Match (ExactMatch, get_count(), false, true); // XXX
}
- /* try automatic configuration next */
+ /* try automatic configuration */
Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
-
PluginInfoPtr info = _plugins.front()->get_info();
ChanCount inputs = info->n_inputs;
ChanCount outputs = info->n_outputs;
ChanCount midi_bypass;
+ if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
+ midi_bypass.set (DataType::MIDI, 1);
+ }
/* handle case strict-i/o */
if (_strict_io && m.method != Impossible) {
// output = midi-bypass + at most master-out channels.
ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
max_out.set (DataType::MIDI, out.get(DataType::MIDI));
- out = min (out, max_out);
+ out = ChanCount::min (out, max_out);
return m;
}
switch (m.method) {
case NoInputs:
- if (inx != out) {
+ if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
/* replicate processor to match output count (generators and such)
* at least enough to feed every output port. */
uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
if (nin == 0 || inx.get(*t) == 0) { continue; }
f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
}
- out = inx;
+ out = inx + midi_bypass;
return Match (Replicate, f);
}
break;
default:
break;
}
- if (inx == out) { return m; }
- out = inx;
+ out = inx + midi_bypass;
if (inx.get(DataType::MIDI) == 1
&& out.get (DataType::MIDI) == 0
&& outputs.get(DataType::MIDI) == 0) {
f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
}
if (f > 0 && outputs * f >= _configured_out) {
- out = outputs * f;
+ out = outputs * f + midi_bypass;
return Match (Replicate, f);
}
if (nin == 0 || inx.get(*t) == 0) { continue; }
f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
}
- out = outputs * f;
+ out = outputs * f + midi_bypass;
return Match (Replicate, f);
}
if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
- midi_bypass.set(DataType::MIDI, 1);
+ midi_bypass.set (DataType::MIDI, 1);
}
if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
}
}
- if (can_replicate) {
+ if (can_replicate && f > 0) {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
out.set (*t, outputs.get(*t) * f);
}
return Match (Hide, 1, false, false, hide_channels);
}
- midi_bypass.reset();
return Match (Impossible, 0);
}
ac->stop_touch (true, session().audible_frame());
}
}
+
+std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
+{
+ switch (m.method) {
+ case PluginInsert::Impossible: o << "Impossible"; break;
+ case PluginInsert::Delegate: o << "Delegate"; break;
+ case PluginInsert::NoInputs: o << "NoInputs"; break;
+ case PluginInsert::ExactMatch: o << "ExactMatch"; break;
+ case PluginInsert::Replicate: o << "Replicate"; break;
+ case PluginInsert::Split: o << "Split"; break;
+ case PluginInsert::Hide: o << "Hide"; break;
+ }
+ o << " cnt: " << m.plugins
+ << (m.strict_io ? " strict-io" : "")
+ << (m.custom_cfg ? " custom-cfg" : "");
+ if (m.method == PluginInsert::Hide) {
+ o << " hide: " << m.hide;
+ }
+ o << "\n";
+ return o;
+}