changes to use overwrite-buffers when loop is disabled or loop range changed
This commit is contained in:
parent
551702b9e9
commit
8b4e714006
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
// schedule a locate-roll to refill the diskstreams at the
|
||||
// previous loop end
|
||||
|
||||
loop_changing = true;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// schedule a buffer overwrite to refill buffers with the new loop.
|
||||
|
||||
request_overwrite_buffer (boost::shared_ptr<Track>());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue