summaryrefslogtreecommitdiff
path: root/libs/ardour/session_transport.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-11-06 22:43:47 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-11-06 22:43:47 +0000
commit8bb5605dfc48a9578164e820fb866f0e7881d899 (patch)
tree29171e531c26a0a79513f0b6f06d95d9ce05c494 /libs/ardour/session_transport.cc
parentc3e7746e367b5b461f0577b548c9e29854bdde06 (diff)
deep, somewhat subtle changes for transport control. Everything should use Session::request_stop(), which nows takes an additional argument indicating whether or not to clear play range/loop state. UI threads will generally do so, other things, like slave sync objects, generally will not. also fixed stupid delay on exit, caused by unconditional usleep (2.5 seconds) ...
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6027 d708f5d6-7413-0410-9779-e7cbd77b26cf
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;