Tempo marker movement snaps to the future grid, rather than the current one.
authornick_m <mainsbridge@gmail.com>
Tue, 23 Aug 2016 17:38:46 +0000 (03:38 +1000)
committernick_m <mainsbridge@gmail.com>
Tue, 23 Aug 2016 17:38:46 +0000 (03:38 +1000)
- fixes jittery tempo movement when snapping within large gradients.

libs/ardour/tempo.cc

index 35a19b13db1119fa1dc0fe1909e13800a8739333..65c4765dd4fa2c7dd59c76d438d617f249902c99 100644 (file)
@@ -2774,26 +2774,23 @@ void
 TempoMap::gui_move_tempo (TempoSection* ts, const framepos_t& frame, const int& sub_num)
 {
        Metrics future_map;
-       bool was_musical = ts->position_lock_style() == MusicTime;
-
-       if (sub_num == 0 && was_musical) {
-               /* if we're not snapping to music,
-                  AudioTime and MusicTime may be treated identically.
-               */
-               ts->set_position_lock_style (AudioTime);
-       }
 
        if (ts->position_lock_style() == MusicTime) {
                {
                        /* if we're snapping to a musical grid, set the pulse exactly instead of via the supplied frame. */
                        Glib::Threads::RWLock::WriterLock lm (lock);
                        TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
-                       const double beat = exact_beat_at_frame_locked (future_map, frame, sub_num);
-                       double pulse = pulse_at_beat_locked (future_map, beat);
 
-                       if (solve_map_pulse (future_map, tempo_copy, pulse)) {
-                               solve_map_pulse (_metrics, ts, pulse);
-                               recompute_meters (_metrics);
+                       tempo_copy->set_position_lock_style (AudioTime);
+
+                       if (solve_map_frame (future_map, tempo_copy, frame)) {
+                               const double beat = exact_beat_at_frame_locked (future_map, frame, sub_num);
+                               const double pulse = pulse_at_beat_locked (future_map, beat);
+
+                               if (solve_map_pulse (future_map, tempo_copy, pulse)) {
+                                       solve_map_pulse (_metrics, ts, pulse);
+                                       recompute_meters (_metrics);
+                               }
                        }
                }
 
@@ -2802,17 +2799,37 @@ TempoMap::gui_move_tempo (TempoSection* ts, const framepos_t& frame, const int&
                {
                        Glib::Threads::RWLock::WriterLock lm (lock);
                        TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
+
                        if (solve_map_frame (future_map, tempo_copy, frame)) {
-                               solve_map_frame (_metrics, ts, frame);
-                               recompute_meters (_metrics);
+                               if (sub_num != 0) {
+                                       /* We're moving the object that defines the grid while snapping to it...
+                                        * Placing the ts at the beat corresponding to the requested frame may shift the
+                                        * grid in such a way that the mouse is left hovering over a completerly different division,
+                                        * causing jittering when the mouse next moves (esp. large tempo deltas).
+                                        * To avoid this, place the ts at the requested frame in a dummy map
+                                        * then find the closest beat subdivision to that frame in the dummy.
+                                        * This alters the snap behaviour slightly in that we snap to beat divisions
+                                        * in the future map rather than the existing one.
+                                        */
+                                       const double beat = exact_beat_at_frame_locked (future_map, frame, sub_num);
+                                       const double pulse = pulse_at_beat_locked (future_map, beat);
+
+                                       if (solve_map_pulse (future_map, tempo_copy, pulse)) {
+                                               /* snapping to a grid. force MusicTime temporarily. */
+                                               ts->set_position_lock_style (MusicTime);
+                                               solve_map_pulse (_metrics, ts, pulse);
+                                               ts->set_position_lock_style (AudioTime);
+
+                                               recompute_meters (_metrics);
+                                       }
+                               } else {
+                                       solve_map_frame (_metrics, ts, frame);
+                                       recompute_meters (_metrics);
+                               }
                        }
                }
        }
 
-       if (sub_num == 0 && was_musical) {
-               ts->set_position_lock_style (MusicTime);
-       }
-
        Metrics::const_iterator d = future_map.begin();
        while (d != future_map.end()) {
                delete (*d);