Set tempo sections to the exact pulse when snapped to a musical grid.
authornick_m <mainsbridge@gmail.com>
Sat, 11 Jun 2016 14:42:43 +0000 (00:42 +1000)
committernick_m <mainsbridge@gmail.com>
Sat, 11 Jun 2016 14:42:43 +0000 (00:42 +1000)
gtk2_ardour/editor_drag.cc
libs/ardour/ardour/tempo.h
libs/ardour/tempo.cc

index c95979514ffb85264fe791ffae2cb44aa0dd8baf..635a590b6aa2333589ba58c96a500b24b20dd67d 100644 (file)
@@ -3335,29 +3335,22 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
                show_verbose_cursor_text (strs.str());
 
        } else if (_movable && !_real_section->locked_to_meter()) {
+               const framepos_t pf = adjusted_current_frame (event);
                TempoMap& map (_editor->session()->tempo_map());
-               const bool was_music = _real_section->position_lock_style() == MusicTime;
 
-               const framepos_t pf = adjusted_current_frame (event);
+               /* snap to beat is -2, snap to bar is -3 (sorry) */
+               int sub_num = _editor->get_grid_beat_divisions (0);
 
-               /* cop-out : we really should set the musical position of music-locked tempo sections here, which generally works well.
-                  The problem is that when the mouse pointer's motion causes the location of the beat to change in a more-or-less
-                  chaotic way when cross-dragging tempo sections (the beat the pointer is now above could have changed without any pointer motion).
-                  Until there is a way to deal with this, just pretend the tempo section is audio-locked.
-               */
-               if (was_music) {
-                       _real_section->set_position_lock_style (AudioTime);
+               if (_editor->snap_type() == SnapToBar) {
+                       sub_num = -3;
+               } else if (_editor->snap_type() == SnapToBeat) {
+                       sub_num = -2;
                }
 
-               map.gui_move_tempo (_real_section, pf);
-
-               if (was_music) {
-                       _real_section->set_position_lock_style (MusicTime);
-               }
+               map.gui_move_tempo (_real_section, pf, _editor->get_grid_beat_divisions (0));
 
                show_verbose_cursor_time (_real_section->frame());
        }
-
        _marker->set_position (adjusted_current_frame (event, false));
 }
 
index a04f1bb072b19033f68f10d7b304a962ae0b0a74..33d9fb937d6af3aa78396ca787cfe95f6ec75deb 100644 (file)
@@ -445,7 +445,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        framepos_t framepos_minus_beats (framepos_t, Evoral::Beats) const;
        Evoral::Beats framewalk_to_beats (framepos_t pos, framecnt_t distance) const;
 
-       void gui_move_tempo (TempoSection*, const framepos_t& frame);
+       void gui_move_tempo (TempoSection*, const framepos_t& frame, const int& sub_num);
        void gui_move_meter (MeterSection*, const framepos_t& frame);
        bool gui_change_tempo (TempoSection*, const Tempo& bpm);
        void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame, const double& pulse);
index d0cf857ad9577db02686637ddd955e53c27edeb6..15323751b41f59ac1db61eda324dbb3d6cc6bed4 100644 (file)
@@ -2528,15 +2528,31 @@ TempoMap::predict_tempo_position (TempoSection* section, const BBT_Time& bbt)
 }
 
 void
-TempoMap::gui_move_tempo (TempoSection* ts, const framepos_t& frame)
+TempoMap::gui_move_tempo (TempoSection* ts, const framepos_t& frame, const int& sub_num)
 {
        Metrics future_map;
 
        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 pulse = pulse_at_frame_locked (future_map, frame);
+                       double beat = beat_at_frame_locked (future_map, frame);
+
+                       if (sub_num > 0) {
+                               beat = floor (beat) + (floor (((beat - floor (beat)) * (double) sub_num) + 0.5) / sub_num);
+                       } else if (sub_num == -2) {
+                               /* snap to beat */
+                               beat = floor (beat + 0.5);
+                       }
+
+                       double pulse = pulse_at_beat_locked (future_map, beat);
+
+                       if (sub_num == -3) {
+                               /* snap to  bar */
+                               pulse = floor (pulse + 0.5);
+                       }
+
                        if (solve_map_pulse (future_map, tempo_copy, pulse)) {
                                solve_map_pulse (_metrics, ts, pulse);
                                recompute_meters (_metrics);