summaryrefslogtreecommitdiff
path: root/libs/ardour/session_transport.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/session_transport.cc')
-rw-r--r--libs/ardour/session_transport.cc91
1 files changed, 54 insertions, 37 deletions
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 7c2eba1a61..41b4bcd0a6 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -97,9 +97,9 @@ Session::request_diskstream_speed (Diskstream& ds, float speed)
}
void
-Session::request_stop (bool abort)
+Session::request_stop (bool abort, bool clear_state)
{
- Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
+ Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort, clear_state);
queue_event (ev);
}
@@ -140,14 +140,23 @@ Session::request_play_loop (bool yn, bool leave_rolling)
}
void
-Session::realtime_stop (bool abort)
+Session::request_play_range (bool yn, bool leave_rolling)
+{
+ Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
+ queue_event (ev);
+}
+
+void
+Session::realtime_stop (bool abort, bool clear_state)
{
+ PostTransportWork todo = PostTransportWork (0);
+
/* assume that when we start, we'll be moving forwards */
if (_transport_speed < 0.0f) {
- post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
+ todo = PostTransportWork (todo | PostTransportStop | PostTransportReverse);
} else {
- post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
+ todo = PostTransportWork (todo | PostTransportStop);
}
if (actively_recording()) {
@@ -163,13 +172,21 @@ Session::realtime_stop (bool abort)
/* the duration change is not guaranteed to have happened, but is likely */
- post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
+ todo = PostTransportWork (todo | PostTransportDuration);
}
if (abort) {
- post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
+ todo = PostTransportWork (todo | PostTransportAbort);
}
+ if (clear_state) {
+ todo = PostTransportWork (todo | PostTransportClearSubstate);
+ }
+
+ if (todo) {
+ post_transport_work = PostTransportWork (post_transport_work | todo);
+ }
+
_clear_event_type (Event::StopOnce);
_clear_event_type (Event::RangeStop);
_clear_event_type (Event::RangeLocate);
@@ -451,11 +468,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
}
- /* unconditionally reset these flags. if play_loop is still true then Diskstream::seek() will do
- the wrong thing in seamless loop mode.
+ /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
*/
- if (post_transport_work & PostTransportStop) {
+ if (post_transport_work & PostTransportClearSubstate) {
_play_range = false;
unset_play_loop ();
}
@@ -552,7 +568,7 @@ Session::check_declick_out ()
start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
} else {
- stop_transport (pending_abort);
+ stop_transport (pending_abort, pending_clear_substate);
transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
}
}
@@ -580,11 +596,8 @@ Session::set_play_loop (bool yn)
Location *loc;
- if (yn == play_loop) {
- return;
- }
-
- if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
+ 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;
}
@@ -671,11 +684,10 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
*/
_engine.transport_locate (target_frame);
+ }
- if (sp != 1.0f && with_roll) {
- _engine.transport_start ();
- }
-
+ if (sp != 1.0f && with_roll) {
+ _engine.transport_start ();
}
} else {
@@ -737,7 +749,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
*/
if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
- realtime_stop (false);
+ realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
}
if (force || !with_loop || loop_changing) {
@@ -825,7 +837,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
}
void
-Session::set_transport_speed (float speed, bool abort)
+Session::set_transport_speed (float speed, bool abort, bool clear_state)
{
if (_transport_speed == speed) {
return;
@@ -852,9 +864,16 @@ Session::set_transport_speed (float speed, bool abort)
}
if (synced_to_jack ()) {
+ if (clear_state) {
+ /* do this here because our response to the slave won't
+ take care of it.
+ */
+ _play_range = false;
+ unset_play_loop ();
+ }
_engine.transport_stop ();
} else {
- stop_transport (abort);
+ stop_transport (abort, clear_state);
}
} else if (transport_stopped() && speed == 1.0) {
@@ -911,8 +930,10 @@ Session::set_transport_speed (float speed, bool abort)
before the last stop, then we have to do extra work.
*/
+ PostTransportWork todo = PostTransportWork (0);
+
if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
- post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
+ todo = PostTransportWork (todo | PostTransportReverse);
last_stop_frame = _transport_frame;
}
@@ -922,18 +943,20 @@ Session::set_transport_speed (float speed, bool abort)
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
- post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
+ todo = PostTransportWork (todo | PostTransportSpeed);
+ break;
}
}
- if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
+ if (todo) {
+ post_transport_work = PostTransportWork (post_transport_work | todo);
schedule_butler_transport_work ();
}
}
}
void
-Session::stop_transport (bool abort)
+Session::stop_transport (bool abort, bool clear_state)
{
if (_transport_speed == 0.0f) {
return;
@@ -958,18 +981,19 @@ Session::stop_transport (bool abort)
merge_event (ev);
transport_sub_state |= StopPendingCapture;
pending_abort = abort;
+ pending_clear_substate = clear_state;
return;
}
-
if ((transport_sub_state & PendingDeclickOut) == 0) {
transport_sub_state |= PendingDeclickOut;
/* we'll be called again after the declick */
pending_abort = abort;
+ pending_clear_substate = clear_state;
return;
}
- realtime_stop (abort);
+ realtime_stop (abort, clear_state);
schedule_butler_transport_work ();
}
@@ -1168,13 +1192,6 @@ Session::set_audio_range (list<AudioRange>& range)
}
void
-Session::request_play_range (bool yn, bool leave_rolling)
-{
- Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
- queue_event (ev);
-}
-
-void
Session::set_play_range (bool yn, bool leave_rolling)
{
/* Called from event-processing context */
@@ -1291,7 +1308,7 @@ Session::engine_halted ()
post_transport_work = PostTransportWork (0);
stop_butler ();
- realtime_stop (false);
+ realtime_stop (false, true);
non_realtime_stop (false, 0, ignored);
transport_sub_state = 0;