remove Tracks runtime conditional, incorrectly added during manual merging
[ardour.git] / libs / ardour / session_transport.cc
index b392dabcbf536280c842a7f70b76ba923351d54c..42ef46ca257e34f7a76ef3206050dc1b780a6328 100644 (file)
@@ -314,12 +314,13 @@ Session::butler_transport_work ()
        bool finished;
        PostTransportWork ptw;
        boost::shared_ptr<RouteList> r = routes.reader ();
-
+       uint64_t before;
+       
        int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
        finished = true;
        ptw = post_transport_work();
 
-       DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
+       DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
 
        if (ptw & PostTransportAdjustPlaybackBuffering) {
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -410,7 +411,7 @@ Session::butler_transport_work ()
 
        g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
 
-       DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
+       DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs\n"), g_get_monotonic_time() - before));
        DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
 }
 
@@ -493,6 +494,101 @@ Session::non_realtime_locate ()
        clear_clicks ();
 }
 
+bool
+Session::select_playhead_priority_target (framepos_t& jump_to)
+{
+       jump_to = -1;
+
+       AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
+
+       if (!autoreturn) {
+               return false;
+       }
+
+       if (Profile->get_trx() && transport_rolling() ) {
+               // We're playing, so do nothing.
+               // Next stop will put us where we need to be.
+               return false;
+       }
+       
+       /* Note that the order of checking each AutoReturnTarget flag defines
+          the priority each flag.
+
+          Ardour/Mixbus: Last Locate
+                         Range Selection
+                         Loop Range
+                         Region Selection
+
+          Tracks:        Range Selection
+                          Loop Range
+                          Region Selection
+                          Last Locate
+       */
+       
+#ifndef USE_TRACKS_CODE_FEATURES
+       if (autoreturn & LastLocate) {
+               jump_to = _last_roll_location;
+       }
+       
+       if (jump_to < 0 && (autoreturn & RangeSelectionStart)) {
+#else
+       if (autoreturn & RangeSelectionStart) {
+#endif
+               if (!_range_selection.empty()) {
+                       jump_to = _range_selection.from;
+               } else {
+                       if (transport_rolling ()) {
+                               /* Range selection no longer exists, but we're playing,
+                                  so do nothing. Next stop will put us where
+                                  we need to be.
+                               */
+                               return false;
+                       }
+               }
+       }
+       
+       if (jump_to < 0 && (autoreturn & Loop)) {
+               /* don't try to handle loop play when synced to JACK */
+               
+               if (!synced_to_engine()) {
+                       Location *location = _locations->auto_loop_location();
+                       
+                       if (location) {
+                               jump_to = location->start();
+
+                               if (Config->get_seamless_loop()) {
+                                       /* need to get track buffers reloaded */
+                                       set_track_loop (true);
+                               }
+                       } 
+               }
+       }
+       
+       if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
+               if (!_object_selection.empty()) {
+                       jump_to = _object_selection.from;
+               }
+       } 
+
+#ifdef USE_TRACKS_CODE_FEATURES
+       if (jump_to < 0 && (autoreturn & LastLocate)) {
+               jump_to = _last_roll_location;
+       }
+#endif
+       
+       return jump_to >= 0;
+}
+
+void
+Session::follow_playhead_priority ()
+{
+       framepos_t target;
+
+       if (select_playhead_priority_target (target)) {
+               request_locate (target);
+       }
+}
+
 void
 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 {
@@ -575,8 +671,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                update_latency_compensation ();
        }
 
-       bool const auto_return_enabled =
-               (!config.get_external_sync() && (config.get_auto_return() || abort));
+       bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
 
        if (auto_return_enabled ||
            (ptw & PostTransportLocate) ||
@@ -602,40 +697,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                                do_locate = true;
 
                        } else {
-                               if (config.get_auto_return()) {
-
-                                       if (play_loop) {
-
-                                               /* don't try to handle loop play when synced to JACK */
+                               framepos_t jump_to;
 
-                                               if (!synced_to_engine()) {
+                               if (select_playhead_priority_target (jump_to)) {
 
-                                                       Location *location = _locations->auto_loop_location();
-
-                                                       if (location != 0) {
-                                                               _transport_frame = location->start();
-                                                       } else {
-                                                               _transport_frame = _last_roll_location;
-                                                       }
-                                                       do_locate = true;
-                                               }
-
-                                       } else if (_play_range) {
-
-                                               /* return to start of range */
-
-                                               if (!current_audio_range.empty()) {
-                                                       _transport_frame = current_audio_range.front().start;
-                                                       do_locate = true;
-                                               }
-
-                                       } else {
-
-                                               /* regular auto-return */
+                                       _transport_frame = jump_to;
+                                       do_locate = true;
 
-                                               _transport_frame = _last_roll_location;
-                                               do_locate = true;
-                                       }
                                } else if (abort) {
 
                                        _transport_frame = _last_roll_location;
@@ -1035,8 +1103,9 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
         */
 
        bool transport_was_stopped = !transport_rolling();
-       
-       if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
+
+       if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
+           (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
                realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
                transport_was_stopped = true;
        } else {
@@ -1216,7 +1285,7 @@ Session::set_transport_speed (double speed, framepos_t destination_frame, bool a
                        }
                        _engine.transport_stop ();
                } else {
-                       bool const auto_return_enabled = (!config.get_external_sync() && (config.get_auto_return() || abort));
+                       bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
 
                        if (!auto_return_enabled) {
                                _requested_return_frame = destination_frame;
@@ -1542,6 +1611,13 @@ Session::reset_rf_scale (framecnt_t motion)
        }
 }
 
+void
+Session::mtc_status_changed (bool yn)
+{
+       g_atomic_int_set (&_mtc_active, yn);
+       MTCSyncStateChanged( yn );
+}
+
 void
 Session::use_sync_source (Slave* new_slave)
 {
@@ -1554,6 +1630,18 @@ Session::use_sync_source (Slave* new_slave)
        delete _slave;
        _slave = new_slave;
 
+       MTC_Slave* mtc_slave = dynamic_cast<MTC_Slave*>(_slave);
+       if (mtc_slave) {
+               mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
+               MTCSyncStateChanged(mtc_slave->locked() );
+       } else {
+               if (g_atomic_int_get (&_mtc_active) ){
+                       g_atomic_int_set (&_mtc_active, 0);
+                       MTCSyncStateChanged( false );
+               }
+               mtc_status_connection.disconnect ();
+       }
+
        DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
        
        // need to queue this for next process() cycle
@@ -1789,8 +1877,6 @@ Session::engine_halted ()
        */
 
        if (_butler) {
-               g_atomic_int_set (&_butler->should_do_transport_work, 0);
-               set_post_transport_work (PostTransportWork (0));
                _butler->stop ();
        }
 
@@ -1806,6 +1892,8 @@ Session::engine_halted ()
 void
 Session::xrun_recovery ()
 {
+       ++_xrun_count;
+
        Xrun (_transport_frame); /* EMIT SIGNAL */
 
        if (Config->get_stop_recording_on_xrun() && actively_recording()) {
@@ -1826,6 +1914,12 @@ Session::route_processors_changed (RouteProcessorChange c)
        }
 
        if (c.type == RouteProcessorChange::MeterPointChange) {
+               set_dirty ();
+               return;
+       }
+
+       if (c.type == RouteProcessorChange::RealTimeChange) {
+               set_dirty ();
                return;
        }