WIP - Experimenting with an alternative clock generating algo
[ardour.git] / libs / ardour / session_transport.cc
index 7502ded28851e0a2d152d6179823852b2af9b570..51d8d2c369f57fb2131bf4c3960ba85c75412a16 100644 (file)
@@ -99,6 +99,7 @@ Session::request_sync_source (Slave* new_slave)
        _was_seamless = seamless;
 
        ev->slave = new_slave;
+       DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
        queue_event (ev);
 }
 
@@ -203,6 +204,7 @@ Session::realtime_stop (bool abort, bool clear_state)
 
        if (_transport_speed < 0.0f) {
                todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
+               _default_transport_speed = 1.0;
        } else {
                todo = PostTransportWork (todo | PostTransportStop);
        }
@@ -382,6 +384,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, X_(string_compose ("Frame %1\n", _transport_frame)));
 }
 
 void
@@ -489,7 +492,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)->is_hidden()) {
+               if (!(*i)->is_auditioner()) {
                        (*i)->set_pending_declick (0);
                }
        }
@@ -617,9 +620,19 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
        }
 
        if ((ptw & PostTransportLocate) && get_record_enabled()) {
-               /* capture start has been changed, so save pending state */
-               save_state ("", true);
-               saved = true;
+               /* This is scheduled by realtime_stop(), which is also done
+                * when a slave requests /locate/ for an initial sync.
+                * We can't hold up the slave for long with a save() here,
+                * without breaking its initial sync cycle.
+                *
+                * save state only if there's no slave or if it's not yet locked.
+                */
+               if (!_slave || !_slave->locked()) {
+                       DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n"));
+                       /* capture start has been changed, so save pending state */
+                       save_state ("", true);
+                       saved = true;
+               }
        }
 
        /* always try to get rid of this */
@@ -645,8 +658,12 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
        if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
                request_transport_speed (1.0);
-               pending_locate_roll = false;
        }
+
+       /* Even if we didn't do a pending locate roll this time, we don't want it hanging
+          around for next time.
+       */
+       pending_locate_roll = false;
 }
 
 void
@@ -850,7 +867,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
         * though, is all the housekeeping that is associated with non-linear
         * changes in the value of _transport_frame. 
         */
-        
+
        if (actively_recording() && !for_seamless_loop) {
                return;
        }
@@ -991,6 +1008,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
                send_mmc_locate (_transport_frame);
        }
 
+       _last_roll_location = _last_roll_or_reversal_location =  _transport_frame;
        Located (); /* EMIT SIGNAL */
 }
 
@@ -1001,15 +1019,20 @@ 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, bool as_default)
 {
-       DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %5\n", 
+       DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n", 
                                                       speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
 
        if (_transport_speed == speed) {
+               if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
+                       _default_transport_speed = 1.0;
+               }
                return;
        }
 
        if (actively_recording() && speed != 1.0 && speed != 0.0) {
                /* no varispeed during recording */
+               DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n", 
+                                                      _transport_speed, _transport_frame));
                return;
        }
 
@@ -1314,6 +1337,8 @@ Session::use_sync_source (Slave* new_slave)
        delete _slave;
        _slave = new_slave;
 
+       DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
+
        send_full_time_code (_transport_frame);
 
        boost::shared_ptr<RouteList> rl = routes.reader();
@@ -1363,6 +1388,21 @@ Session::switch_to_sync_source (SyncSource src)
                }
                break;
 
+       case LTC:
+               if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
+                       return;
+               }
+
+               try {
+                       new_slave = new LTC_Slave (*this);
+               }
+
+               catch (failed_constructor& err) {
+                       return;
+               }
+
+               break;
+
        case MIDIClock:
                if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
                        return;