sort of no-op ... remove debug output ... just basically put it in git so that i...
[ardour.git] / libs / ardour / session_transport.cc
index e80978a8058d9f7e6e781420eecac1b563cb2183..f09f3ac2538d2e2bc60571ac646901472d793fbb 100644 (file)
@@ -41,6 +41,7 @@
 #include "ardour/butler.h"
 #include "ardour/click.h"
 #include "ardour/debug.h"
+#include "ardour/disk_reader.h"
 #include "ardour/location.h"
 #include "ardour/profile.h"
 #include "ardour/scene_changer.h"
@@ -48,6 +49,8 @@
 #include "ardour/slave.h"
 #include "ardour/tempo.h"
 #include "ardour/operations.h"
+#include "ardour/vca.h"
+#include "ardour/vca_manager.h"
 
 #include "pbd/i18n.h"
 
@@ -74,15 +77,6 @@ Session::add_post_transport_work (PostTransportWork ptw)
        error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
 }
 
-void
-Session::request_input_change_handling ()
-{
-       if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
-               SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
-               queue_event (ev);
-       }
-}
-
 void
 Session::request_sync_source (Slave* new_slave)
 {
@@ -130,14 +124,6 @@ Session::request_transport_speed_nonzero (double speed, bool as_default)
        request_transport_speed (speed, as_default);
 }
 
-void
-Session::request_track_speed (Track* tr, double speed)
-{
-       SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
-       ev->set_ptr (tr);
-       queue_event (ev);
-}
-
 void
 Session::request_stop (bool abort, bool clear_state)
 {
@@ -444,12 +430,6 @@ Session::butler_transport_work ()
        }
 
        if (ptw & PostTransportAdjustPlaybackBuffering) {
-               /* non_realtime_locate() calls Automatable::transport_located()
-                * for every route. This eventually calls
-                * ARDOUR::AutomationList::state () which has a LocaleGuard,
-                * and would switch locales forth/back every time.
-                */
-               LocaleGuard lg;
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                        boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
                        if (tr) {
@@ -458,7 +438,10 @@ Session::butler_transport_work ()
                        }
                        (*i)->non_realtime_locate (_transport_frame);
                }
-
+               VCAList v = _vca_manager->vcas ();
+               for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+                       (*i)->non_realtime_locate (_transport_frame);
+               }
        }
 
        if (ptw & PostTransportAdjustCaptureBuffering) {
@@ -476,15 +459,6 @@ Session::butler_transport_work ()
                }
        }
 
-       if (ptw & PostTransportInputChange) {
-               for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-                       boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
-                       if (tr) {
-                               tr->non_realtime_input_change ();
-                       }
-               }
-       }
-
        if (ptw & PostTransportSpeed) {
                non_realtime_set_speed ();
        }
@@ -498,7 +472,6 @@ Session::butler_transport_work ()
                /* don't seek if locate will take care of that in non_realtime_stop() */
 
                if (!(ptw & PostTransportLocate)) {
-                       LocaleGuard lg; // see note for non_realtime_locate() above
                        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                                (*i)->non_realtime_locate (_transport_frame);
 
@@ -508,6 +481,10 @@ Session::butler_transport_work ()
                                        goto restart;
                                }
                        }
+                       VCAList v = _vca_manager->vcas ();
+                       for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+                               (*i)->non_realtime_locate (_transport_frame);
+                       }
                }
        }
 
@@ -538,8 +515,7 @@ Session::butler_transport_work ()
 
        g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
 
-       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)));
+       DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs @ %2 trw = %3\n"), g_get_monotonic_time() - before, _transport_frame, _butler->transport_work_requested()));
 }
 
 void
@@ -549,7 +525,7 @@ Session::non_realtime_set_speed ()
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
                if (tr) {
-                       tr->non_realtime_set_speed ();
+                       tr->non_realtime_speed_change ();
                }
        }
 }
@@ -607,14 +583,46 @@ Session::non_realtime_locate ()
        }
 
 
+       microseconds_t begin = get_microseconds ();
+       framepos_t tf;
+
        {
-               LocaleGuard lg; // see note for non_realtime_locate() above
                boost::shared_ptr<RouteList> rl = routes.reader();
+
+         restart:
+               gint sc = g_atomic_int_get (&_seek_counter);
+               tf = _transport_frame;
+
+               cerr << "\n\n >>> START Non-RT locate on routes to " << tf << " counter = " << sc << "\n\n";
+
                for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
-                       (*i)->non_realtime_locate (_transport_frame);
+                       (*i)->non_realtime_locate (tf);
+                       //::usleep (250000);
+                       cerr << "\t\tcounter after track: " << g_atomic_int_get (&_seek_counter) << endl;
+                       if (sc != g_atomic_int_get (&_seek_counter)) {
+                               cerr << "\n\n RESTART locate, new seek delivered\n";
+                               goto restart;
+                       }
+               }
+
+               cerr << "\n\n <<< DONE Non-RT locate on routes\n\n";
+       }
+
+       {
+               /* VCAs are quick to locate because they have no data (except
+                  automation) associated with them. Don't bother with a
+                  restart mechanism here, but do use the same transport frame
+                  that the Routes used.
+               */
+               VCAList v = _vca_manager->vcas ();
+               for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+                       (*i)->non_realtime_locate (tf);
                }
        }
 
+       microseconds_t end = get_microseconds ();
+       cerr << "Locate took " << setprecision (3) << ((end - begin) /1000000.0) << " secs\n";
+
        _scene_changer->locate (_transport_frame);
 
        /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
@@ -800,9 +808,15 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
        if (_engine.running()) {
                PostTransportWork ptw = post_transport_work ();
+
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-                       (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
+                       (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
                }
+               VCAList v = _vca_manager->vcas ();
+               for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+                       (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
+               }
+
                update_latency_compensation ();
        }
 
@@ -875,7 +889,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
        /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
 
        {
-               LocaleGuard lg; // see note for non_realtime_locate() above
                DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                        DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
@@ -889,6 +902,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                }
        }
 
+       {
+               VCAList v = _vca_manager->vcas ();
+               for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+                       (*i)->non_realtime_locate (_transport_frame);
+               }
+       }
+
        have_looped = false;
 
        /* don't bother with this stuff if we're disconnected from the engine,
@@ -1022,7 +1042,7 @@ Session::set_track_loop (bool yn)
 
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
-               if (tr && !tr->hidden()) {
+               if (tr && !tr->is_private_route()) {
                        tr->set_loop (yn ? loc : 0);
                }
        }
@@ -1228,12 +1248,18 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
                        pending_locate_frame = target_frame;
                        pending_locate_roll = with_roll;
                        pending_locate_flush = with_flush;
+                       cerr << "Declick scheduled ... back soon\n";
                        return;
                }
        }
 
+       cerr << "... now doing the actual locate\n";
+
        // Update Timecode time
        _transport_frame = target_frame;
+       // Bump seek counter so that any in-process locate in the butler
+       // thread(s?) can restart.
+       g_atomic_int_inc (&_seek_counter);
        _last_roll_or_reversal_location = target_frame;
        timecode_time(_transport_frame, transmitting_timecode_time);
 
@@ -1367,7 +1393,9 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
        }
 
        _last_roll_location = _last_roll_or_reversal_location =  _transport_frame;
-       Located (); /* EMIT SIGNAL */
+       if (!synced_to_engine () || _transport_frame == _engine.transport_frame ()) {
+               Located (); /* EMIT SIGNAL */
+       }
 }
 
 /** Set the transport speed.
@@ -1518,7 +1546,7 @@ Session::set_transport_speed (double speed, framepos_t destination_frame, bool a
                boost::shared_ptr<RouteList> rl = routes.reader();
                for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
                        boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
-                       if (tr && tr->realtime_set_speed (tr->speed(), true)) {
+                       if (tr && tr->realtime_speed_change()) {
                                todo = PostTransportWork (todo | PostTransportSpeed);
                        }
                }
@@ -1682,7 +1710,7 @@ Session::start_transport ()
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
                if (tr) {
-                       tr->realtime_set_speed (tr->speed(), true);
+                       tr->realtime_speed_change ();
                }
        }
 
@@ -1816,6 +1844,12 @@ Session::use_sync_source (Slave* new_slave)
        delete _slave;
        _slave = new_slave;
 
+
+       /* slave change, reset any DiskIO block on disk output because it is no
+          longer valid with a new slave.
+       */
+       DiskReader::set_no_disk_output (false);
+
        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));
@@ -1848,8 +1882,8 @@ Session::use_sync_source (Slave* new_slave)
        boost::shared_ptr<RouteList> rl = routes.reader();
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
-               if (tr && !tr->hidden()) {
-                       if (tr->realtime_set_speed (tr->speed(), true)) {
+               if (tr && !tr->is_private_route()) {
+                       if (tr->realtime_speed_change()) {
                                non_rt_required = true;
                        }
                        tr->set_slaved (_slave != 0);
@@ -1941,16 +1975,6 @@ Session::switch_to_sync_source (SyncSource src)
        request_sync_source (new_slave);
 }
 
-void
-Session::set_track_speed (Track* track, double speed)
-{
-       if (track->realtime_set_speed (speed, false)) {
-               add_post_transport_work (PostTransportSpeed);
-               _butler->schedule_transport_work ();
-               set_dirty ();
-       }
-}
-
 void
 Session::unset_play_range ()
 {