Session::request_locate() takes a tri-valued second argument for "roll-after-locate"
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 17 Jan 2020 22:26:01 +0000 (15:26 -0700)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 18 Jan 2020 15:49:18 +0000 (08:49 -0700)
This allows callers to defer logic about auto-play/current rolling state and more to TransportFSM where it
can be cnentralized and is less ambiguous

27 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_summary.cc
gtk2_ardour/mini_timeline.cc
libs/ardour/ardour/session.h
libs/ardour/ardour/session_event.h
libs/ardour/ardour/transport_fsm.h
libs/ardour/ardour/types.h
libs/ardour/disk_reader.cc
libs/ardour/enums.cc
libs/ardour/mtc_slave.cc
libs/ardour/session.cc
libs/ardour/session_export.cc
libs/ardour/session_midi.cc
libs/ardour/session_process.cc
libs/ardour/session_transport.cc
libs/ardour/transport_fsm.cc
libs/surfaces/contourdesign/contourdesign.cc
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/control_protocol/control_protocol/basic_ui.h
libs/surfaces/faderport8/actions.cc
libs/surfaces/osc/osc.cc

index 83609a6d70ff8695cb8c75a19fa270ff55c4fc66..c604d0c508eebf52103b9f3845853c5d66974db0 100644 (file)
@@ -1611,7 +1611,7 @@ ARDOUR_UI::transport_goto_wallclock ()
                samples += tmnow.tm_min * (60 * sample_rate);
                samples += tmnow.tm_sec * sample_rate;
 
-               _session->request_locate (samples, _session->transport_rolling ());
+               _session->request_locate (samples, DoTheRightThing);
 
                /* force displayed area in editor to start no matter
                   what "follow playhead" setting is.
@@ -1829,7 +1829,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
                }
 
                if (_session->get_play_loop() && Config->get_loop_is_mode()) {
-                       _session->request_locate (_session->locations()->auto_loop_location()->start(), true);
+                       _session->request_locate (_session->locations()->auto_loop_location()->start(), MustRoll);
                } else {
                        if (UIConfiguration::instance().get_follow_edits()) {
                                list<AudioRange>& range = editor->get_selection().time;
index 8556405a51b3c84c1e3e37bc60ad60bb6b829c43..690b2ffd56796e5c69d3eec890fc8a216ff12ccd 100644 (file)
@@ -2184,7 +2184,7 @@ AudioClock::locate ()
                return;
        }
 
-       _session->request_locate (current_time(), _session->transport_rolling ());
+       _session->request_locate (current_time(), DoTheRightThing);
 }
 
 void
index 6e806b9c94706f8c5a4bc1983df975a6fca864d8..ca2b73d0a8591891e95c6c4e25047efe52848b1b 100644 (file)
@@ -1131,7 +1131,7 @@ Editor::control_scroll (float fraction)
 bool
 Editor::deferred_control_scroll (samplepos_t /*target*/)
 {
-       _session->request_locate (*_control_scroll_target, _session->transport_rolling());
+       _session->request_locate (*_control_scroll_target, DoTheRightThing);
        /* reset for next stream */
        _control_scroll_target = boost::none;
        _dragging_playhead = false;
index 57d8b08ceaae9225aa376680b593462fb09fc442..a2c43abedadd48aabb5f591a1f4b416980a81867 100644 (file)
@@ -4104,7 +4104,7 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred)
 
        Session* s = _editor->session ();
        if (s) {
-               s->request_locate (_editor->playhead_cursor->current_sample (), _was_rolling);
+               s->request_locate (_editor->playhead_cursor->current_sample (), _was_rolling ? MustRoll : MustStop);
                _editor->_pending_locate_request = true;
                s->request_resume_timecode_transmission ();
        }
@@ -6002,7 +6002,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
 
                        /* didn't drag, so just locate */
 
-                       _editor->session()->request_locate (grab_sample(), _editor->session()->transport_rolling());
+                       _editor->session()->request_locate (grab_sample(), DoTheRightThing);
 
                } else if (_operation == CreateCDMarker) {
 
index 99a538e60b56932a7fc6350afdd20395e9afd4fa..d125536ac182d2ff9510247908a02346405ebe98 100644 (file)
@@ -1179,15 +1179,15 @@ Editor::marker_menu_play_from ()
        if ((l = find_location_from_marker (marker, is_start)) != 0) {
 
                if (l->is_mark()) {
-                       _session->request_locate (l->start(), true);
+                       _session->request_locate (l->start(), MustRoll);
                }
                else {
                        //_session->request_bounded_roll (l->start(), l->end());
 
                        if (is_start) {
-                               _session->request_locate (l->start(), true);
+                               _session->request_locate (l->start(), MustRoll);
                        } else {
-                               _session->request_locate (l->end(), true);
+                               _session->request_locate (l->end(), MustRoll);
                        }
                }
        }
@@ -1209,13 +1209,13 @@ Editor::marker_menu_set_playhead ()
        if ((l = find_location_from_marker (marker, is_start)) != 0) {
 
                if (l->is_mark()) {
-                       _session->request_locate (l->start(), false);
+                       _session->request_locate (l->start(), MustStop);
                }
                else {
                        if (is_start) {
-                               _session->request_locate (l->start(), false);
+                               _session->request_locate (l->start(), MustStop);
                        } else {
-                               _session->request_locate (l->end(), false);
+                               _session->request_locate (l->end(), MustStop);
                        }
                }
        }
@@ -1330,7 +1330,7 @@ Editor::marker_menu_play_range ()
        if ((l = find_location_from_marker (marker, is_start)) != 0) {
 
                if (l->is_mark()) {
-                       _session->request_locate (l->start(), true);
+                       _session->request_locate (l->start(), MustRoll);
                }
                else {
                        _session->request_bounded_roll (l->start(), l->end());
@@ -1356,7 +1356,7 @@ Editor::marker_menu_loop_range ()
                if (l != transport_loop_location()) {
                        set_loop_range (l->start(), l->end(), _("loop range from marker"));
                }
-               _session->request_locate (l->start(), true);
+               _session->request_locate (l->start(), MustRoll);
                _session->request_play_loop (true);
        }
 }
@@ -1768,7 +1768,7 @@ Editor::goto_nth_marker (int n)
        for (Locations::LocationList::iterator i = ordered.begin(); n >= 0 && i != ordered.end(); ++i) {
                if ((*i)->is_mark() && !(*i)->is_hidden() && !(*i)->is_session_range()) {
                        if (n == 0) {
-                               _session->request_locate ((*i)->start(), _session->transport_rolling());
+                               _session->request_locate ((*i)->start(), DoTheRightThing);
                                break;
                        }
                        --n;
index 22476d5d62d4d4a155b282d730b15afd47b5be75..7c1722831313b65a3dcb2946ba3251074d6a3dc6 100644 (file)
@@ -1376,7 +1376,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
 
                MusicSample where (canvas_event_sample (event), 0);
                snap_to (where);
-               _session->request_locate (where.sample, false);
+               _session->request_locate (where.sample, MustStop);
        }
 
        switch (event->button.button) {
@@ -2062,7 +2062,7 @@ Editor::scrub (samplepos_t sample, double current_x)
 
        if (scrubbing_direction == 0) {
                /* first move */
-               _session->request_locate (sample, false);
+               _session->request_locate (sample, MustStop);
                _session->request_transport_speed (0.1);
                scrubbing_direction = 1;
 
index 195d4d16436b6bbb41aa9e926eafbe0dcbd9abfc..050809dfe3d7bd5651a3b535a85384cfc4d04fec 100644 (file)
@@ -1351,7 +1351,7 @@ Editor::cursor_align (bool playhead_to_edit)
                        return;
                }
 
-               _session->request_locate (selection->markers.front()->position(), _session->transport_rolling());
+               _session->request_locate (selection->markers.front()->position(), DoTheRightThing);
 
        } else {
                const int32_t divisions = get_grid_music_divisions (0);
@@ -2445,7 +2445,7 @@ Editor::jump_forward_to_mark ()
                return;
        }
 
-       _session->request_locate (pos, _session->transport_rolling());
+       _session->request_locate (pos, DoTheRightThing);
 }
 
 void
@@ -2469,7 +2469,7 @@ Editor::jump_backward_to_mark ()
                return;
        }
 
-       _session->request_locate (pos, _session->transport_rolling());
+       _session->request_locate (pos, DoTheRightThing);
 }
 
 void
@@ -2640,13 +2640,13 @@ Editor::transition_to_rolling (bool fwd)
 void
 Editor::play_from_start ()
 {
-       _session->request_locate (_session->current_start_sample(), true);
+       _session->request_locate (_session->current_start_sample(), MustRoll);
 }
 
 void
 Editor::play_from_edit_point ()
 {
-       _session->request_locate (get_preferred_edit_position(), true);
+       _session->request_locate (get_preferred_edit_position(), MustRoll);
 }
 
 void
@@ -2658,7 +2658,7 @@ Editor::play_from_edit_point_and_return ()
        start_sample = get_preferred_edit_position (EDIT_IGNORE_PHEAD);
 
        if (_session->transport_rolling()) {
-               _session->request_locate (start_sample, false);
+               _session->request_locate (start_sample, MustStop);
                return;
        }
 
@@ -2739,7 +2739,7 @@ Editor::play_with_preroll ()
                } else {
                        start = 0;
                }
-               _session->request_locate (start, true);
+               _session->request_locate (start, MustRoll);
                _session->set_requested_return_sample (ph);  //force auto-return to return to playhead location, without the preroll
        }
 }
@@ -2781,7 +2781,7 @@ Editor::loop_location (Location& location)
                tll->set (location.start(), location.end());
 
                // enable looping, reposition and start rolling
-               _session->request_locate (tll->start(), true);
+               _session->request_locate (tll->start(), MustRoll);
                _session->request_play_loop (true);
        }
 }
@@ -6520,7 +6520,7 @@ void
 Editor::set_playhead_cursor ()
 {
        if (entered_marker) {
-               _session->request_locate (entered_marker->position(), _session->transport_rolling());
+               _session->request_locate (entered_marker->position(), DoTheRightThing);
        } else {
                MusicSample where (0, 0);
                bool ignored;
@@ -6532,7 +6532,7 @@ Editor::set_playhead_cursor ()
                snap_to (where);
 
                if (_session) {
-                       _session->request_locate (where.sample, _session->transport_rolling());
+                       _session->request_locate (where.sample, DoTheRightThing);
                }
        }
 
@@ -6639,7 +6639,7 @@ Editor::set_loop_from_region (bool play)
        set_loop_range (start, end, _("set loop range from region"));
 
        if (play) {
-               _session->request_locate (start, true);
+               _session->request_locate (start, MustRoll);
                _session->request_play_loop (true);
        }
 }
@@ -7525,7 +7525,7 @@ Editor::playhead_backward_to_grid ()
                        }
                }
 
-               _session->request_locate (pos.sample, _session->transport_rolling());
+               _session->request_locate (pos.sample, DoTheRightThing);
        }
 
        /* keep PH visible in window */
index 4bb53fb88bb8fd9223babc92e3bcdb9d729f78a6..4a8598d59c11d86bb169defc58c200b5f0360de9 100644 (file)
@@ -437,7 +437,7 @@ EditorSummary::on_key_press_event (GdkEventKey* key)
                if (key->keyval == set_playhead_accel.accel_key && (int) key->state == set_playhead_accel.accel_mods) {
                        if (_session) {
                                get_pointer (x, y);
-                               _session->request_locate (_start + (samplepos_t) x / _x_scale, _session->transport_rolling());
+                               _session->request_locate (_start + (samplepos_t) x / _x_scale, DoTheRightThing);
                                return true;
                        }
                }
index cbda9d052d44d253f6978fe7d008c24597e26bb7..bd8274affd76d07810f325825e8e27998bdd96d8 100644 (file)
@@ -728,7 +728,7 @@ MiniTimeline::on_button_release_event (GdkEventButton *ev)
        if (ev->y <= PADDING + _marker_height) {
                for (JumpList::const_iterator i = _jumplist.begin (); i != _jumplist.end(); ++i) {
                        if (i->left <= ev->x && ev->x <= i->right) {
-                               _session->request_locate (i->to, _session->transport_rolling ());
+                               _session->request_locate (i->to, DoTheRightThing);
                                return true;
                        }
                }
@@ -736,7 +736,7 @@ MiniTimeline::on_button_release_event (GdkEventButton *ev)
 
        if (ev->button == 1) {
                samplepos_t when = _last_update_sample + (ev->x - get_width() * .5) / _px_per_sample;
-               _session->request_locate (std::max ((samplepos_t)0, when), _session->transport_rolling ());
+               _session->request_locate (std::max ((samplepos_t)0, when), DoTheRightThing);
        }
 
        return true;
@@ -818,6 +818,6 @@ MiniTimeline::on_scroll_event (GdkEventScroll *ev)
                        return true;
                        break;
        }
-       _session->request_locate (std::max ((samplepos_t)0, when), _session->transport_rolling ());
+       _session->request_locate (std::max ((samplepos_t)0, when), DoTheRightThing);
        return true;
 }
index 2b42c59973ad8465b765f97b403cda97daaa796c..402c55bf5905f18c074ac749ce2e85d0df86fa13 100644 (file)
@@ -444,7 +444,7 @@ public:
        void request_roll_at_and_return (samplepos_t start, samplepos_t return_to);
        void request_bounded_roll (samplepos_t start, samplepos_t end);
        void request_stop (bool abort = false, bool clear_state = false, TransportRequestSource origin = TRS_UI);
-       void request_locate (samplepos_t sample, bool with_roll = false, TransportRequestSource origin = TRS_UI);
+       void request_locate (samplepos_t sample, LocateTransportDisposition ltd = DoTheRightThing, TransportRequestSource origin = TRS_UI);
 
        void request_play_loop (bool yn, bool leave_rolling = false);
        bool get_play_loop () const { return play_loop; }
index ddf7210617c2267d1ba59615463743e377439590..b0af5596f6c2f437edc2c074a28623d0eb7722ac 100644 (file)
@@ -91,6 +91,7 @@ public:
        union {
                bool second_yes_or_no;
                double control_value;
+               LocateTransportDisposition locate_transport_disposition;
        };
 
        union {
index 12550d92a7ac81834088091139564924b80868c3..54ceac230446963685aa863a697d95fa501b8ffd 100644 (file)
@@ -46,7 +46,7 @@ struct TransportFSM
                EventType type;
                union {
                        bool abort; /* for stop */
-                       bool with_roll; /* for locate */
+                       LocateTransportDisposition ltd; /* for locate */
                };
                union {
                        bool clear_state; /* for stop */
@@ -59,7 +59,7 @@ struct TransportFSM
 
                Event (EventType t)
                        : type (t)
-                       , with_roll (false)
+                       , ltd (MustStop)
                        , with_flush (false)
                        , target (0)
                        , for_loop_end (false)
@@ -72,9 +72,9 @@ struct TransportFSM
                {
                        assert (t == StopTransport);
                }
-               Event (EventType t, samplepos_t pos, bool r, bool fl, bool lp, bool f4c)
+               Event (EventType t, samplepos_t pos, LocateTransportDisposition l, bool fl, bool lp, bool f4c)
                        : type (t)
-                       , with_roll (r)
+                       , ltd (l)
                        , with_flush (fl)
                        , target (pos)
                        , for_loop_end (lp)
@@ -175,6 +175,7 @@ struct TransportFSM
        void defer (Event& ev);
        void bad_transition (Event const &);
        void set_roll_after (bool) const;
+       bool compute_should_roll (LocateTransportDisposition) const;
 };
 
 } /* end namespace ARDOUR */
index c7453fcf1b5275a850616e4e8624285e9f71e3ae..1504698896c33dcb50d8dbca7297569e94a468b2 100644 (file)
@@ -799,6 +799,12 @@ enum OverwriteReason {
        LoopChanged = 0x8,
 };
 
+enum LocateTransportDisposition {
+       MustRoll,
+       MustStop,
+       DoTheRightThing
+};
+
 typedef std::vector<CaptureInfo*> CaptureInfos;
 
 } // namespace ARDOUR
index 73dede5a9635713738e8714557193781edb78d56..2ba941eab0dcf2f5e40641c77269991e87b8cb1a 100644 (file)
@@ -492,7 +492,9 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
                _need_butler = butler_required;
        }
 
-       DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 reader run, needs butler = %2\n", name(), _need_butler));
+       if (_need_butler) {
+               DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 reader run, needs butler = %2\n", name(), _need_butler));
+       }
 }
 
 bool
@@ -1127,6 +1129,9 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai
 
        samplepos_t file_sample_tmp = ffa;
 
+       // int64_t before = g_get_monotonic_time ();
+       // int64_t elapsed;
+
        for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
 
                ChannelInfo* chan (*i);
index f9eda73b7e414486fd991bd2a13039d6fa55c82b..d8a442150c0137ef2fc7b9bc818d0e79d34dd73e 100644 (file)
@@ -157,7 +157,8 @@ setup_enum_writer ()
        TransportFSM::ButlerState _TransportFSM_ButlerState;
        LoopFadeChoice _LoopFadeChooice;
        TransportState _TransportState;
-
+       LocateTransportDisposition _LocateTransportDisposition;
+       
 #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
 #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
 #define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
@@ -833,6 +834,11 @@ setup_enum_writer ()
        REGISTER_ENUM (TransportLooping);
        REGISTER_ENUM (TransportStarting);
        REGISTER (_TransportState);
+
+       REGISTER_ENUM (MustStop);
+       REGISTER_ENUM (MustRoll);
+       REGISTER_ENUM (DoTheRightThing);
+       REGISTER (_LocateTransportDisposition);
 }
 
 } /* namespace ARDOUR */
index eded0e6dc2ecf16cbbb382fa50a04b1076fb53ce..c4af3f9bc7f05dbc0a70625b9441308ea69fa264 100644 (file)
@@ -431,7 +431,7 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp
                DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC %1 or outside window %2 MTC %3\n", was_full, outside_window (mtc_frame), mtc_frame));
                _session->set_requested_return_sample (-1);
                _session->request_transport_speed (0, TRS_MTC);
-               _session->request_locate (mtc_frame, false, TRS_MTC);
+               _session->request_locate (mtc_frame, MustStop, TRS_MTC);
                update_mtc_status (MIDI::MTC_Stopped);
                reset (false);
                reset_window (mtc_frame);
index 62660c9fa256619ff78706e85c02197a05ef3326..454a9065edc4996e3ba730c0765024b076d5d2e4 100644 (file)
@@ -1443,7 +1443,7 @@ Session::auto_loop_changed (Location* location)
                                 */
 
                                loop_changing = true;
-                               request_locate (location->start(), true);
+                               request_locate (location->start(), MustRoll);
 
                        } else {
 
@@ -6083,9 +6083,9 @@ void
 Session::goto_end ()
 {
        if (_session_range_location) {
-               request_locate (_session_range_location->end(), false);
+               request_locate (_session_range_location->end(), MustStop);
        } else {
-               request_locate (0, false);
+               request_locate (0, MustStop);
        }
 }
 
@@ -6093,9 +6093,9 @@ void
 Session::goto_start (bool and_roll)
 {
        if (_session_range_location) {
-               request_locate (_session_range_location->start(), and_roll);
+               request_locate (_session_range_location->start(), and_roll ? MustRoll : DoTheRightThing);
        } else {
-               request_locate (0, and_roll);
+               request_locate (0, and_roll ? MustRoll : DoTheRightThing);
        }
 }
 
index 3ec32e1d6f77bf347d76a503b53233dbf13805d1..c86d55e248c23c351cfb8dcf51c43a2c352a7acc 100644 (file)
@@ -346,6 +346,6 @@ Session::finalize_audio_export (TransportRequestSource trs)
        if (post_export_sync) {
                config.set_external_sync (true);
        } else {
-               request_locate (post_export_position, false, trs);
+               request_locate (post_export_position, MustStop, trs);
        }
 }
index 3048303c7d26674b3fe9ce62de4b3bbef2b55325..c08abe95f5e7263210f5734c05070d105d68ba18 100644 (file)
@@ -306,7 +306,7 @@ Session::mmc_locate (MIDI::MachineControl &/*mmc*/, const MIDI::byte* mmc_tc)
                mtcs->handle_locate (mmc_tc);
        } else {
                // cerr << "Locate without MTC slave\n";
-               request_locate (target_sample, false);
+               request_locate (target_sample, MustStop);
        }
 }
 
index bd8bd8d08b0e127f75c36ef90b81018594873b75..a4429c36093dd7271ad897b6432b1a67ef650c74 100644 (file)
@@ -61,7 +61,7 @@ using namespace std;
 
 #define TFSM_EVENT(evtype) { _transport_fsm->enqueue (new TransportFSM::Event (evtype)); }
 #define TFSM_STOP(abort,clear) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::StopTransport,abort,clear)); }
-#define TFSM_LOCATE(target,roll,flush,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,roll,flush,loop,force)); }
+#define TFSM_LOCATE(target,ltd,flush,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,ltd,flush,loop,force)); }
 
 
 /** Called by the audio engine when there is work to be done with JACK.
@@ -859,7 +859,7 @@ Session::process_event (SessionEvent* ev)
                if (play_loop) {
                        /* roll after locate, do not flush, set "for loop end" true
                        */
-                       TFSM_LOCATE (ev->target_sample, true, false, true, false);
+                       TFSM_LOCATE (ev->target_sample, MustRoll, false, true, false);
                }
                remove = false;
                del = false;
@@ -867,19 +867,19 @@ Session::process_event (SessionEvent* ev)
 
        case SessionEvent::Locate:
                /* args: do not roll after locate, clear state, not for loop, force */
-               TFSM_LOCATE (ev->target_sample, false, true, false, ev->yes_or_no);
+               TFSM_LOCATE (ev->target_sample, ev->locate_transport_disposition, true, false, ev->yes_or_no);
                _send_timecode_update = true;
                break;
 
        case SessionEvent::LocateRoll:
                /* args: roll after locate, clear state if not looping, not for loop, force */
-               TFSM_LOCATE (ev->target_sample, true, !play_loop, false, ev->yes_or_no);
+               TFSM_LOCATE (ev->target_sample, ev->locate_transport_disposition, !play_loop, false, ev->yes_or_no);
                _send_timecode_update = true;
                break;
 
        case SessionEvent::Skip:
                if (Config->get_skip_playback()) {
-                       TFSM_LOCATE (ev->target_sample, true, true, false, false);
+                       TFSM_LOCATE (ev->target_sample, MustRoll, true, false, false);
                        _send_timecode_update = true;
                }
                remove = false;
@@ -889,7 +889,7 @@ Session::process_event (SessionEvent* ev)
        case SessionEvent::LocateRollLocate:
                // locate is handled by ::request_roll_at_and_return()
                _requested_return_sample = ev->target_sample;
-               TFSM_LOCATE (ev->target2_sample, true, true, false, false);
+               TFSM_LOCATE (ev->target2_sample, MustRoll, true, false, false);
                _send_timecode_update = true;
                break;
 
@@ -928,7 +928,7 @@ Session::process_event (SessionEvent* ev)
 
        case SessionEvent::RangeLocate:
                /* args: roll after locate, do flush, not with loop */
-               TFSM_LOCATE (ev->target_sample, true, true, false, false);
+               TFSM_LOCATE (ev->target_sample, MustRoll, true, false, false);
                remove = false;
                del = false;
                break;
@@ -1126,7 +1126,7 @@ Session::follow_transport_master (pframes_t nframes)
                                                const samplepos_t locate_target = master_transport_sample + wlp;
                                                DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: jump to master position %1 by locating to %2\n", master_transport_sample, locate_target));
                                                /* for JACK transport always stop after the locate (2nd argument == false) */
-                                               TFSM_LOCATE (locate_target, false, true, false, false);
+                                               TFSM_LOCATE (locate_target, MustStop, true, false, false);
 
                                        } else {
                                                DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: locate already in process, sts = %1\n", master_transport_sample));
@@ -1166,7 +1166,7 @@ Session::follow_transport_master (pframes_t nframes)
                                /* note that for non-JACK transport masters, we assume that the transport state (rolling,stopped) after the locate
                                 * remains unchanged (2nd argument, "roll-after-locate")
                                 */
-                               TFSM_LOCATE (master_transport_sample, master_speed != 0, true, false, false);
+                               TFSM_LOCATE (master_transport_sample, (master_speed != 0) ? MustRoll : MustStop, true, false, false);
                        }
 
                        return true;
index c62e42d5d9af4251f2b1d72837aede5e4ac2989d..9e5117f9d184953c61a7b2197e0a3b21a3d66356 100644 (file)
@@ -85,7 +85,7 @@ using namespace PBD;
 
 #define TFSM_EVENT(evtype) { _transport_fsm->enqueue (new TransportFSM::Event (evtype)); }
 #define TFSM_STOP(abort,clear) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::StopTransport,abort,clear)); }
-#define TFSM_LOCATE(target,roll,flush,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,roll,flush,loop,force)); }
+#define TFSM_LOCATE(target,ltd,flush,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,ltd,flush,loop,force)); }
 
 /* *****************************************************************************
  * REALTIME ACTIONS (to be called on state transitions)
@@ -470,7 +470,7 @@ Session::set_transport_speed (double speed, samplepos_t destination_sample, bool
 
                                        /* jump to start and then roll from there */
 
-                                       request_locate (location->start(), true);
+                                       request_locate (location->start(), MustRoll);
                                        return;
                                }
                        }
@@ -910,7 +910,7 @@ Session::request_stop (bool abort, bool clear_state, TransportRequestSource orig
 }
 
 void
-Session::request_locate (samplepos_t target_sample, bool with_roll, TransportRequestSource origin)
+Session::request_locate (samplepos_t target_sample, LocateTransportDisposition ltd, TransportRequestSource origin)
 {
        if (synced_to_engine()) {
                _engine.transport_locate (target_sample);
@@ -921,8 +921,27 @@ Session::request_locate (samplepos_t target_sample, bool with_roll, TransportReq
                return;
        }
 
-       SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
-       DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_sample));
+       SessionEvent::Type type;
+
+       switch (ltd) {
+       case MustRoll:
+               type = SessionEvent::LocateRoll;
+               break;
+       case MustStop:
+               type = SessionEvent::Locate;
+               break;
+       case DoTheRightThing:
+               if (config.get_auto_play()) {
+                       type = SessionEvent::LocateRoll;
+               } else {
+                       type = SessionEvent::Locate;
+               }
+               break;
+       }
+
+       SessionEvent *ev = new SessionEvent (type, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
+       ev->locate_transport_disposition = ltd;
+       DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1 ltd = %2\n", target_sample, enum_2_string (ltd)));
        queue_event (ev);
 }
 
@@ -954,7 +973,7 @@ Session::request_preroll_record_trim (samplepos_t rec_in, samplecnt_t preroll)
        samplepos_t pos = std::max ((samplepos_t)0, rec_in - preroll);
        _preroll_record_trim_len = preroll;
        maybe_enable_record ();
-       request_locate (pos, true);
+       request_locate (pos, MustRoll);
        set_requested_return_sample (rec_in);
 }
 
@@ -1367,7 +1386,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                _have_captured = true;
        }
 
-       DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
+       DEBUG_TRACE (DEBUG::Transport, X_("Butler post-transport-work, non realtime stop\n"));
 
        if (abort && did_record) {
                /* no reason to save the session file when we remove sources
@@ -1612,10 +1631,10 @@ Session::set_play_loop (bool yn, bool change_transport_state)
                                   crude mechanism. Got a better idea?
                                */
                                loop_changing = true;
-                               TFSM_LOCATE (loc->start(), true, true, false, true);
+                               TFSM_LOCATE (loc->start(), MustRoll, true, false, true);
                        } else if (!transport_rolling()) {
                                /* loop-is-mode: not rolling, just locate to loop start */
-                               TFSM_LOCATE (loc->start(), false, true, false, true);
+                               TFSM_LOCATE (loc->start(), MustStop, true, false, true);
                        }
                }
 
index bd3ac986b2c313aa9d646dcaa00b4a79b0125397..a06e2159c9c8e6585fb53391ff85acee539af90b 100644 (file)
@@ -253,8 +253,8 @@ TransportFSM::process_event (Event& ev, bool already_deferred, bool& deferred)
                break;
 
        case Locate:
-               DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("locate, with roll = %1 flush = %2 target = %3 loop %4 force %5\n",
-                                                               ev.with_roll,
+               DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("locate, ltd = %1 flush = %2 target = %3 loop %4 force %5\n",
+                                                               enum_2_string (ev.ltd),
                                                                ev.with_flush,
                                                                ev.target,
                                                                ev.for_loop_end,
@@ -277,7 +277,7 @@ TransportFSM::process_event (Event& ev, bool already_deferred, bool& deferred)
                                 * disk I/O is required - the loop is
                                 * automically present in buffers already.
                                 *
-                                * Note that ev.with_roll is ignored and
+                                * Note that ev.ltd is ignored and
                                 * assumed to be true because we're looping.
                                 */
                                transition (WaitingForLocate);
@@ -389,11 +389,12 @@ void
 TransportFSM::start_declick_for_locate (Event const & l)
 {
        assert (l.type == Locate);
-       DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("start_declick_for_locate, crals %1 with_roll %2 speed %3 sral %4\n", (bool) current_roll_after_locate_status, l.with_roll, api->speed(), api->should_roll_after_locate()));
+       DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("start_declick_for_locate, crals %1 ltd %2 speed %3 sral %4\n", (bool) current_roll_after_locate_status,
+                                                       enum_2_string (l.ltd), api->speed(), api->should_roll_after_locate()));
        _last_locate = l;
 
        if (!current_roll_after_locate_status) {
-               set_roll_after (l.with_roll);
+               set_roll_after (compute_should_roll (l.ltd));
        }
        api->stop_transport (false, false);
 }
@@ -404,28 +405,50 @@ TransportFSM::start_locate_while_stopped (Event const & l) const
        assert (l.type == Locate);
        DEBUG_TRACE (DEBUG::TFSMEvents, "start_locate_while_stopped\n");
 
-       set_roll_after (l.with_roll || api->should_roll_after_locate());
+       set_roll_after (compute_should_roll (l.ltd));
 
        api->locate (l.target, current_roll_after_locate_status.get(), l.with_flush, l.for_loop_end, l.force);
 }
 
+bool
+TransportFSM::compute_should_roll (LocateTransportDisposition ltd) const
+{
+       switch (ltd) {
+       case MustRoll:
+               return true;
+       case MustStop:
+               return false;
+       case DoTheRightThing:
+               if (rolling()) {
+                       return true;
+               } else {
+                       return api->should_roll_after_locate ();
+               }
+               break;
+       }
+       /*NOTREACHED*/
+       return true;
+}
+
 void
 TransportFSM::locate_for_loop (Event const & l)
 {
        assert (l.type == Locate);
        DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("locate_for_loop, wl = %1\n", l.for_loop_end));
-       set_roll_after (l.with_roll);
+
+       const bool should_roll = compute_should_roll (l.ltd);
+
        _last_locate = l;
-       api->locate (l.target, l.with_roll, l.with_flush, l.for_loop_end, l.force);
+       api->locate (l.target, should_roll, l.with_flush, l.for_loop_end, l.force);
 }
 
 void
 TransportFSM::start_locate_after_declick () const
 {
        DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("start_locate_after_declick, have crals ? %1 roll will be %2\n", (bool) current_roll_after_locate_status,
-                                                       current_roll_after_locate_status ? current_roll_after_locate_status.get() : _last_locate.with_roll));
+                                                       current_roll_after_locate_status ? current_roll_after_locate_status.get() : compute_should_roll (_last_locate.ltd)));
 
-       const bool roll = current_roll_after_locate_status ? current_roll_after_locate_status.get() : _last_locate.with_roll;
+       const bool roll = current_roll_after_locate_status ? current_roll_after_locate_status.get() : compute_should_roll (_last_locate.ltd);
        api->locate (_last_locate.target, roll, _last_locate.with_flush, _last_locate.for_loop_end, _last_locate.force);
 }
 
index 1e4471b56b87430baea070b35985817d4ef80fda..0ddf9c5945f2d7faf100fcbff72bf2520398dc39 100644 (file)
@@ -557,7 +557,7 @@ ContourDesignControlProtocol::prev_marker_keep_rolling ()
        samplepos_t pos = session->locations()->first_mark_before (session->transport_sample());
 
        if (pos >= 0) {
-               session->request_locate (pos, _keep_rolling && session->transport_rolling());
+               session->request_locate (pos, DoTheRightThing);
        } else {
                session->goto_start ();
        }
@@ -569,7 +569,7 @@ ContourDesignControlProtocol::next_marker_keep_rolling ()
        samplepos_t pos = session->locations()->first_mark_after (session->transport_sample());
 
        if (pos >= 0) {
-               session->request_locate (pos, _keep_rolling && session->transport_rolling());
+               session->request_locate (pos, DoTheRightThing);
        } else {
                session->goto_end();
        }
@@ -592,7 +592,7 @@ ContourDesignControlProtocol::jog_event_forward ()
 void
 ContourDesignControlProtocol::jump_forward (JumpDistance dist)
 {
-       bool kr = _keep_rolling && session->transport_rolling ();
+       LocateTransportDisposition kr = _keep_rolling ? DoTheRightThing : MustStop;
        switch (dist.unit) {
        case SECONDS: jump_by_seconds (dist.value, kr); break;
        case BEATS: jump_by_beats (dist.value, kr); break;
index 65ea59197adb4bd2c40195f0dcb66ed7ea86b483..5c2879cdf0b15621b78f949298858377634c9b62 100644 (file)
@@ -330,7 +330,7 @@ BasicUI::prev_marker ()
        samplepos_t pos = session->locations()->first_mark_before (session->transport_sample());
 
        if (pos >= 0) {
-               session->request_locate (pos, session->transport_rolling());
+               session->request_locate (pos, DoTheRightThing);
        } else {
                session->goto_start ();
        }
@@ -342,7 +342,7 @@ BasicUI::next_marker ()
        samplepos_t pos = session->locations()->first_mark_after (session->transport_sample());
 
        if (pos >= 0) {
-               session->request_locate (pos, session->transport_rolling());
+               session->request_locate (pos, DoTheRightThing);
        } else {
                session->goto_end();
        }
@@ -417,13 +417,19 @@ BasicUI::transport_sample ()
 }
 
 void
-BasicUI::locate (samplepos_t where, bool roll_after_locate)
+BasicUI::locate (samplepos_t where, LocateTransportDisposition ltd)
 {
-       session->request_locate (where, roll_after_locate);
+       session->request_locate (where, ltd);
 }
 
 void
-BasicUI::jump_by_seconds (double secs, bool with_roll)
+BasicUI::locate (samplepos_t where, bool roll)
+{
+       session->request_locate (where, roll ? MustRoll : DoTheRightThing);
+}
+
+void
+BasicUI::jump_by_seconds (double secs, LocateTransportDisposition ltd)
 {
        samplepos_t current = session->transport_sample();
        double s = (double) current / (double) session->nominal_sample_rate();
@@ -434,11 +440,11 @@ BasicUI::jump_by_seconds (double secs, bool with_roll)
        }
        s = s * session->nominal_sample_rate();
 
-       session->request_locate (floor(s), with_roll);
+       session->request_locate (floor(s), ltd);
 }
 
 void
-BasicUI::jump_by_bars (double bars, bool with_roll)
+BasicUI::jump_by_bars (double bars, LocateTransportDisposition ltd)
 {
        TempoMap& tmap (session->tempo_map());
        Timecode::BBT_Time bbt (tmap.bbt_at_sample (session->transport_sample()));
@@ -452,18 +458,18 @@ BasicUI::jump_by_bars (double bars, bool with_roll)
        any.type = AnyTime::BBT;
        any.bbt.bars = bars;
 
-       session->request_locate (session->convert_to_samples (any), with_roll);
+       session->request_locate (session->convert_to_samples (any), ltd);
 }
 
 void
-BasicUI::jump_by_beats (double beats, bool with_roll)
+BasicUI::jump_by_beats (double beats, LocateTransportDisposition ltd)
 {
        TempoMap& tmap (session->tempo_map ());
        double qn_goal = tmap.quarter_note_at_sample (session->transport_sample ()) + beats;
        if (qn_goal < 0.0) {
                qn_goal = 0.0;
        }
-       session->request_locate (tmap.sample_at_quarter_note (qn_goal), with_roll);
+       session->request_locate (tmap.sample_at_quarter_note (qn_goal), ltd);
 }
 
 void
@@ -574,7 +580,7 @@ BasicUI::toggle_roll (bool roll_out_of_bounded_mode)
        } else { /* not rolling */
 
                if (session->get_play_loop() && Config->get_loop_is_mode()) {
-                       session->request_locate (session->locations()->auto_loop_location()->start(), true);
+                       session->request_locate (session->locations()->auto_loop_location()->start(), MustRoll);
                } else {
                        session->request_transport_speed (1.0f);
                }
@@ -689,7 +695,7 @@ BasicUI::goto_nth_marker (int n)
        for (Locations::LocationList::iterator i = ordered.begin(); n >= 0 && i != ordered.end(); ++i) {
                if ((*i)->is_mark() && !(*i)->is_hidden() && !(*i)->is_session_range()) {
                        if (n == 0) {
-                               session->request_locate ((*i)->start(), session->transport_rolling());
+                               session->request_locate ((*i)->start(), DoTheRightThing);
                                break;
                        }
                        --n;
index af1e127b031a7d86080a972c769126ea054c5eae..70f40f97b8308818b04eca3495cc0350dfddafbc 100644 (file)
@@ -70,12 +70,13 @@ class LIBCONTROLCP_API BasicUI {
        void set_transport_speed (double speed);
        double get_transport_speed ();
 
-       void jump_by_seconds (double sec, bool with_roll = false);
-       void jump_by_bars (double bars, bool with_roll = false);
-       void jump_by_beats (double beats, bool with_roll = false);
+       void jump_by_seconds (double sec, ARDOUR::LocateTransportDisposition ltd = ARDOUR::DoTheRightThing);
+       void jump_by_bars (double bars, ARDOUR::LocateTransportDisposition ltd = ARDOUR::DoTheRightThing);
+       void jump_by_beats (double beats, ARDOUR::LocateTransportDisposition ltd = ARDOUR::DoTheRightThing);
 
        ARDOUR::samplepos_t transport_sample ();
-       void locate (ARDOUR::samplepos_t sample, bool play = false);
+       void locate (ARDOUR::samplepos_t sample, ARDOUR::LocateTransportDisposition ltd);
+       void locate (ARDOUR::samplepos_t sample, bool);
        bool locating ();
        bool locked ();
 
index 27fdce1a667708ac5f67fc13a2b4a9550dc65282..29beadd5fc3bd839a0637b0dcfb0b260612d8f88 100644 (file)
@@ -309,7 +309,7 @@ FaderPort8::button_varispeed (bool ffw)
                // stop key-repeat
                dynamic_cast<FP8RepeatButton*>(&b_ffw)->stop_repeat();
                dynamic_cast<FP8RepeatButton*>(&b_rew)->stop_repeat();
-               session->request_locate (0, false);
+               session->request_locate (0, MustStop);
                return;
        }
 
index 666c1023c316cc6884de15f7b081b8dc35050d92..5e336e653d08747359415597c58c697fb9c8c001 100644 (file)
@@ -3369,7 +3369,7 @@ OSC::set_marker (const char* types, lo_arg **argv, int argc, lo_message msg)
                                for (Locations::LocationList::const_iterator l = ll.begin(); l != ll.end(); ++l) {
                                        if ((*l)->is_mark ()) {
                                                if (strcmp (&argv[0]->s, (*l)->name().c_str()) == 0) {
-                                                       session->request_locate ((*l)->start (), false);
+                                                       session->request_locate ((*l)->start (), MustStop);
                                                        return 0;
                                                } else if ((*l)->start () == session->transport_sample()) {
                                                        cur_mark = (*l);
@@ -3406,7 +3406,7 @@ OSC::set_marker (const char* types, lo_arg **argv, int argc, lo_message msg)
        std::sort (lm.begin(), lm.end(), location_marker_sort);
        // go there
        if (marker < lm.size()) {
-               session->request_locate (lm[marker].when, false);
+               session->request_locate (lm[marker].when, MustStop);
                return 0;
        }
        // we were unable to deal with things
@@ -6202,7 +6202,7 @@ OSC::periodic (void)
                        scrub_speed = 0;
                        session->request_transport_speed (0);
                        // locate to the place PH was at last tick
-                       session->request_locate (scrub_place, false);
+                       session->request_locate (scrub_place, MustStop);
                }
        }
        for (uint32_t it = 0; it < _surface.size(); it++) {