X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=11db73241cbd304c629a556828f02611134678c9;hp=c36e501aefde8e1d9bf1c59add2658568ede0908;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hpb=eee3837245f570d36e5d4d92409660c8ff777b5b diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index c36e501aef..11db73241c 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -74,20 +74,18 @@ #include "ardour/utils.h" #include "ardour/vca.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; -PBD::Signal0 Route::SyncOrderKeys; -PBD::Signal0 Route::RemoteControlIDChange; PBD::Signal3, boost::shared_ptr, Route::PluginSetupOptions > Route::PluginSetup; /** Base class for all routable/mixable objects (tracks and busses) */ -Route::Route (Session& sess, string name, Flag flg, DataType default_type) - : GraphNode (sess._process_graph) - , Stripable (sess, name) +Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType default_type) + : Stripable (sess, name, PresentationInfo (flag)) + , GraphNode (sess._process_graph) , Muteable (sess, name) , Automatable (sess) , _active (true) @@ -98,7 +96,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _roll_delay (0) , _pending_process_reorder (0) , _pending_signals (0) - , _flags (flg) , _pending_declick (true) , _meter_point (MeterPostFader) , _pending_meter_point (MeterPostFader) @@ -109,9 +106,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _declickable (false) , _have_internal_generator (false) , _default_type (default_type) - , _order_key (0) - , _has_order_key (false) - , _remote_control_id (0) , _track_number (0) , _in_configure_processors (false) , _initial_io_setup (false) @@ -162,7 +156,7 @@ Route::init () /* panning */ - if (!(_flags & Route::MonitorOut)) { + if (!(_presentation_info.flags() & PresentationInfo::MonitorOut)) { _pannable.reset (new Pannable (_session)); } @@ -235,10 +229,6 @@ Route::init () _monitor_control->activate (); } - if (is_master() || is_monitor() || is_auditioner()) { - _mute_master->set_solo_ignore (true); - } - /* now that we have _meter, its safe to connect to this */ { @@ -270,120 +260,6 @@ Route::~Route () _processors.clear (); } -void -Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) -{ - if (Config->get_remote_model() != UserOrdered) { - return; - } - - set_remote_control_id_internal (id, notify_class_listeners); -} - -void -Route::set_remote_control_id_internal (uint32_t id, bool notify_class_listeners) -{ - /* force IDs for master/monitor busses and prevent - any other route from accidentally getting these IDs - (i.e. legacy sessions) - */ - - if (is_master() && id != MasterBusRemoteControlID) { - id = MasterBusRemoteControlID; - } - - if (is_monitor() && id != MonitorBusRemoteControlID) { - id = MonitorBusRemoteControlID; - } - - if (id < 1) { - return; - } - - /* don't allow it to collide */ - - if (!is_master () && !is_monitor() && - (id == MasterBusRemoteControlID || id == MonitorBusRemoteControlID)) { - id += MonitorBusRemoteControlID; - } - - if (id != remote_control_id()) { - _remote_control_id = id; - RemoteControlIDChanged (); - - if (notify_class_listeners) { - RemoteControlIDChange (); - } - } -} - -uint32_t -Route::remote_control_id() const -{ - if (is_master()) { - return MasterBusRemoteControlID; - } - - if (is_monitor()) { - return MonitorBusRemoteControlID; - } - - return _remote_control_id; -} - -bool -Route::has_order_key () const -{ - return _has_order_key; -} - -uint32_t -Route::order_key () const -{ - return _order_key; -} - -void -Route::set_remote_control_id_explicit (uint32_t rid) -{ - if (is_master() || is_monitor() || is_auditioner()) { - /* hard-coded remote IDs, or no remote ID */ - return; - } - - if (_remote_control_id != rid) { - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), rid)); - _remote_control_id = rid; - RemoteControlIDChanged (); /* EMIT SIGNAL (per-route) */ - } - - /* don't emit the class-level RID signal RemoteControlIDChange here, - leave that to the entity that changed the order key, so that we - don't get lots of emissions for no good reasons (e.g. when changing - all route order keys). - - See Session::sync_remote_id_from_order_keys() for the (primary|only) - spot where that is emitted. - */ -} - -void -Route::set_order_key (uint32_t n) -{ - _has_order_key = true; - - if (_order_key == n) { - return; - } - - _order_key = n; - - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key set to %2\n", - name(), order_key ())); - - _session.set_dirty (); -} - string Route::ensure_track_or_route_name(string name, Session &session) { @@ -437,6 +313,8 @@ Route::process_output_buffers (BufferSet& bufs, return; } + _mute_control->automation_run (start_frame, nframes); + /* figure out if we're going to use gain automation */ if (gain_automation_ok) { _amp->set_gain_automation_buffer (_session.gain_automation_buffer ()); @@ -533,6 +411,7 @@ Route::process_output_buffers (BufferSet& bufs, bool const meter_already_run = metering_state() == MeteringInput; framecnt_t latency = 0; + const double speed = _session.transport_speed (); for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { @@ -562,8 +441,13 @@ Route::process_output_buffers (BufferSet& bufs, if (boost::dynamic_pointer_cast(*i) != 0) { boost::dynamic_pointer_cast(*i)->set_delay_in(_signal_latency - latency); } + if (boost::dynamic_pointer_cast(*i) != 0) { + const framecnt_t longest_session_latency = _initial_delay + _signal_latency; + boost::dynamic_pointer_cast(*i)->set_sidechain_latency ( + _initial_delay + latency, longest_session_latency - latency); + } - (*i)->run (bufs, start_frame - latency, end_frame - latency, nframes, *i != _processors.back()); + (*i)->run (bufs, start_frame - latency, end_frame - latency, speed, nframes, *i != _processors.back()); bufs.set_count ((*i)->output_streams()); if ((*i)->active ()) { @@ -591,6 +475,7 @@ Route::bounce_process (BufferSet& buffers, framepos_t start, framecnt_t nframes, _trim->setup_gain_automation (start, start + nframes, nframes); latency = 0; + const double speed = _session.transport_speed (); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { if (!include_endpoint && (*i) == endpoint) { @@ -613,7 +498,7 @@ Route::bounce_process (BufferSet& buffers, framepos_t start, framecnt_t nframes, */ if ((*i) == _main_outs) { assert ((*i)->does_routing()); - (*i)->run (buffers, start - latency, start - latency + nframes, nframes, true); + (*i)->run (buffers, start - latency, start - latency + nframes, speed, nframes, true); buffers.set_count ((*i)->output_streams()); } @@ -621,7 +506,7 @@ Route::bounce_process (BufferSet& buffers, framepos_t start, framecnt_t nframes, * Also don't bother with metering. */ if (!(*i)->does_routing() && !boost::dynamic_pointer_cast(*i)) { - (*i)->run (buffers, start - latency, start - latency + nframes, nframes, true); + (*i)->run (buffers, start - latency, start - latency + nframes, 1.0, nframes, true); buffers.set_count ((*i)->output_streams()); latency += (*i)->signal_latency (); } @@ -1129,7 +1014,12 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr } } + if (pi && pi->has_sidechain ()) { + pi->sidechain_input ()->changed.connect_same_thread (*this, boost::bind (&Route::sidechain_change_handler, this, _1, _2)); + } + if ((*i)->active()) { + // emit ActiveChanged() and latency_changed() if needed (*i)->activate (); } @@ -1188,7 +1078,7 @@ Route::disable_processors (Placement p) placement_range(p, start, end); for (ProcessorList::iterator i = start; i != end; ++i) { - (*i)->deactivate (); + (*i)->enable (false); } _session.set_dirty (); @@ -1202,7 +1092,7 @@ Route::disable_processors () Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->deactivate (); + (*i)->enable (false); } _session.set_dirty (); @@ -1221,7 +1111,7 @@ Route::disable_plugins (Placement p) for (ProcessorList::iterator i = start; i != end; ++i) { if (boost::dynamic_pointer_cast (*i)) { - (*i)->deactivate (); + (*i)->enable (false); } } @@ -1237,7 +1127,7 @@ Route::disable_plugins () for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { if (boost::dynamic_pointer_cast (*i)) { - (*i)->deactivate (); + (*i)->enable (false); } } @@ -1261,8 +1151,8 @@ Route::ab_plugins (bool forward) continue; } - if ((*i)->active()) { - (*i)->deactivate (); + if ((*i)->enabled ()) { + (*i)->enable (false); (*i)->set_next_ab_is_active (true); } else { (*i)->set_next_ab_is_active (false); @@ -1279,11 +1169,7 @@ Route::ab_plugins (bool forward) continue; } - if ((*i)->get_next_ab_is_active()) { - (*i)->activate (); - } else { - (*i)->deactivate (); - } + (*i)->enable ((*i)->get_next_ab_is_active ()); } } @@ -1524,7 +1410,7 @@ Route::replace_processor (boost::shared_ptr old, boost::shared_ptractive (); + bool enable = old->enabled (); for (i = _processors.begin(); i != _processors.end(); ) { if (*i == old) { @@ -1568,7 +1454,7 @@ Route::replace_processor (boost::shared_ptr old, boost::shared_ptractivate (); + sub->enable (true); } sub->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); @@ -1737,8 +1623,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) if (boost::dynamic_pointer_cast (*p) && boost::dynamic_pointer_cast (*p)->role() == Delivery::Main - && !(is_monitor() || is_auditioner()) - && ( _strict_io || Profile->get_mixbus ())) { + && !is_auditioner() + && (is_monitor() || _strict_io || Profile->get_mixbus ())) { /* with strict I/O the panner + output are forced to * follow the last processor's output. * @@ -1750,8 +1636,9 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) * 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 */ + if (!is_master() && _session.master_out () && in.n_audio() > 0) { + /* ..but at least as many as there are master-inputs, if + * the delivery is dealing with audio */ // 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 ()); @@ -1942,12 +1829,7 @@ Route::all_visible_processors_active (bool state) if (!(*i)->display_to_user() || boost::dynamic_pointer_cast (*i)) { continue; } - - if (state) { - (*i)->activate (); - } else { - (*i)->deactivate (); - } + (*i)->enable (state); } _session.set_dirty (); @@ -2357,9 +2239,7 @@ Route::state(bool full_state) node->add_property("default-type", _default_type.to_string()); node->add_property ("strict-io", _strict_io); - if (_flags) { - node->add_property("flags", enum_2_string (_flags)); - } + node->add_child_nocopy (_presentation_info.get_state()); node->add_property("active", _active?"yes":"no"); string p; @@ -2372,9 +2252,6 @@ Route::state(bool full_state) node->add_property("route-group", _route_group->name()); } - snprintf (buf, sizeof (buf), "%d", _order_key); - node->add_property ("order-key", buf); - node->add_child_nocopy (_solo_control->get_state ()); node->add_child_nocopy (_solo_isolate_control->get_state ()); node->add_child_nocopy (_solo_safe_control->get_state ()); @@ -2390,11 +2267,6 @@ Route::state(bool full_state) node->add_child_nocopy (Automatable::get_automation_xml_state ()); } - XMLNode* remote_control_node = new XMLNode (X_("RemoteControl")); - snprintf (buf, sizeof (buf), "%d", _remote_control_id); - remote_control_node->add_property (X_("id"), buf); - node->add_child_nocopy (*remote_control_node); - if (_comment.length()) { XMLNode *cmt = node->add_child ("Comment"); cmt->add_content (_comment); @@ -2474,20 +2346,12 @@ Route::set_state (const XMLNode& node, int version) set_id (node); _initial_io_setup = true; - if ((prop = node.property (X_("flags"))) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } else { - _flags = Flag (0); - } + Stripable::set_state (node, version); if ((prop = node.property (X_("strict-io"))) != 0) { _strict_io = string_is_affirmative (prop->value()); } - if (!can_solo()) { - _mute_master->set_solo_ignore (true); - } - if (is_monitor()) { /* monitor bus does not get a panner, but if (re)created via XML, it will already have one by the time we @@ -2526,22 +2390,6 @@ Route::set_state (const XMLNode& node, int version) } else { warning << string_compose (_("Pannable state found for route (%1) without a panner!"), name()) << endmsg; } - } else if (child->name() == Controllable::xml_node_name) { - if ((prop = child->property (X_("name"))) == 0) { - continue; - } - - if (prop->value() == _gain_control->name()) { - _gain_control->set_state (*child, version); - } else if (prop->value() == _solo_control->name()) { - _solo_control->set_state (*child, version); - } else if (prop->value() == _solo_safe_control->name()) { - _solo_safe_control->set_state (*child, version); - } else if (prop->value() == _solo_isolate_control->name()) { - _solo_isolate_control->set_state (*child, version); - } else if (prop->value() == _solo_control->name()) { - _mute_control->set_state (*child, version); - } } else if (child->name() == Slavable::xml_node_name) { Slavable::set_state (*child, version); } @@ -2575,46 +2423,6 @@ Route::set_state (const XMLNode& node, int version) set_active (yn, this); } - if ((prop = node.property (X_("order-key"))) != 0) { // New order key (no separate mixer/editor ordering) - set_order_key (atoi(prop->value())); - } - - if ((prop = node.property (X_("order-keys"))) != 0) { // Deprecated order keys - - int32_t n; - - string::size_type colon, equal; - string remaining = prop->value(); - - while (remaining.length()) { - - if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - string keyname = remaining.substr (0, equal); - - if ((keyname == "EditorSort") || (keyname == "editor")) { - cerr << "Setting " << name() << " order key to " << n << " using saved Editor order." << endl; - set_order_key (n); - } - } - } - - colon = remaining.find_first_of (':'); - - if (colon != string::npos) { - remaining = remaining.substr (colon+1); - } else { - break; - } - } - } - if ((prop = node.property (X_("processor-after-last-custom-meter"))) != 0) { PBD::ID id (prop->value ()); Glib::Threads::RWLock::ReaderLock lm (_processor_lock); @@ -2639,20 +2447,24 @@ Route::set_state (const XMLNode& node, int version) XMLNode *cmt = *(child->children().begin()); _comment = cmt->content(); - } else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) { - if (prop->value() == "solo") { - _solo_control->set_state (*child, version); - } else if (prop->value() == "mute") { - _mute_control->set_state (*child, version); + } else if (child->name() == Controllable::xml_node_name) { + if ((prop = child->property (X_("name"))) == 0) { + continue; } - } else if (child->name() == X_("RemoteControl")) { - if ((prop = child->property (X_("id"))) != 0) { - int32_t x; - sscanf (prop->value().c_str(), "%d", &x); - set_remote_control_id_internal (x); + if (prop->value() == _gain_control->name()) { + _gain_control->set_state (*child, version); + } else if (prop->value() == _solo_control->name()) { + _solo_control->set_state (*child, version); + } else if (prop->value() == _solo_safe_control->name()) { + _solo_safe_control->set_state (*child, version); + } else if (prop->value() == _solo_isolate_control->name()) { + _solo_isolate_control->set_state (*child, version); + } else if (prop->value() == _solo_control->name()) { + _mute_control->set_state (*child, version); + } else if (prop->value() == _phase_control->name()) { + _phase_control->set_state (*child, version); } - } else if (child->name() == MuteMaster::xml_node_name) { _mute_master->set_state (*child, version); @@ -2684,17 +2496,7 @@ Route::set_state_2X (const XMLNode& node, int version) return -1; } - if ((prop = node.property (X_("flags"))) != 0) { - string f = prop->value (); - boost::replace_all (f, "ControlOut", "MonitorOut"); - _flags = Flag (string_2_enum (f, _flags)); - } else { - _flags = Flag (0); - } - - if (is_master() || is_monitor() || is_auditioner()) { - _mute_master->set_solo_ignore (true); - } + Stripable::set_state (node, version); if ((prop = node.property (X_("denormal-protection"))) != 0) { set_denormal_protection (string_is_affirmative (prop->value())); @@ -2764,46 +2566,6 @@ Route::set_state_2X (const XMLNode& node, int version) _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point)); } - /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they - don't mean the same thing. - */ - - if ((prop = node.property (X_("order-keys"))) != 0) { - - int32_t n; - - string::size_type colon, equal; - string remaining = prop->value(); - - while (remaining.length()) { - - if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - string keyname = remaining.substr (0, equal); - - if (keyname == "EditorSort" || keyname == "editor") { - info << string_compose(_("Converting deprecated order key for %1 using Editor order %2"), name (), n) << endmsg; - set_order_key (n); - } - } - } - - colon = remaining.find_first_of (':'); - - if (colon != string::npos) { - remaining = remaining.substr (colon+1); - } else { - break; - } - } - } - /* IOs */ nlist = node.children (); @@ -2893,13 +2655,6 @@ Route::set_state_2X (const XMLNode& node, int version) _mute_control->set_state (*child, version); } - } else if (child->name() == X_("RemoteControl")) { - if ((prop = child->property (X_("id"))) != 0) { - int32_t x; - sscanf (prop->value().c_str(), "%d", &x); - set_remote_control_id_internal (x); - } - } } @@ -3060,9 +2815,14 @@ Route::set_processor_state (const XMLNode& node) } { - Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); Glib::Threads::RWLock::WriterLock lm (_processor_lock); + /* re-assign _processors w/o process-lock. + * if there's an IO-processor present in _processors but + * not in new_order, it will be deleted and ~IO takes + * a process lock. + */ _processors = new_order; + Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); if (must_configure) { configure_processors_unlocked (0, &lm); @@ -3112,6 +2872,8 @@ Route::silence_unlocked (framecnt_t nframes) { /* Must be called with the processor lock held */ + const framepos_t now = _session.transport_frame (); + if (!_silent) { _output->silence (nframes); @@ -3124,7 +2886,7 @@ Route::silence_unlocked (framecnt_t nframes) continue; } - (*i)->silence (nframes); + (*i)->silence (nframes, now); } if (nframes == _session.get_block_size()) { @@ -3398,6 +3160,11 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr other, bool* if (iop != 0) { boost::shared_ptr iop_out = iop->output(); + if (other.get() == this && iop_out && iop->input() && iop_out->connected_to (iop->input())) { + // TODO this needs a delaylines in the Insert to align connections (!) + DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed its own return (%2)\n", iop->name(), other->name())); + continue; + } 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) { @@ -3616,6 +3383,22 @@ Route::pans_required () const return max (n_inputs ().n_audio(), processor_max_streams.n_audio()); } +void +Route::flush_processor_buffers_locked (framecnt_t nframes) +{ + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + boost::shared_ptr d = boost::dynamic_pointer_cast (*i); + if (d) { + d->flush_buffers (nframes); + } else { + boost::shared_ptr p = boost::dynamic_pointer_cast (*i); + if (p) { + p->flush_buffers (nframes); + } + } + } +} + int Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing) { @@ -3654,13 +3437,15 @@ Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, fill_buffers_with_input (bufs, _input, nframes); if (_meter_point == MeterInput) { - _meter->run (bufs, start_frame, end_frame, nframes, true); + _meter->run (bufs, start_frame, end_frame, 0.0, nframes, true); } _amp->apply_gain_automation (false); _trim->apply_gain_automation (false); passthru (bufs, start_frame, end_frame, nframes, 0); + flush_processor_buffers_locked (nframes); + return 0; } @@ -3694,11 +3479,13 @@ Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, in fill_buffers_with_input (bufs, _input, nframes); if (_meter_point == MeterInput) { - _meter->run (bufs, start_frame, end_frame, nframes, true); + _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true); } passthru (bufs, start_frame, end_frame, nframes, declick); + flush_processor_buffers_locked (nframes); + return 0; } @@ -3706,6 +3493,7 @@ int Route::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& /* need_butler */) { silence (nframes); + flush_processor_buffers_locked (nframes); return 0; } @@ -3929,7 +3717,9 @@ Route::add_export_point() Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); Glib::Threads::RWLock::WriterLock lw (_processor_lock); - _capturing_processor.reset (new CapturingProcessor (_session)); + // this aligns all tracks; but not tracks + busses + assert (_session.worst_track_latency () >= _initial_delay); + _capturing_processor.reset (new CapturingProcessor (_session, _session.worst_track_latency () - _initial_delay)); _capturing_processor->activate (); configure_processors_unlocked (0, &lw); @@ -4707,10 +4497,17 @@ Route::setup_invisible_processors () new_processors.insert (amp, _monitor_control); } + /* TRIM CONTROL */ + + if (_trim && _trim->active()) { + assert (!_trim->display_to_user ()); + new_processors.push_front (_trim); + } + /* INTERNAL RETURN */ - /* doing this here means that any monitor control will come just after - the return. + /* doing this here means that any monitor control will come after + the return and trim. */ if (_intreturn) { @@ -4718,10 +4515,6 @@ Route::setup_invisible_processors () new_processors.push_front (_intreturn); } - if (_trim && _trim->active()) { - assert (!_trim->display_to_user ()); - new_processors.push_front (_trim); - } /* EXPORT PROCESSOR */ if (_capturing_processor) { @@ -4732,8 +4525,8 @@ Route::setup_invisible_processors () _processors = new_processors; for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if (!(*i)->display_to_user () && !(*i)->active () && (*i) != _monitor_send) { - (*i)->activate (); + if (!(*i)->display_to_user () && !(*i)->enabled () && (*i) != _monitor_send) { + (*i)->enable (true); } } @@ -5433,42 +5226,25 @@ Route::master_send_enable_controllable () const } bool -Route::slaved_to (boost::shared_ptr vca) const +Route::slaved () const { - if (!vca || !_gain_control) { + if (!_gain_control) { return false; } - /* just test one particular control, not all of them */ - - return _gain_control->slaved_to (vca->gain_control()); -} - -int -Route::assign_controls (boost::shared_ptr vca) -{ - _gain_control->add_master (vca->gain_control()); - _solo_control->add_master (vca->solo_control()); - _mute_control->add_master (vca->mute_control()); - - return 0; + return _gain_control->slaved (); } -int -Route::unassign_controls (boost::shared_ptr vca) +bool +Route::slaved_to (boost::shared_ptr vca) const { - if (!vca) { - /* unassign from all */ - _gain_control->clear_masters (); - _solo_control->clear_masters (); - _mute_control->clear_masters (); - } else { - _gain_control->remove_master (vca->gain_control()); - _solo_control->remove_master (vca->solo_control()); - _mute_control->remove_master (vca->mute_control()); + if (!vca || !_gain_control) { + return false; } - return 0; + /* just test one particular control, not all of them */ + + return _gain_control->slaved_to (vca->gain_control()); } bool @@ -5478,7 +5254,7 @@ Route::muted_by_others_soloing () const return false; } - return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); + return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); } void