X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_transport.cc;h=51734a06c0ba4a280e0b737556a20d4095eba86f;hb=46c83693284ece4a732d26e62113ea4ac584d539;hp=711c3e51e71eeca640df6f9717511a12da021e23;hpb=1caf54ee7f6754181037a6a05a5667acd0b3e9b1;p=ardour.git diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 711c3e51e7..51734a06c0 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -314,12 +314,13 @@ Session::butler_transport_work () bool finished; PostTransportWork ptw; boost::shared_ptr 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 at %2\n", enum_2_string (ptw), g_get_monotonic_time())); + 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, string_compose (X_("Butler transport work all done at %1\n"), g_get_monotonic_time())); + 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,106 @@ Session::non_realtime_locate () clear_clicks (); } +#ifdef USE_TRACKS_CODE_FEATURES +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 + */ + + if (autoreturn & RangeSelectionStart) { + 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) && get_play_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; + } + } + + if (jump_to < 0 && (autoreturn & LastLocate)) { + jump_to = _last_roll_location; + } + + return jump_to >= 0; +} +#else + +bool +Session::select_playhead_priority_target (framepos_t& jump_to) +{ + if (!config.get_auto_return()) { + return false; + } + + jump_to = _last_roll_location; + return jump_to >= 0; +} + +#endif + +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 +676,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 +702,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) do_locate = true; } else { - if (config.get_auto_return()) { + framepos_t jump_to; - if (play_loop) { + if (select_playhead_priority_target (jump_to)) { - /* don't try to handle loop play when synced to JACK */ - - if (!synced_to_engine()) { - - 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; @@ -1217,7 +1290,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; @@ -1550,6 +1623,13 @@ Session::mtc_status_changed (bool yn) MTCSyncStateChanged( yn ); } +void +Session::ltc_status_changed (bool yn) +{ + g_atomic_int_set (&_ltc_active, yn); + LTCSyncStateChanged( yn ); +} + void Session::use_sync_source (Slave* new_slave) { @@ -1574,6 +1654,18 @@ Session::use_sync_source (Slave* new_slave) mtc_status_connection.disconnect (); } + LTC_Slave* ltc_slave = dynamic_cast (_slave); + if (ltc_slave) { + ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1)); + LTCSyncStateChanged (ltc_slave->locked() ); + } else { + if (g_atomic_int_get (&_ltc_active) ){ + g_atomic_int_set (&_ltc_active, 0); + LTCSyncStateChanged( false ); + } + ltc_status_connection.disconnect (); + } + DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave)); // need to queue this for next process() cycle