various "deep" fixes related to looping, particularly seamless, and transport state

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6013 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-11-04 21:18:37 +00:00
parent c7a1fd3951
commit 36c2cc577d
5 changed files with 29 additions and 19 deletions

View file

@ -1472,7 +1472,14 @@ ARDOUR_UI::transport_roll ()
bool rolling = session->transport_rolling();
if (session->get_play_loop()) {
session->request_play_loop (false, true);
/* XXX it is not possible to just leave seamless loop and keep
playing at present (nov 4th 2009
*/
if (!Config->get_seamless_loop()) {
session->request_play_loop (false, true);
} else {
return;
}
} else if (session->get_play_range ()) {
session->request_play_range (false, true);
}

View file

@ -1452,8 +1452,8 @@ class Session : public PBD::StatefulDestructible
void overwrite_some_buffers (Diskstream*);
void flush_all_redirects ();
int micro_locate (nframes_t distance);
void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
void force_locate (nframes_t frame, bool with_roll = false);
void set_diskstream_speed (Diskstream*, float speed);
void set_transport_speed (float speed, bool abort = false);

View file

@ -985,7 +985,7 @@ AudioDiskstream::seek (nframes_t frame, bool complete_refill)
(*chan)->playback_buf->reset ();
(*chan)->capture_buf->reset ();
}
/* can't rec-enable in destructive mode if transport is before start */
if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
@ -994,7 +994,7 @@ AudioDiskstream::seek (nframes_t frame, bool complete_refill)
playback_sample = frame;
file_frame = frame;
if (complete_refill) {
while ((ret = do_refill_with_alloc ()) > 0) ;
} else {

View file

@ -322,7 +322,7 @@ Session::process_event (Event* ev)
case Event::AutoLoop:
if (play_loop) {
start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
start_locate (ev->target_frame, true, false, true);
}
remove = false;
del = false;

View file

@ -392,8 +392,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
/* explicit return request pre-queued in event list. overrides everything else */
cerr << "explicit auto-return to " << _requested_return_frame << endl;
_transport_frame = _requested_return_frame;
do_locate = true;
@ -455,7 +453,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
/* this for() block can be put inside the previous if() and has the effect of ... ??? what */
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
@ -623,13 +620,15 @@ Session::set_play_loop (bool yn)
Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
merge_event (event);
/* locate to start of loop and roll */
event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
merge_event (event);
/* locate to start of loop and roll. If doing seamless loop, force a
locate+buffer refill even if we are positioned there already.
*/
start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
}
} else {
unset_play_loop ();
}
@ -647,7 +646,7 @@ Session::flush_all_redirects ()
}
void
Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
{
if (synced_to_jack()) {
@ -672,7 +671,7 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
} else {
locate (target_frame, with_roll, with_flush, with_loop);
locate (target_frame, with_roll, with_flush, with_loop, force);
}
}
@ -696,13 +695,13 @@ Session::micro_locate (nframes_t distance)
}
void
Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
{
if (actively_recording() && !with_loop) {
return;
}
if (_transport_frame == target_frame && !loop_changing && !with_loop) {
if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
if (with_roll) {
set_transport_speed (1.0, false);
}
@ -724,12 +723,16 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
}
}
/* stop if we are rolling and we're not doing autoplay and we don't plan to roll when done and we not looping while synced to
jack
*/
if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
realtime_stop (false);
}
if ( !with_loop || loop_changing) {
if (force || !with_loop || loop_changing) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
if (with_roll) {