fix implementation of SoloControl::clear_all_solo_state()
[ardour.git] / libs / ardour / route.cc
index e59677f44ccd28b78b159d6da9e03e4ea6d23759..b31bfccf75f80a874e85cabf76f8fb3ceccdf82a 100644 (file)
@@ -117,6 +117,11 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
        processor_max_streams.reset();
 }
 
+boost::weak_ptr<Route>
+Route::weakroute () {
+       return boost::weak_ptr<Route> (shared_from_this ());
+}
+
 int
 Route::init ()
 {
@@ -229,10 +234,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 */
 
        {
@@ -626,6 +627,9 @@ void
 Route::set_listen (bool yn)
 {
        if (_monitor_send) {
+               if (_monitor_send->active() == yn) {
+                       return;
+               }
                if (yn) {
                        _monitor_send->activate ();
                } else {
@@ -835,6 +839,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
                                if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
                                                prop->value() == "lv2" ||
                                                prop->value() == "windows-vst" ||
+                                               prop->value() == "mac-vst" ||
                                                prop->value() == "lxvst" ||
                                                prop->value() == "audiounit") {
 
@@ -1018,8 +1023,12 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
                                }
                        }
 
+                       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()) {
-                               // why?  emit  ActiveChanged() ??
+                               // emit ActiveChanged() and latency_changed() if needed
                                (*i)->activate ();
                        }
 
@@ -2352,10 +2361,6 @@ Route::set_state (const XMLNode& node, int version)
                _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
@@ -2394,22 +2399,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);
                }
@@ -2467,13 +2456,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") {
+               }  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() == "mute") {
+                       } 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() == _mute_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);
 
@@ -2507,10 +2507,6 @@ Route::set_state_2X (const XMLNode& node, int version)
 
        Stripable::set_state (node, version);
 
-       if (is_master() || is_monitor() || is_auditioner()) {
-               _mute_master->set_solo_ignore (true);
-       }
-
        if ((prop = node.property (X_("denormal-protection"))) != 0) {
                set_denormal_protection (string_is_affirmative (prop->value()));
        }
@@ -2767,6 +2763,7 @@ Route::set_processor_state (const XMLNode& node)
                                } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
                                           prop->value() == "lv2" ||
                                           prop->value() == "windows-vst" ||
+                                          prop->value() == "mac-vst" ||
                                           prop->value() == "lxvst" ||
                                           prop->value() == "luaproc" ||
                                           prop->value() == "audiounit") {
@@ -2828,6 +2825,7 @@ 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
@@ -2835,7 +2833,6 @@ Route::set_processor_state (const XMLNode& node)
                 * a process lock.
                 */
                _processors = new_order;
-               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
 
                if (must_configure) {
                        configure_processors_unlocked (0, &lm);
@@ -2994,8 +2991,7 @@ Route::add_aux_send (boost::shared_ptr<Route> route, boost::shared_ptr<Processor
 
                {
                        Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-                       boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
-                       listener.reset (new InternalSend (_session, sendpan, _mute_master, boost::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), route, Delivery::Aux));
+                       listener.reset (new InternalSend (_session, _pannable, _mute_master, boost::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), route, Delivery::Aux));
                }
 
                add_processor (listener, before);
@@ -3174,6 +3170,7 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool*
                if (iop != 0) {
                        boost::shared_ptr<const IO> 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;
                        }
@@ -4509,10 +4506,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) {
@@ -4520,10 +4524,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) {
@@ -5263,7 +5263,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