diff options
Diffstat (limited to 'libs/ardour/session_transport.cc')
-rw-r--r-- | libs/ardour/session_transport.cc | 143 |
1 files changed, 99 insertions, 44 deletions
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index e53aa4d5d3..8ab2523119 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -67,9 +67,8 @@ Session::request_slave_source (SlaveSource src) if (src == JACK) { /* could set_seamless_loop() be disposed of entirely?*/ Config->set_seamless_loop (false); - } else { - Config->set_seamless_loop (true); } + ev->slave = src; queue_event (ev); } @@ -111,7 +110,7 @@ Session::force_locate (nframes_t target_frame, bool with_roll) } void -Session::request_play_loop (bool yn) +Session::request_play_loop (bool yn, bool leave_rolling) { Event* ev; Location *location = _locations.auto_loop_location(); @@ -122,10 +121,10 @@ Session::request_play_loop (bool yn) return; } - ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn); + ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); queue_event (ev); - if (!yn && Config->get_seamless_loop() && transport_rolling()) { + if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) { // request an immediate locate to refresh the diskstreams // after disabling looping request_locate (_transport_frame-1, false); @@ -402,28 +401,69 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) && !(post_transport_work & PostTransportLocate)) { + /* no explicit locate queued */ + bool do_locate = false; if (_requested_return_frame >= 0) { + + /* 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; - _requested_return_frame = -1; do_locate = true; + } else { - _transport_frame = _last_roll_location; - } + if (config.get_auto_return()) { - if (synced_to_jack() && !play_loop) { - do_locate = true; + if (play_loop) { + + /* don't try to handle loop play when synced to JACK */ + + if (!synced_to_jack()) { + + Location *location = _locations.auto_loop_location(); + + if (location != 0) { + _transport_frame = location->start(); + } else { + _transport_frame = _last_roll_location; + } + do_locate = true; + } + + } else if (_play_range) { + + /* return to start of range */ + + if (!current_audio_range.empty()) { + _transport_frame = current_audio_range.front().start; + do_locate = true; + } + + } else { + + /* regular auto-return */ + + _transport_frame = _last_roll_location; + do_locate = true; + } + } } + _requested_return_frame = -1; + if (do_locate) { - // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl; _engine.transport_locate (_transport_frame); } - } + } } + /* 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()) { (*i)->non_realtime_locate (_transport_frame); @@ -480,9 +520,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if (post_transport_work & PostTransportStop) { _play_range = false; - - /* do not turn off autoloop on stop */ - + play_loop = false; } nframes_t tf = _transport_frame; @@ -523,11 +561,17 @@ Session::check_declick_out () } void -Session::set_play_loop (bool yn) +Session::set_play_loop (bool yn, bool leave_rolling) { /* Called from event-handling context */ - if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) { + Location *loc; + + if (yn == play_loop) { + return; + } + + if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) { return; } @@ -543,10 +587,9 @@ Session::set_play_loop (bool yn) if ((play_loop = yn)) { - Location *loc; - + if (loc) { - if ((loc = _locations.auto_loop_location()) != 0) { + set_play_range (false, true); if (Config->get_seamless_loop()) { // set all diskstreams to use internal looping @@ -572,20 +615,13 @@ 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 if current pos is outside of the loop range */ - if (_transport_frame < loc->start() || _transport_frame > loc->end()) { - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack()); - merge_event (event); - } - else { - // locate to current position (+ 1 to force reload) - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack()); - 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); } - } else { clear_events (Event::AutoLoop); @@ -598,6 +634,7 @@ Session::set_play_loop (bool yn) } } + TransportStateChange (); /* EMIT SIGNAL */ } void @@ -755,7 +792,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { // cancel looping directly, this is called from event handling context - set_play_loop (false); + set_play_loop (false, false); } else if (al && _transport_frame == al->start()) { if (with_loop) { @@ -1157,27 +1194,32 @@ Session::set_audio_range (list<AudioRange>& range) } void -Session::request_play_range (bool yn) +Session::request_play_range (bool yn, bool leave_rolling) { - Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn); + Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0f : 0.0f), yn); queue_event (ev); } void -Session::set_play_range (bool yn) +Session::set_play_range (bool yn, bool leave_rolling) { /* Called from event-processing context */ - if (_play_range != yn) { - _play_range = yn; - setup_auto_play (); + if (yn) { + /* cancel loop play */ + set_play_range (false, true); + } - if (!_play_range) { - /* stop transport */ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); - merge_event (ev); - } + _play_range = yn; + setup_auto_play (); + + + if (!_play_range && !leave_rolling) { + /* stop transport */ + Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); + merge_event (ev); } + TransportStateChange (); /* EMIT SIGNAL */ } void @@ -1252,7 +1294,6 @@ Session::request_roll_at_and_return (nframes_t start, nframes_t return_to) void Session::request_bounded_roll (nframes_t start, nframes_t end) { - request_stop (); Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0); queue_event (ev); request_locate (start, true); @@ -1375,3 +1416,17 @@ Session::reset_jack_connection (jack_client_t* jack) js->reset_client (jack); } } + +bool +Session::maybe_stop (nframes_t limit) +{ + if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) { + if (synced_to_jack () && Config->get_jack_time_master ()) { + _engine.transport_stop (); + } else if (!synced_to_jack ()) { + stop_transport (); + } + return true; + } + return false; +} |