fix #4405, by explicitly cancelling solo when a route's inputs drop to zero
[ardour.git] / libs / ardour / session_transport.cc
index 78b675de0eda514bb13e9702b1e266fa5f3b0d20..6347c553a9759f523518d10f1e52a2231fb00dfd 100644 (file)
@@ -40,6 +40,7 @@
 #include "ardour/audioengine.h"
 #include "ardour/auditioner.h"
 #include "ardour/butler.h"
+#include "ardour/click.h"
 #include "ardour/debug.h"
 #include "ardour/location.h"
 #include "ardour/session.h"
@@ -196,7 +197,7 @@ Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
 void
 Session::realtime_stop (bool abort, bool clear_state)
 {
-       DEBUG_TRACE (DEBUG::Transport, "realtime stop\n");
+       DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
        PostTransportWork todo = PostTransportWork (0);
 
        /* assume that when we start, we'll be moving forwards */
@@ -425,6 +426,12 @@ Session::non_realtime_locate ()
                        tr->non_realtime_locate (_transport_frame);
                }
        }
+
+       /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
+          rather than clearing them so that the RT thread has to spend time constructing
+          them (in Session::click).
+        */
+       clear_clicks ();
 }
 
 
@@ -458,7 +465,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                auditioner->cancel_audition ();
        }
 
-       clear_clicks();
        cumulative_rf_motion = 0;
        reset_rf_scale (0);
 
@@ -581,6 +587,8 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
        }
 
+       clear_clicks();
+
        /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
        */
 
@@ -951,12 +959,18 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
 void
 Session::set_transport_speed (double speed, bool abort, bool clear_state)
 {
-       DEBUG_TRACE (DEBUG::Transport, string_compose ("Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", speed, abort, clear_state, _transport_speed));
+       DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", 
+                                                      speed, abort, clear_state, _transport_speed, _transport_frame));
 
        if (_transport_speed == speed) {
                return;
        }
 
+       if (actively_recording() && speed != 1.0 && speed != 0.0) {
+               /* no varispeed during recording */
+               return;
+       }
+
        _target_transport_speed = fabs(speed);
 
        /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
@@ -1090,6 +1104,11 @@ Session::stop_transport (bool abort, bool clear_state)
                   and then we'll really be stopped.
                */
 
+               DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
+                                                              _transport_frame, _worst_input_latency, current_block_size,
+                                                              _transport_frame - _worst_input_latency - current_block_size,
+                                                              abort));
+
                SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
                                                     _transport_frame + _worst_input_latency - current_block_size,
                                                     0, 0, abort);
@@ -1330,13 +1349,6 @@ Session::switch_to_sync_source (SyncSource src)
        request_sync_source (new_slave);
 }
 
-void
-Session::reverse_track_buffers ()
-{
-       add_post_transport_work (PostTransportReverse);
-       _butler->schedule_transport_work ();
-}
-
 void
 Session::set_track_speed (Track* track, double speed)
 {
@@ -1492,6 +1504,10 @@ Session::xrun_recovery ()
 void
 Session::route_processors_changed (RouteProcessorChange c)
 {
+       if (ignore_route_processor_changes) {
+               return;
+       }
+
        if (c.type == RouteProcessorChange::MeterPointChange) {
                return;
        }