From aa5cf04ca61e9d20953f2aacd516acdd709a8a0c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 13 Feb 2015 15:27:53 -0500 Subject: [PATCH] correctly set track loop status when locating away from loop range (and later, when coming back to the loop) Conflicts: libs/ardour/ardour/session.h libs/ardour/session.cc libs/ardour/session_transport.cc --- libs/ardour/ardour/session.h | 3 +- libs/ardour/audio_diskstream.cc | 1 + libs/ardour/session.cc | 3 +- libs/ardour/session_transport.cc | 48 ++++++++++++++++++++------------ 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 4008ddbef4..e45036a094 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1360,7 +1360,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void post_transport (); void engine_halted (); void xrun_recovery (); - + void set_track_loop (bool); + /* These are synchronous and so can only be called from within the process * cycle */ diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 4facf5db64..cf3f550ac4 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -995,6 +995,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, if (loc && start >= loop_end) { start = loop_start + ((start - loop_start) % loop_length); } + } if (reversed) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 67ce7e6e53..52c9506c54 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1439,7 +1439,8 @@ void Session::location_removed (Location *location) { if (location->is_auto_loop()) { - set_auto_loop_location (0); + set_auto_loop_location (0); + set_track_loop (false); } if (location->is_auto_punch()) { diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 9750d91ce8..79390599d5 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -384,6 +384,7 @@ Session::butler_transport_work () } if (ptw & PostTransportLocate) { + DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n"); non_realtime_locate (); } @@ -445,6 +446,18 @@ Session::non_realtime_overwrite (int on_entry, bool& finished) void Session::non_realtime_locate () { + DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_frame)); + + if (Config->get_loop_is_mode() && get_play_loop()) { + Location *loc = _locations->auto_loop_location(); + if (!loc || (_transport_frame < loc->start() || _transport_frame >= loc->end())) { + /* jumped out of loop range: stop tracks from looping, + but leave loop (mode) enabled. + */ + set_track_loop (false); + } + } + boost::shared_ptr rl = routes.reader(); for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { (*i)->non_realtime_locate (_transport_frame); @@ -459,7 +472,6 @@ Session::non_realtime_locate () clear_clicks (); } - void Session::non_realtime_stop (bool abort, int on_entry, bool& finished) { @@ -752,13 +764,24 @@ Session::unset_play_loop () play_loop = false; clear_events (SessionEvent::AutoLoop); clear_events (SessionEvent::AutoLoopDeclick); + set_track_loop (false); +} +void +Session::set_track_loop (bool yn) +{ + Location* loc = _locations->auto_loop_location (); + + if (!loc) { + yn = false; + } + // set all tracks to NOT use internal looping 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()) { - tr->set_loop (0); + tr->set_loop (yn ? loc : 0); } } } @@ -793,23 +816,10 @@ Session::set_play_loop (bool yn, double speed) if (Config->get_seamless_loop()) { // set all tracks to use internal looping - 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()) { - tr->set_loop (loc); - } - } - } - else { + set_track_loop (true); + } else { // set all tracks to NOT use internal looping - 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()) { - tr->set_loop (0); - } - } + set_track_loop (false); } /* Put the delick and loop events in into the event list. The declick event will @@ -1043,6 +1053,8 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool if (!Config->get_loop_is_mode()) { set_play_loop (false, _transport_speed); + } else { + /* handled in ::non_realtime_locate() */ } } else if (_transport_frame == al->start()) {