"Run plugins while recording" -> "Do not run plugins while recording"
[ardour.git] / libs / ardour / route.cc
index cd925e90b538dbfecc0b65a9340ffff90e91c3f4..5fcbd53bb68c8c2a968cbccdf31d84a8af9c47a8 100644 (file)
@@ -86,6 +86,7 @@ Route::init ()
        _have_internal_generator = false;
        _declickable = false;
        _pending_declick = true;
+       _remote_control_id = 0;
 
        _edit_group = 0;
        _mix_group = 0;
@@ -118,6 +119,21 @@ Route::~Route ()
        }
 }
 
+void
+Route::set_remote_control_id (uint32_t id)
+{
+       if (id != _remote_control_id) {
+               _remote_control_id = id;
+               RemoteControlIDChanged ();
+       }
+}
+
+uint32_t
+Route::remote_control_id() const
+{
+       return _remote_control_id;
+}
+
 long
 Route::order_key (string name) const
 {
@@ -213,7 +229,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
        IO *co;
        bool mute_audible;
        bool solo_audible;
-       bool no_monitor = (Config->get_use_hardware_monitoring() || Config->get_no_sw_monitoring ());
+       bool no_monitor = (Config->get_use_hardware_monitoring() || !Config->get_use_sw_monitoring ());
        gain_t* gab = _session.gain_automation_buffer();
 
        declick = _pending_declick;
@@ -314,7 +330,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
           -------------------------------------------------------------------------------------------------- */
 
        if (with_redirects) {
-               TentativeLockMonitor rm (redirect_lock, __LINE__, __FILE__);
+               TentativeRWLockMonitor rm (redirect_lock, false, __LINE__, __FILE__);
                if (rm.locked()) {
                        if (mute_gain > 0 || !_mute_affects_pre_fader) {
                                for (i = _redirects.begin(); i != _redirects.end(); ++i) {
@@ -406,7 +422,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
 
                 // AND software monitoring required
 
-                !Config->get_no_sw_monitoring())) { 
+                Config->get_use_sw_monitoring())) { 
                
                if (apply_gain_automation) {
                        
@@ -428,7 +444,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
                                }
                        }
                        
-                       if (apply_gain_automation) {
+                       if (apply_gain_automation && _session.transport_rolling()) {
                                _effective_gain = gab[nframes-1];
                        }
                        
@@ -483,7 +499,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
 
        if (post_fader_work) {
 
-               TentativeLockMonitor rm (redirect_lock, __LINE__, __FILE__);
+               TentativeRWLockMonitor rm (redirect_lock, false, __LINE__, __FILE__);
                if (rm.locked()) {
                        if (mute_gain > 0 || !_mute_affects_post_fader) {
                                for (i = _redirects.begin(); i != _redirects.end(); ++i) {
@@ -755,7 +771,7 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
        }
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
 
                PluginInsert* pi;
                PortInsert* porti;
@@ -816,7 +832,7 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
        }
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
 
                RedirectList::iterator existing_end = _redirects.end();
                --existing_end;
@@ -861,7 +877,7 @@ Route::clear_redirects (void *src)
        }
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
 
                for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
                        delete *i;
@@ -891,7 +907,7 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
        redirect_max_outs = 0;
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
                RedirectList::iterator i;
                bool removed = false;
 
@@ -970,7 +986,7 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
 int
 Route::reset_plugin_counts (uint32_t* lpc)
 {
-       LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+       RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
        return _reset_plugin_counts (lpc);
 }
 
@@ -1140,7 +1156,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
        RedirectList to_be_deleted;
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
                RedirectList::iterator tmp;
                RedirectList the_copy;
 
@@ -1219,7 +1235,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
 void
 Route::all_redirects_flip ()
 {
-       LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+       RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
 
        if (_redirects.empty()) {
                return;
@@ -1235,7 +1251,7 @@ Route::all_redirects_flip ()
 void
 Route::all_redirects_active (bool state)
 {
-       LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+       RWLockMonitor lm (redirect_lock, false,  __LINE__, __FILE__);
 
        if (_redirects.empty()) {
                return;
@@ -1257,7 +1273,7 @@ Route::sort_redirects (uint32_t* err_streams)
 {
        {
                RedirectSorter comparator;
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__);
                uint32_t old_rmo = redirect_max_outs;
 
                /* the sweet power of C++ ... */
@@ -1458,7 +1474,7 @@ Route::add_redirect_from_xml (const XMLNode& node)
 
                                } else {
 
-                                       error << compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
+                                       error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
                                }
 
                                add_redirect (insert, this);
@@ -1487,7 +1503,7 @@ Route::set_state (const XMLNode& node)
 
 
        if (node.name() != "Route"){
-               error << compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
+               error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
                return -1;
        }
 
@@ -1546,7 +1562,7 @@ Route::set_state (const XMLNode& node)
        if ((prop = node.property ("edit-group")) != 0) {
                RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
                if(edit_group == 0) {
-                       error << compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
+                       error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
                } else {
                        set_edit_group(edit_group, this);
                }
@@ -1562,11 +1578,11 @@ Route::set_state (const XMLNode& node)
                while (remaining.length()) {
 
                        if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
-                               error << compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
+                               error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
                                      << endmsg;
                        } else {
                                if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
-                                       error << compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
+                                       error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
                                              << endmsg;
                                } else {
                                        set_order_key (remaining.substr (0, equal), n);
@@ -1667,7 +1683,7 @@ Route::set_state (const XMLNode& node)
        if ((prop = node.property ("mix-group")) != 0) {
                RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
                if (mix_group == 0) {
-                       error << compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
+                       error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
                }  else {
                        set_mix_group(mix_group, this);
                }
@@ -1696,7 +1712,7 @@ Route::set_state (const XMLNode& node)
                                if (get_midi_node_info (child, ev, chn, additional)) {
                                        _midi_mute_control.set_control_type (chn, ev, additional);
                                } else {
-                                       error << compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
+                                       error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
                                }
                        }
                        else if (child->name() == "solo") {
@@ -1704,7 +1720,7 @@ Route::set_state (const XMLNode& node)
                                if (get_midi_node_info (child, ev, chn, additional)) {
                                        _midi_solo_control.set_control_type (chn, ev, additional);
                                } else {
-                                       error << compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
+                                       error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
                                }
                        }
 
@@ -1736,7 +1752,7 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
                }
 
                { 
-                       TentativeLockMonitor lm (redirect_lock, __LINE__, __FILE__);
+                       TentativeRWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
                        
                        if (lm.locked()) {
                                for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
@@ -1935,12 +1951,13 @@ Route::transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_re
 {
        jack_nframes_t now = _session.transport_frame();
 
-       if (!did_locate) {
-               automation_snapshot (now);
-       }
-
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
+
+               if (!did_locate) {
+                       automation_snapshot (now);
+               }
+
                for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
                        
                        if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
@@ -2014,7 +2031,7 @@ Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes
        }
 
        apply_gain_automation = false;
-
+       
        if (n_inputs()) {
                passthru (start_frame, end_frame, nframes, offset, 0, false);
        } else {
@@ -2053,26 +2070,34 @@ int
 Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
             bool can_record, bool rec_monitors_input)
 {
-       automation_snapshot (_session.transport_frame());
-
+       {
+               TentativeRWLockMonitor lm(redirect_lock, false, __LINE__, __FILE__);
+               if (lm.locked()) {
+                       // automation snapshot can also be called from the non-rt context
+                       // and it uses the redirect list, so we take the lock out here
+                       automation_snapshot (_session.transport_frame());
+               }
+       }
+               
        if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
                silence (nframes, offset);
                return 0;
        }
        
-       jack_nframes_t unused;
+       jack_nframes_t unused = 0;
 
        if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
                return 0;
        }
 
        _silent = false;
+
        apply_gain_automation = false;
 
        { 
                TentativeLockMonitor am (automation_lock, __LINE__, __FILE__);
                
-               if (am.locked()) {
+               if (am.locked() && _session.transport_rolling()) {
                        
                        jack_nframes_t start_frame = end_frame - nframes;
                        
@@ -2162,7 +2187,7 @@ Route::send_all_midi_feedback ()
        if (_session.get_midi_feedback()) {
 
                {
-                       LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+                       RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
                        for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
                                (*i)->send_all_midi_feedback ();
                        }
@@ -2182,7 +2207,7 @@ Route::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize)
        buf = _midi_mute_control.write_feedback (buf, bufsize, _muted);
 
        {
-               LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
                for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
                        buf = (*i)->write_midi_feedback (buf, bufsize);
                }
@@ -2198,7 +2223,7 @@ Route::flush_redirects ()
           this is called from the RT audio thread.
        */
 
-       LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+       RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
 
        for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
                (*i)->deactivate ();
@@ -2333,7 +2358,8 @@ Route::MIDIToggleControl::send_feedback (bool value)
                if (get_control_info (ch, ev, additional)) {
                        data.controller_number = additional;
                        data.value = val;
-
+                       last_written = value;
+                       
                        route._session.send_midi_message (get_port(), ev, ch, data);
                }
        }