Initial Gain Coefficient tweaks
[ardour.git] / libs / ardour / route.cc
index e6ab6fb6fc544e20e3252d2c235454089c3b9af0..c2a7c62f6d891290b45ae3bfea6e435c4ff60761 100644 (file)
@@ -433,7 +433,10 @@ Route::process_output_buffers (BufferSet& bufs,
        assert (!AudioEngine::instance()->process_lock().trylock());
 
        Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
-       assert(lm.locked());
+       if (!lm.locked()) {
+               bufs.silence (nframes, 0);
+               return;
+       }
 
        /* figure out if we're going to use gain automation */
        if (gain_automation_ok) {
@@ -769,6 +772,11 @@ Route::set_solo (bool yn, void *src)
                return;
        }
 
+       if (is_master() || is_monitor() || is_auditioner()) {
+               DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change (master, monitor or auditioner)\n", name()));
+               return;
+       }
+
        if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
                _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group));
                return;
@@ -1214,8 +1222,18 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
                if (processor->set_state (node, version)) {
                        return false;
                }
+               
+               //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() )
+                                       processor->activate();
+                               else
+                                       processor->deactivate();
+                       }
+               }
 
-               return (add_processor (processor, placement) == 0);
+               return (add_processor (processor, placement, 0, false) == 0);
        }
 
        catch (failed_constructor &err) {
@@ -2321,6 +2339,7 @@ Route::set_state (const XMLNode& node, int version)
 int
 Route::set_state_2X (const XMLNode& node, int version)
 {
+       LocaleGuard lg (X_("C"));
        XMLNodeList nlist;
        XMLNodeConstIterator niter;
        XMLNode *child;
@@ -3077,6 +3096,11 @@ Route::output_change_handler (IOChange change, void * /*src*/)
                */
                need_to_queue_solo_change = false;
                configure_processors (0);
+
+               if (is_master()) {
+                       _session.reset_monitor_section();
+               }
+
                io_changed (); /* EMIT SIGNAL */
        }
 
@@ -3406,7 +3430,7 @@ Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<R
 void
 Route::SoloControllable::set_value (double val)
 {
-       bool bval = ((val >= 0.5f) ? true: false);
+       const bool bval = ((val >= 0.5) ? true : false);
 
        boost::shared_ptr<RouteList> rl (new RouteList);
 
@@ -3433,9 +3457,9 @@ Route::SoloControllable::get_value () const
        }
 
        if (Config->get_solo_control_is_listen_control()) {
-               return r->listening_via_monitor() ? 1.0f : 0.0f;
+               return r->listening_via_monitor() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
        } else {
-               return r->self_soloed() ? 1.0f : 0.0f;
+               return r->self_soloed() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
        }
 }
 
@@ -3453,37 +3477,51 @@ Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<R
 }
 
 void
-Route::MuteControllable::set_value (double val)
+Route::MuteControllable::set_superficial_value(bool muted)
 {
-       bool bval = ((val >= 0.5f) ? true: false);
+       /* Note we can not use AutomationControl::set_value here since it will emit
+          Changed(), but the value will not be correct to the observer. */
+
+       bool to_list = _list && ((AutomationList*)_list.get())->automation_write();
+
+       Control::set_double (muted, _session.transport_frame(), to_list);
+}
 
-       // boost::shared_ptr<RouteList> rl (new RouteList);
+void
+Route::MuteControllable::set_value (double val)
+{
+       const bool bval = ((val >= 0.5) ? true : false);
 
        boost::shared_ptr<Route> r = _route.lock ();
        if (!r) {
                return;
        }
 
-       /* I don't know why this apparently "should" be done via the RT event
-          system, but doing so causes a ton of annoying errors... */
-       // rl->push_back (r);
-       // _session.set_mute (rl, bval);
-
-       /* ... but this seems to work. */
-       r->set_mute (bval, this);
+       if (_list && ((AutomationList*)_list.get())->automation_playback()) {
+               // Playing back automation, set route mute directly
+               r->set_mute (bval, this);
+       } else {
+               // Set from user, queue mute event
+               boost::shared_ptr<RouteList> rl (new RouteList);
+               rl->push_back (r);
+               _session.set_mute (rl, bval, Session::rt_cleanup);
+       }
 
-       AutomationControl::set_value(bval);
+       // Set superficial/automation value to drive controller (and possibly record)
+       set_superficial_value(bval);
 }
 
 double
 Route::MuteControllable::get_value () const
 {
-       boost::shared_ptr<Route> r = _route.lock ();
-       if (!r) {
-               return 0;
+       if (_list && ((AutomationList*)_list.get())->automation_playback()) {
+               // Playing back automation, get the value from the list
+               return AutomationControl::get_value();
        }
 
-       return r->muted() ? 1.0f : 0.0f;
+       // Not playing back automation, get the actual route mute value
+       boost::shared_ptr<Route> r = _route.lock ();
+       return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
 }
 
 void