compat for old sessions with missing plugins (+doc)
[ardour.git] / libs / ardour / route.cc
index 18dec7c8b93fb7b7cfddb169c805145d4d72e3a9..ce5570057ba1422b4184a9bd6db2f9f0eca94747 100644 (file)
@@ -60,6 +60,7 @@
 #include "ardour/port.h"
 #include "ardour/port_insert.h"
 #include "ardour/processor.h"
+#include "ardour/profile.h"
 #include "ardour/route.h"
 #include "ardour/route_group.h"
 #include "ardour/send.h"
@@ -95,7 +96,8 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _self_solo (false)
        , _soloed_by_others_upstream (0)
        , _soloed_by_others_downstream (0)
-       , _solo_isolated (0)
+       , _solo_isolated (false)
+       , _solo_isolated_by_upstream (0)
        , _denormal_protection (false)
        , _recordable (true)
        , _silent (false)
@@ -112,15 +114,22 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _initial_io_setup (false)
        , _custom_meter_position_noted (false)
 {
-       if (is_master()) {
-               _meter_type = MeterK20;
-       }
        processor_max_streams.reset();
 }
 
 int
 Route::init ()
 {
+       /* set default meter type */
+       if (is_master()) {
+               _meter_type = Config->get_meter_type_master ();
+       }
+       else if (dynamic_cast<Track*>(this)) {
+               _meter_type = Config->get_meter_type_track ();
+       } else {
+               _meter_type = Config->get_meter_type_bus ();
+       }
+
        /* add standard controls */
 
        _solo_control.reset (new SoloControllable (X_("solo"), shared_from_this ()));
@@ -833,6 +842,14 @@ Route::set_solo (bool yn, void *src)
                solo_changed (true, src); /* EMIT SIGNAL */
                _solo_control->Changed (); /* EMIT SIGNAL */
        }
+
+       /* XXX TRACKS DEVELOPERS: THIS LOGIC SUGGESTS THAT YOU ARE NOT AWARE OF
+          Config->get_solo_mute_overrride().
+       */
+
+       if (yn && Profile->get_trx()) {
+               set_mute (false, src);
+       }
 }
 
 void
@@ -935,6 +952,28 @@ Route::set_mute_master_solo ()
        _mute_master->set_soloed (self_soloed() || soloed_by_others_downstream() || soloed_by_others_upstream());
 }
 
+void
+Route::mod_solo_isolated_by_upstream (bool yn, void* src)
+{
+       bool old = solo_isolated ();
+
+       if (!yn) {
+               if (_solo_isolated_by_upstream >= 1) {
+                       _solo_isolated_by_upstream--;
+               } else {
+                       _solo_isolated_by_upstream = 0;
+               }
+       } else {
+               _solo_isolated_by_upstream++;
+       }
+
+       if (solo_isolated() != old) {
+               /* solo isolated status changed */
+               _mute_master->set_solo_ignore (yn);
+               solo_isolated_changed (src);
+       }
+}
+
 void
 Route::set_solo_isolated (bool yn, void *src)
 {
@@ -947,52 +986,53 @@ Route::set_solo_isolated (bool yn, void *src)
                return;
        }
 
+       bool changed = false;
+
+       if (yn) {
+               if (_solo_isolated == false) {
+                       _mute_master->set_solo_ignore (true);
+                       changed = true;
+               }
+               _solo_isolated = true;
+       } else {
+               if (_solo_isolated == true) {
+                       _solo_isolated = false;
+            _mute_master->set_solo_ignore (false);
+                       changed = true;
+               }
+       }
+
+       
+       if (!changed) {
+               return;
+       }
+       
        /* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
 
        boost::shared_ptr<RouteList> routes = _session.get_routes ();
        for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
-
+               
                if ((*i).get() == this || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
                        continue;
                }
-
+               
                bool sends_only;
-               bool does_feed = direct_feeds_according_to_graph (*i, &sends_only); // we will recurse anyway, so don't use ::feeds()
-
+               bool does_feed = feeds (*i, &sends_only);
+               
                if (does_feed && !sends_only) {
-                       (*i)->set_solo_isolated (yn, (*i)->route_group());
+                       (*i)->mod_solo_isolated_by_upstream (yn, src);
                }
        }
-
+       
        /* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
 
-       bool changed = false;
-
-       if (yn) {
-               if (_solo_isolated == 0) {
-                       _mute_master->set_solo_ignore (true);
-                       changed = true;
-               }
-               _solo_isolated++;
-       } else {
-               if (_solo_isolated > 0) {
-                       _solo_isolated--;
-                       if (_solo_isolated == 0) {
-                               _mute_master->set_solo_ignore (false);
-                               changed = true;
-                       }
-               }
-       }
-
-       if (changed) {
-               solo_isolated_changed (src);
-       }
+       solo_isolated_changed (src);
 }
 
 bool
 Route::solo_isolated () const
 {
-       return _solo_isolated > 0;
+       return (_solo_isolated == true) || (_solo_isolated_by_upstream > 0);
 }
 
 void
@@ -1199,7 +1239,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
 
                }
 
-               if (activation_allowed && !_session.get_disable_all_loaded_plugins()) {
+               if (activation_allowed && (!_session.get_disable_all_loaded_plugins () || !processor->display_to_user ())) {
                        processor->activate ();
                }
 
@@ -1279,7 +1319,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
                //A2 uses the "active" flag in the toplevel redirect node, not in the child plugin/IO
                if (i != children.end()) {
                        if ((prop = (*i)->property (X_("active"))) != 0) {
-                               if ( string_is_affirmative (prop->value()) && !_session.get_disable_all_loaded_plugins() )
+                               if ( string_is_affirmative (prop->value()) && (!_session.get_disable_all_loaded_plugins () || !processor->display_to_user () ) )
                                        processor->activate();
                                else
                                        processor->deactivate();
@@ -1838,12 +1878,6 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
 
        for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
 
-               if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
-                       DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
-                       DEBUG_TRACE (DEBUG::Processors, "}\n");
-                       return list<pair<ChanCount, ChanCount> > ();
-               }
-
                if ((*p)->can_support_io_configuration(in, out)) {
                        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));
@@ -1900,11 +1934,9 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
        list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
        for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
 
-               if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
-                       break;
+               if (!(*p)->configure_io(c->first, c->second)) {
+                       DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configuration failed\n", _name));
                }
-
-               (*p)->configure_io(c->first, c->second);
                processor_max_streams = ChanCount::max(processor_max_streams, c->first);
                processor_max_streams = ChanCount::max(processor_max_streams, c->second);
 
@@ -4487,6 +4519,12 @@ 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)->activate ();
+               }
+       }
+
        DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: setup_invisible_processors\n", _name));
        for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
                DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));