X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_transport.cc;h=f09f3ac2538d2e2bc60571ac646901472d793fbb;hb=eeeb8563c28da3f84467fbd0213684077a00bfaa;hp=e80978a8058d9f7e6e781420eecac1b563cb2183;hpb=7807869a68d3e27d0d088a1c005c25869b4ce2f3;p=ardour.git diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index e80978a805..f09f3ac253 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -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 tr = boost::dynamic_pointer_cast (*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 tr = boost::dynamic_pointer_cast (*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 tr = boost::dynamic_pointer_cast (*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 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 tr = boost::dynamic_pointer_cast (*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 rl = routes.reader(); for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { boost::shared_ptr tr = boost::dynamic_pointer_cast (*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 tr = boost::dynamic_pointer_cast (*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(_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 rl = routes.reader(); for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { boost::shared_ptr tr = boost::dynamic_pointer_cast (*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 () {