Merge with trunk R2920.
[ardour.git] / libs / ardour / session_transport.cc
index 52f6346789b3de1db2b42fd6bb4ca149e9dbbbf3..d422698f302c2e626c4b4961e13d31edea8bbdf4 100644 (file)
@@ -29,6 +29,7 @@
 #include <glibmm/thread.h>
 #include <pbd/pthread_utils.h>
 #include <pbd/memento_command.h>
+#include <pbd/stacktrace.h>
 
 #include <midi++/mmc.h>
 #include <midi++/port.h>
@@ -54,7 +55,7 @@ Session::request_input_change_handling ()
        if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
                Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
                queue_event (ev);
-       }
+       } 
 }
 
 void
@@ -238,8 +239,12 @@ Session::butler_transport_work ()
                        }
                }
        }
+       
+       if (post_transport_work & PostTransportLocate) {
+               non_realtime_locate ();
+       }
 
-       if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
+       if (post_transport_work & PostTransportStop) {
                non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
                if (!finished) {
                        g_atomic_int_dec_and_test (&butler_should_do_transport_work);
@@ -288,6 +293,18 @@ Session::non_realtime_overwrite (int on_entry, bool& finished)
        }
 }
 
+       
+void
+Session::non_realtime_locate ()
+{
+       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+               (*i)->non_realtime_locate (_transport_frame);
+       }
+}
+
+
 void
 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 {
@@ -363,7 +380,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
        boost::shared_ptr<RouteList> r = routes.reader ();
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if (!(*i)->hidden()) {
+               if (!(*i)->is_hidden()) {
                        (*i)->set_pending_declick (0);
                }
        }
@@ -376,17 +393,35 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                update_latency_compensation (true, abort);
        }
 
-       if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
+       if ((Config->get_slave_source() == None && Config->get_auto_return()) || 
+           (post_transport_work & PostTransportLocate) || 
+           (_requested_return_frame >= 0) ||
+           synced_to_jack()) {
                
                if (pending_locate_flush) {
                        flush_all_inserts ();
                }
                
-               if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
+               if (((Config->get_slave_source() == None && Config->get_auto_return()) || 
+                    synced_to_jack() ||
+                    _requested_return_frame >= 0) &&
+                   !(post_transport_work & PostTransportLocate)) {
 
-                       _transport_frame = last_stop_frame;
+                       bool do_locate = false;
+
+                       if (_requested_return_frame >= 0) {
+                               _transport_frame = _requested_return_frame;
+                               _requested_return_frame = -1;
+                               do_locate = true;
+                       } else {
+                               _transport_frame = last_stop_frame;
+                       }
 
                        if (synced_to_jack() && !play_loop) {
+                               do_locate = true;
+                       }
+                       
+                       if (do_locate) {
                                // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
                                _engine.transport_locate (_transport_frame);
                        }
@@ -462,7 +497,9 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                
        }
 
-       PositionChanged (_transport_frame); /* EMIT SIGNAL */
+        nframes_t tf = _transport_frame;
+
+        PositionChanged (tf); /* EMIT SIGNAL */
        TransportStateChange (); /* EMIT SIGNAL */
 
        /* and start it up again if relevant */
@@ -1186,6 +1223,14 @@ Session::setup_auto_play ()
        merge_event (ev);
 }
 
+void
+Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
+{
+       request_locate (start, false);
+       Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
+       queue_event (ev);
+}
+
 void
 Session::request_bounded_roll (nframes_t start, nframes_t end)
 {
@@ -1262,7 +1307,7 @@ Session::update_latency_compensation (bool with_stop, bool abort)
                        update_jack = true;
                }
 
-               if (!(*i)->hidden() && ((*i)->active())) {
+               if (!(*i)->is_hidden() && ((*i)->active())) {
                        _worst_track_latency = max (_worst_track_latency, track_latency);
                }
        }