diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 2 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 100 |
4 files changed, 85 insertions, 20 deletions
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 6b14680b42..d290d8ebc8 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -133,6 +133,7 @@ CONFIG_VARIABLE (bool, stop_recording_on_xrun, "stop-recording-on-xrun", false) CONFIG_VARIABLE (bool, create_xrun_marker, "create-xrun-marker", true) CONFIG_VARIABLE (bool, stop_at_session_end, "stop-at-session-end", false) CONFIG_VARIABLE (bool, seamless_loop, "seamless-loop", false) +CONFIG_VARIABLE (bool, loop_is_mode, "loop-is-mode", false) CONFIG_VARIABLE (framecnt_t, preroll, "preroll", 0) CONFIG_VARIABLE (framecnt_t, postroll, "postroll", 0) CONFIG_VARIABLE (float, rf_speed, "rf-speed", 2.0f) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 20feb27001..15af67ada7 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1262,7 +1262,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop int start_midi_thread (); - void set_play_loop (bool yn); + void set_play_loop (bool yn, double speed); void unset_play_loop (); void overwrite_some_buffers (Track *); void flush_all_inserts (); diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 6bfb250aec..eb5c0de294 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -1010,7 +1010,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, ev->speed); break; case SessionEvent::AutoLoop: diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 38ad521235..ea9f5d28dd 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -30,6 +30,7 @@ #include "pbd/enumwriter.h" #include "pbd/pthread_utils.h" #include "pbd/memento_command.h" +#include "pbd/stacktrace.h" #include "midi++/mmc.h" #include "midi++/port.h" @@ -40,6 +41,7 @@ #include "ardour/click.h" #include "ardour/debug.h" #include "ardour/location.h" +#include "ardour/profile.h" #include "ardour/session.h" #include "ardour/slave.h" #include "ardour/operations.h" @@ -158,10 +160,11 @@ Session::force_locate (framepos_t target_frame, bool with_roll) } void -Session::request_play_loop (bool yn, bool leave_rolling) +Session::request_play_loop (bool yn, bool change_transport_roll) { SessionEvent* ev; Location *location = _locations->auto_loop_location(); + double target_speed; if (location == 0 && yn) { error << _("Cannot loop - no loop range defined") @@ -169,14 +172,44 @@ Session::request_play_loop (bool yn, bool leave_rolling) return; } - ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); - DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling)); + if (change_transport_roll) { + if (transport_rolling()) { + /* start looping at current speed */ + target_speed = transport_speed (); + } else { + /* currently stopped */ + if (yn) { + /* start looping at normal speed */ + target_speed = 1.0; + } else { + target_speed = 0.0; + } + } + } else { + /* leave the speed alone */ + target_speed = transport_speed (); + } + + ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn); + DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll)); queue_event (ev); - if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) { - // request an immediate locate to refresh the tracks - // after disabling looping - request_locate (_transport_frame-1, false); + if (yn) { + if (!change_transport_roll) { + if (!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 && Config->get_seamless_loop() && transport_rolling()) { + // request an immediate locate to refresh the tracks + // after disabling looping + request_locate (_transport_frame-1, false); + } } } @@ -531,8 +564,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; @@ -589,8 +620,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) */ if (ptw & PostTransportClearSubstate) { - _play_range = false; - unset_play_loop (); + unset_play_range (); + if (!Config->get_loop_is_mode()) { + unset_play_loop (); + } } /* this for() block can be put inside the previous if() and has the effect of ... ??? what */ @@ -657,8 +690,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } if (ptw & PostTransportStop) { - _play_range = false; - play_loop = false; + unset_play_range (); + if (!Config->get_loop_is_mode()) { + unset_play_loop (); + } } PositionChanged (_transport_frame); /* EMIT SIGNAL */ @@ -723,7 +758,7 @@ Session::unset_play_loop () } void -Session::set_play_loop (bool yn) +Session::set_play_loop (bool yn, double speed) { /* Called from event-handling context */ @@ -782,12 +817,24 @@ Session::set_play_loop (bool yn) merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f)); merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f)); - /* locate to start of loop and roll. + /* if requested to roll, locate to start of loop and + * roll but ONLY if we're not already rolling. args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping */ - start_locate (loc->start(), true, true, false, Config->get_seamless_loop()); + if (Config->get_loop_is_mode()) { + /* loop IS a transport mode: if already + rolling, do not locate to loop start. + */ + if (!transport_rolling() && (speed != 0.0)) { + start_locate (loc->start(), true, true, false, Config->get_seamless_loop()); + } + } else { + if (speed != 0.0) { + start_locate (loc->start(), true, true, false, Config->get_seamless_loop()); + } + } } } else { @@ -983,7 +1030,9 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool // located outside the loop: cancel looping directly, this is called from event handling context - set_play_loop (false); + if (!Config->get_loop_is_mode()) { + set_play_loop (false, _transport_speed); + } } else if (_transport_frame == al->start()) { @@ -1080,12 +1129,27 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a stop_transport (abort); } - unset_play_loop (); + if (!Config->get_loop_is_mode()) { + unset_play_loop (); + } } else if (transport_stopped() && speed == 1.0) { /* we are stopped and we want to start rolling at speed 1 */ + if (Config->get_loop_is_mode() && play_loop) { + + Location *location = _locations->auto_loop_location(); + + if (location != 0) { + if (_transport_frame != location->start()) { + /* jump to start and then roll from there */ + request_locate (location->start(), true); + return; + } + } + } + if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) { set_track_monitor_input_status (false); } |