X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=1db571385fbd98de2427b63fba3dbb148f013394;hb=a3eaa4d3f0606349b91c7660da19eb3fee91bce3;hp=01ab80f9dcfaaf3b1e1d3c84d21712e66749089b;hpb=e84453e8786052790629e8a7323441a3ab5309c8;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 01ab80f9dc..1db571385f 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -79,6 +79,7 @@ using namespace PBD; PBD::Signal0 Route::SyncOrderKeys; PBD::Signal0 Route::RemoteControlIDChange; +/** Base class for all routable/mixable objects (tracks and busses) */ Route::Route (Session& sess, string name, Flag flg, DataType default_type) : SessionObject (sess, name) , Automatable (sess) @@ -1465,7 +1466,6 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr boost::shared_ptr pi; if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { - pi->set_count (1); // why? configure_processors_unlocked() will re-do this pi->set_strict_io (_strict_io); } @@ -2080,6 +2080,34 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) { if ((*p)->can_support_io_configuration(in, out)) { + + if (boost::dynamic_pointer_cast (*p) + && boost::dynamic_pointer_cast (*p)->role() == Delivery::Main +#ifndef MIXBUS + && _strict_io +#endif + ) { + /* with strict I/O the panner + output are forced to + * follow the last processor's output. + * + * Delivery::can_support_io_configuration() will only add ports, + * but not remove excess ports. + * + * This works because the delivery only requires + * as many outputs as there are inputs. + * Delivery::configure_io() will do the actual removal + * by calling _output->ensure_io() + */ + if (!is_master() && _session.master_out ()) { + /* ..but at least as many as there are master-inputs */ + // XXX this may need special-casing for mixbus (master-outputs) + // and should maybe be a preference anyway ?! + out = ChanCount::max (in, _session.master_out ()->n_inputs ()); + } else { + out = in; + } + } + DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID=%2 in=%3 out=%4\n",(*p)->name(), (*p)->id(), in, out)); configuration.push_back(make_pair(in, out)); @@ -2174,17 +2202,18 @@ Route::configure_processors_unlocked (ProcessorStreams* err) processor_max_streams = ChanCount::max(processor_max_streams, c->first); processor_max_streams = ChanCount::max(processor_max_streams, c->second); + boost::shared_ptr iop; boost::shared_ptr pi; if ((pi = boost::dynamic_pointer_cast(*p)) != 0) { /* plugins connected via Split or Hide Match may have more channels. * route/scratch buffers are needed for all of them * The configuration may only be a subset (both input and output) */ - processor_max_streams = ChanCount::max(processor_max_streams, pi->input_streams()); - processor_max_streams = ChanCount::max(processor_max_streams, pi->internal_streams()); - processor_max_streams = ChanCount::max(processor_max_streams, pi->output_streams()); - processor_max_streams = ChanCount::max(processor_max_streams, pi->natural_input_streams() * pi->get_count()); - processor_max_streams = ChanCount::max(processor_max_streams, pi->natural_output_streams() * pi->get_count()); + processor_max_streams = ChanCount::max(processor_max_streams, pi->required_buffers()); + } + else if ((iop = boost::dynamic_pointer_cast(*p)) != 0) { + processor_max_streams = ChanCount::max(processor_max_streams, iop->natural_input_streams()); + processor_max_streams = ChanCount::max(processor_max_streams, iop->natural_output_streams()); } out = c->second; @@ -3622,7 +3651,22 @@ Route::all_inputs () const } if (iop != 0 && iop->input()) { - ios.push_back (iop->input()); + ios.push_back (iop->input()); + } + } + return ios; +} + +IOVector +Route::all_outputs () const +{ + IOVector ios; + // _output is included via Delivery + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::const_iterator r = _processors.begin(); r != _processors.end(); ++r) { + boost::shared_ptr iop = boost::dynamic_pointer_cast(*r); + if (iop != 0 && iop->output()) { + ios.push_back (iop->output()); } } return ios; @@ -3654,7 +3698,7 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr other, bool* if (iop != 0) { boost::shared_ptr iop_out = iop->output(); - if (iop_out && other->all_inputs().fed_by (iop_out)) { + if ((iop_out && other->all_inputs().fed_by (iop_out)) || iop->feeds (other)) { DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name())); if (via_send_only) { *via_send_only = true; @@ -3679,6 +3723,12 @@ Route::direct_feeds_according_to_graph (boost::shared_ptr other, bool* vi return _session._current_route_graph.has (shared_from_this (), other, via_send_only); } +bool +Route::feeds_according_to_graph (boost::shared_ptr other) +{ + return _session._current_route_graph.feeds (shared_from_this (), other); +} + /** Called from the (non-realtime) butler thread when the transport is stopped */ void Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool /*did_locate*/, bool can_flush_processors) @@ -4711,6 +4761,9 @@ Route::input_port_count_changing (ChanCount to) bool Route::output_port_count_changing (ChanCount to) { + if (_strict_io && !_in_configure_processors) { + return true; + } for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { if (processor_out_streams.get(*t) > to.get(*t)) { return true;