diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/chan_mapping.h | 39 | ||||
-rw-r--r-- | libs/ardour/ardour/plugin_insert.h | 18 | ||||
-rw-r--r-- | libs/ardour/chan_mapping.cc | 20 | ||||
-rw-r--r-- | libs/ardour/plugin_insert.cc | 74 | ||||
-rw-r--r-- | libs/ardour/route.cc | 1 |
5 files changed, 103 insertions, 49 deletions
diff --git a/libs/ardour/ardour/chan_mapping.h b/libs/ardour/ardour/chan_mapping.h index 730ecadc72..f73408baec 100644 --- a/libs/ardour/ardour/chan_mapping.h +++ b/libs/ardour/ardour/chan_mapping.h @@ -31,10 +31,11 @@ namespace ARDOUR { -/** A mapping from one set of channels to another - * (e.g. how to 'connect' two BufferSets). +/** A mapping from one set of channels to another. + * The general form is 1 source (from), many sinks (to). + * numeric IDs are used to identify sources and sinks. * - * for plugins the form is "pin" -> "buffer" + * for plugins this is used to map "plugin-pin" to "audio-buffer" */ class LIBARDOUR_API ChanMapping { public: @@ -44,15 +45,24 @@ public: uint32_t get(DataType t, uint32_t from, bool* valid) const; + /** reverse lookup + * @param type data type + * @param to pin + * @param valid pointer to a boolean. If not NULL it is set to true if the mapping is found, and false otherwise. + * @returns first "from" that matches given "to" + */ + uint32_t get_src(DataType t, uint32_t to, bool* valid) const; + /** get buffer mapping for given data type and pin * @param type data type - * @param from pin + * @param from numeric source id * @returns mapped buffer number (or ChanMapping::Invalid) */ - uint32_t get(DataType t, uint32_t from) const { return get (t, from, NULL); } + uint32_t get (DataType t, uint32_t from) const { return get (t, from, NULL); } + /** set buffer mapping for given data type * @param type data type - * @param from pin + * @param from numeric source id * @param to buffer */ void set(DataType t, uint32_t from, uint32_t to); @@ -61,7 +71,7 @@ public: /** remove mapping * @param type data type - * @param from source to remove from mapping + * @param from numeric source to remove from mapping */ void unset(DataType t, uint32_t from); @@ -76,7 +86,6 @@ public: */ bool is_monotonic () const; - /** Test if this mapping is a subset * @param superset to test against * @returns true if all mapping are also present in the superset @@ -97,20 +106,6 @@ public: return ! (*this == other); } - ChanMapping operator+=(const ChanMapping& other) { - const ChanMapping::Mappings& mp (other.mappings()); - for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) { - for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) { -#if 0 - bool valid; uint32_t x = get (tm->first, i->first, &valid); - assert (!valid || x == i->second); -#endif - set (tm->first, i->first, i->second); - } - } - return *this; - } - private: Mappings _mappings; }; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index d64ee8f31d..291dda4231 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -85,21 +85,9 @@ class LIBARDOUR_API PluginInsert : public Processor } } - ChanMapping input_map () const { - ChanMapping rv; - for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i) { - rv += i->second; - } - return rv; - } - - ChanMapping output_map () const { - ChanMapping rv; - for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i) { - rv += i->second; - } - return rv; - } + ChanMapping input_map () const; + ChanMapping output_map () const; + bool has_midi_bypass () const; void set_input_map (uint32_t, ChanMapping); void set_output_map (uint32_t, ChanMapping); diff --git a/libs/ardour/chan_mapping.cc b/libs/ardour/chan_mapping.cc index 0ca79af505..6386c2863b 100644 --- a/libs/ardour/chan_mapping.cc +++ b/libs/ardour/chan_mapping.cc @@ -67,6 +67,26 @@ ChanMapping::get(DataType t, uint32_t from, bool* valid) const return m->second; } +uint32_t +ChanMapping::get_src(DataType t, uint32_t to, bool* valid) const +{ + Mappings::const_iterator tm = _mappings.find(t); + if (tm == _mappings.end()) { + if (valid) { *valid = false; } + return -1; + } + for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) { + if (i->second == to) { + if (valid) { *valid = true; } + return i->first; + } + } + if (valid) { *valid = false; } + return -1; +} + + + void ChanMapping::set(DataType t, uint32_t from, uint32_t to) { diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 9d7276e732..08a3d8326f 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -567,7 +567,7 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of /* 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) { @@ -592,6 +592,9 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of 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; @@ -892,6 +895,53 @@ PluginInsert::set_output_map (uint32_t num, ChanMapping m) { } } +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) { @@ -1088,14 +1138,16 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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) { @@ -1112,7 +1164,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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. @@ -1121,7 +1173,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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; @@ -1130,9 +1182,8 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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) { @@ -1165,7 +1216,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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); } @@ -1176,7 +1227,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC 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); } @@ -1206,7 +1257,7 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha 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())); @@ -1267,7 +1318,7 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha } } - 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); } @@ -1323,7 +1374,6 @@ PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, Cha return Match (Hide, 1, false, false, hide_channels); } - midi_bypass.reset(); return Match (Impossible, 0); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index de854e7d26..990ab14e28 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2155,6 +2155,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err) if (!(*p)->configure_io(c->first, c->second)) { DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configuration failed\n", _name)); + _in_configure_processors = false; return -1; } processor_max_streams = ChanCount::max(processor_max_streams, c->first); |