summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2019-12-05 13:00:24 -0700
committerPaul Davis <paul@linuxaudiosystems.com>2019-12-05 13:13:16 -0700
commit8b4e71400695acd1dad3598965e92455272c0562 (patch)
tree005b3ba56852be841a0224a1c013c9c754b0502b
parent551702b9e9e8766ba2f9723d23585c914803bf89 (diff)
changes to use overwrite-buffers when loop is disabled or loop range changed
-rw-r--r--libs/ardour/ardour/session.h4
-rw-r--r--libs/ardour/session.cc23
-rw-r--r--libs/ardour/session_butler.cc7
-rw-r--r--libs/ardour/session_process.cc6
-rw-r--r--libs/ardour/session_transport.cc141
5 files changed, 89 insertions, 92 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 3a3f16dfdf..6c34a1b93f 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1683,8 +1683,8 @@ private:
bool should_ignore_transport_request (TransportRequestSource, TransportRequestType) const;
- void set_play_loop (bool yn);
- void unset_play_loop ();
+ void set_play_loop (bool yn, bool change_transport_state);
+ void unset_play_loop (bool change_transport_state = false);
void overwrite_some_buffers (boost::shared_ptr<Route>);
void flush_all_inserts ();
int micro_locate (samplecnt_t distance);
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index d5579eb6fc..7e107b3056 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1425,28 +1425,29 @@ Session::auto_loop_changed (Location* location)
(*i)->reload_loop ();
}
+
if (rolling) {
if (play_loop) {
+ /* Set this so that when/if we have to stop the
+ * transport for a locate, we know that it is triggered
+ * by loop-changing, and we do not cancel play loop
+ */
+
+ loop_changing = true;
+
if (_transport_sample < location->start() || _transport_sample > location->end()) {
// new loop range excludes current transport
// sample => relocate to beginning of loop and roll.
- request_locate (location->start(), true);
- } else if (!loop_changing) {
+ request_locate (location->start(), true);
- // schedule a locate-roll to refill the diskstreams at the
- // previous loop end
+ }
- loop_changing = true;
+ // schedule a buffer overwrite to refill buffers with the new loop.
- if (location->end() > last_loopend) {
- clear_events (SessionEvent::LocateRoll);
- SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
- queue_event (ev);
- }
- }
+ request_overwrite_buffer (boost::shared_ptr<Track>());
}
} else {
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index b36d5459f3..0e9aa128dd 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -89,10 +89,15 @@ Session::request_overwrite_buffer (boost::shared_ptr<Track> t)
queue_event (ev);
}
-/** Process thread. */
void
Session::overwrite_some_buffers (boost::shared_ptr<Route> r)
{
+ /* this is called from the process thread while handling queued
+ * SessionEvents. Therefore neither playback sample or read offsets in
+ * tracks will change while we "queue" them all for an upcoming
+ * overwrite.
+ */
+
if (actively_recording()) {
return;
}
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 020deb41e9..a7e8a068af 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -852,7 +852,7 @@ Session::process_event (SessionEvent* ev)
switch (ev->type) {
case SessionEvent::SetLoop:
- set_play_loop (ev->yes_or_no);
+ set_play_loop (ev->yes_or_no, true);
break;
case SessionEvent::AutoLoop:
@@ -937,6 +937,10 @@ Session::process_event (SessionEvent* ev)
overwrite_some_buffers (ev->track);
break;
+ case SessionEvent::OverwriteAll:
+ overwrite_some_buffers (boost::shared_ptr<Route>());
+ break;
+
case SessionEvent::Audition:
set_audition (ev->region);
// drop reference to region
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 6d9f99127a..6fd3114be6 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -302,7 +302,7 @@ Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, boo
have_looped = false;
if (!Config->get_loop_is_mode()) {
- set_play_loop (false);
+ set_play_loop (false, false);
} else {
/* this will make the non_realtime_locate() in the butler
which then causes seek() in tracks actually do the right
@@ -808,63 +808,10 @@ Session::flush_all_inserts ()
}
}
-void
-Session::set_play_loop (bool yn)
-{
- ENSURE_PROCESS_THREAD;
- /* Called from event-handling context */
-
- DEBUG_TRACE (DEBUG::Transport, string_compose ("set_play_loop (%1)\n", yn));
-
- Location *loc;
-
- if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
- /* nothing to do, or can't change loop status while recording */
- return;
- }
-
- if (yn && synced_to_engine()) {
- warning << string_compose (
- _("Looping cannot be supported while %1 is using JACK transport.\n"
- "Recommend changing the configured options"), PROGRAM_NAME)
- << endmsg;
- return;
- }
-
- if (yn) {
-
- play_loop = true;
- have_looped = false;
-
- if (loc) {
-
- unset_play_range ();
- /* set all tracks to use internal looping */
- set_track_loop (true);
-
- merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
-
- if (!Config->get_loop_is_mode()) {
- /* args: positition, roll=true, flush=true, for_loop_end=false, force buffer, refill looping */
-
- TFSM_LOCATE (loc->start(), true, true, false, true);
- }
- }
-
- } else {
-
- unset_play_loop ();
- }
-
- DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
- TransportStateChange ();
-}
-
/* *****************************************************************************
* END REALTIME ACTIONS
* ****************************************************************************/
-
void
Session::add_post_transport_work (PostTransportWork ptw)
{
@@ -1069,28 +1016,9 @@ Session::request_play_loop (bool yn, bool change_transport_roll)
target_speed = transport_speed ();
}
- ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
+ ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn, change_transport_roll);
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
queue_event (ev);
-
- if (yn) {
-
- if (!change_transport_roll) {
- if (!Config->get_loop_is_mode() && !transport_rolling()) {
- /* we're not changing transport state, but we do want
- to set up position for the new loop. Don't
- do this if we're rolling already.
- */
- request_locate (location->start(), false);
- }
- }
- } else {
- if (!change_transport_roll && transport_rolling()) {
- // request an immediate locate to refresh the tracks
- // after disabling looping
- request_locate (_transport_sample-1, false);
- }
- }
}
void
@@ -1646,15 +1574,74 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
}
void
-Session::unset_play_loop ()
+Session::set_play_loop (bool yn, bool change_transport_state)
+{
+ ENSURE_PROCESS_THREAD;
+ /* Called from event-handling context */
+
+ DEBUG_TRACE (DEBUG::Transport, string_compose ("set_play_loop (%1)\n", yn));
+
+ Location *loc;
+
+ if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
+ /* nothing to do, or can't change loop status while recording */
+ return;
+ }
+
+ if (yn && synced_to_engine()) {
+ warning << string_compose (
+ _("Looping cannot be supported while %1 is using JACK transport.\n"
+ "Recommend changing the configured options"), PROGRAM_NAME)
+ << endmsg;
+ return;
+ }
+
+ if (yn) {
+
+ play_loop = true;
+ have_looped = false;
+
+ if (loc) {
+
+ unset_play_range ();
+ /* set all tracks to use internal looping */
+ set_track_loop (true);
+
+ merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
+
+ if (!Config->get_loop_is_mode() && !transport_rolling()) {
+ /* args: positition, roll=true, flush=true, for_loop_end=false, force buffer, refill looping */
+
+ TFSM_LOCATE (loc->start(), true, true, false, true);
+ }
+ }
+
+ } else {
+
+ unset_play_loop ();
+ }
+
+ DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
+ TransportStateChange ();
+}
+
+void
+Session::unset_play_loop (bool change_transport_state)
{
if (play_loop) {
+
play_loop = false;
clear_events (SessionEvent::AutoLoop);
set_track_loop (false);
+
/* likely need to flush track buffers: this will locate us to wherever we are */
- add_post_transport_work (PostTransportLocate);
- TFSM_EVENT (TransportFSM::ButlerRequired);
+
+ if (change_transport_state && transport_rolling ()) {
+ TFSM_EVENT (TransportFSM::StopTransport);
+ }
+
+ overwrite_some_buffers (boost::shared_ptr<Route>());
+
TransportStateChange (); /* EMIT SIGNAL */
}
}