X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=6209b9f91159a11507e14b31c7dfeee9a1109fcd;hb=a9c09af816b3d7da40221ac4a2bb4c6074708d89;hp=7da7e42abf6953ea43df120a2a489f2a14b8055b;hpb=6de4953be8dc5cd413b405d4801f086567923965;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 7da7e42abf..6209b9f911 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -80,16 +80,14 @@ 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) - : 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) - , GraphNode (sess._process_graph) , _active (true) , _signal_latency (0) , _signal_latency_at_amp_position (0) @@ -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) @@ -145,12 +139,10 @@ Route::init () add_control (_trim_control); _solo_control.reset (new SoloControl (_session, X_("solo"), *this, *this)); - _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle)); add_control (_solo_control); _solo_control->Changed.connect_same_thread (*this, boost::bind (&Route::solo_control_changed, this, _1, _2)); _mute_control.reset (new MuteControl (_session, X_("mute"), *this)); - _mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle)); add_control (_mute_control); _phase_control.reset (new PhaseControl (_session, X_("phase"))); @@ -164,7 +156,7 @@ Route::init () /* panning */ - if (!(_flags & Route::MonitorOut)) { + if (!(_presentation_info.flags() & PresentationInfo::MonitorOut)) { _pannable.reset (new Pannable (_session)); } @@ -272,120 +264,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) { @@ -439,6 +317,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 ()); @@ -564,6 +444,11 @@ 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()); bufs.set_count ((*i)->output_streams()); @@ -755,17 +640,7 @@ Route::solo_control_changed (bool, Controllable::GroupControlDisposition) */ if (Config->get_solo_control_is_listen_control ()) { - set_listen (_solo_control->self_soloed()); - } -} - -bool -Route::listening_via_monitor () const -{ - if (_monitor_send) { - return _monitor_send->active (); - } else { - return false; + set_listen (_solo_control->self_soloed() || _solo_control->get_masters_value()); } } @@ -1749,8 +1624,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. * @@ -2369,9 +2244,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; @@ -2384,9 +2257,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 ()); @@ -2402,11 +2272,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); @@ -2457,6 +2322,8 @@ Route::state(bool full_state) foreach_processor (sigc::bind (sigc::mem_fun (*this, &Route::set_plugin_state_dir), "")); } + node->add_child_copy (Slavable::get_state()); + return *node; } @@ -2484,11 +2351,7 @@ 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()); @@ -2527,21 +2390,16 @@ Route::set_state (const XMLNode& node, int version) } else if (prop->value() == "Output") { _output->set_state (*child, version); } - } - if (child->name() == X_("Processor")) { + } else if (child->name() == X_("Processor")) { processor_state.add_child_copy (*child); - } - - if (child->name() == X_("Pannable")) { + } else if (child->name() == X_("Pannable")) { if (_pannable) { _pannable->set_state (*child, version); } else { warning << string_compose (_("Pannable state found for route (%1) without a panner!"), name()) << endmsg; } - } - - if (child->name() == Controllable::xml_node_name) { + } else if (child->name() == Controllable::xml_node_name) { if ((prop = child->property (X_("name"))) == 0) { continue; } @@ -2557,6 +2415,8 @@ Route::set_state (const XMLNode& node, int 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); } } @@ -2588,46 +2448,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); @@ -2659,13 +2479,6 @@ Route::set_state (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); - } - } else if (child->name() == MuteMaster::xml_node_name) { _mute_master->set_state (*child, version); @@ -2697,13 +2510,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); - } + Stripable::set_state (node, version); if (is_master() || is_monitor() || is_auditioner()) { _mute_master->set_solo_ignore (true); @@ -2777,46 +2584,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 (); @@ -2906,13 +2673,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); - } - } } @@ -3073,9 +2833,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); @@ -5446,36 +5211,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; } - - return _gain_control->slaved_to (vca->gain_control()); + /* just test one particular control, not all of them */ + return _gain_control->slaved (); } -void -Route::vca_assign (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()); -} - -void -Route::vca_unassign (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; } + + /* just test one particular control, not all of them */ + + return _gain_control->slaved_to (vca->gain_control()); } bool @@ -5485,8 +5239,6 @@ Route::muted_by_others_soloing () const return false; } - /* XXX something needed here re: mute-overrides-solo */ - return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); }