diff options
-rw-r--r-- | gtk2_ardour/editor.cc | 30 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 4 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 24 |
4 files changed, 47 insertions, 15 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index ac59ecab4f..e50ef98290 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2588,7 +2588,10 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool switch (_snap_type) { case SnapToTimecodeFrame: - if (((direction == 0) && (fmod((double)start, (double)_session->frames_per_timecode_frame()) > (_session->frames_per_timecode_frame() / 2))) || (direction > 0)) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + fmod((double)start, (double)_session->frames_per_timecode_frame()) == 0) { + /* start is already on a whole timecode frame, do nothing */ + } else if (((direction == 0) && (fmod((double)start, (double)_session->frames_per_timecode_frame()) > (_session->frames_per_timecode_frame() / 2))) || (direction > 0)) { start = (framepos_t) (ceil ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame()); } else { start = (framepos_t) (floor ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame()); @@ -2601,7 +2604,10 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool } else { start -= _session->config.get_timecode_offset (); } - if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + (start % one_timecode_second == 0)) { + /* start is already on a whole second, do nothing */ + } else if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) { start = (framepos_t) ceil ((double) start / one_timecode_second) * one_timecode_second; } else { start = (framepos_t) floor ((double) start / one_timecode_second) * one_timecode_second; @@ -2620,7 +2626,10 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool } else { start -= _session->config.get_timecode_offset (); } - if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + (start % one_timecode_minute == 0)) { + /* start is already on a whole minute, do nothing */ + } else if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) { start = (framepos_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute; } else { start = (framepos_t) floor ((double) start / one_timecode_minute) * one_timecode_minute; @@ -2653,7 +2662,10 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark) return timecode_snap_to_internal (start, direction, for_mark); case SnapToCDFrame: - if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + start % (one_second/75) == 0) { + /* start is already on a whole CD frame, do nothing */ + } else if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) { start = (framepos_t) ceil ((double) start / (one_second / 75)) * (one_second / 75); } else { start = (framepos_t) floor ((double) start / (one_second / 75)) * (one_second / 75); @@ -2661,7 +2673,10 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark) break; case SnapToSeconds: - if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + start % one_second == 0) { + /* start is already on a whole second, do nothing */ + } else if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) { start = (framepos_t) ceil ((double) start / one_second) * one_second; } else { start = (framepos_t) floor ((double) start / one_second) * one_second; @@ -2669,7 +2684,10 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark) break; case SnapToMinutes: - if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + start % one_minute == 0) { + /* start is already on a whole minute, do nothing */ + } else if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) { start = (framepos_t) ceil ((double) start / one_minute) * one_minute; } else { start = (framepos_t) floor ((double) start / one_minute) * one_minute; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 9df013264f..773ef191df 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4221,9 +4221,9 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) if (first_move) { grab = adjusted_current_frame (event, false); if (grab < pending_position) { - _editor->snap_to (grab, RoundDownAlways); + _editor->snap_to (grab, RoundDownMaybe); } else { - _editor->snap_to (grab, RoundUpAlways); + _editor->snap_to (grab, RoundUpMaybe); } } diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 1b0ba5ea3c..5daf9065e3 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -217,9 +217,11 @@ namespace ARDOUR { }; enum RoundMode { + RoundDownMaybe = -2, ///< Round down only if necessary RoundDownAlways = -1, ///< Always round down, even if on a division RoundNearest = 0, ///< Round to nearest - RoundUpAlways = 1 ///< Always round up, even if on a division + RoundUpAlways = 1, ///< Always round up, even if on a division + RoundUpMaybe = 2 ///< Round up only if necessary }; class AnyTime { diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 77128bd0c2..6f667a93b6 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1254,11 +1254,14 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir) if (dir > 0) { - /* round to next (even if we're on a subdivision */ + /* round to next (or same iff dir == RoundUpMaybe) */ uint32_t mod = the_beat.ticks % ticks_one_subdivisions_worth; - if (mod == 0) { + if (mod == 0 && dir == RoundUpMaybe) { + /* right on the subdivision, which is fine, so do nothing */ + + } else if (mod == 0) { /* right on the subdivision, so the difference is just the subdivision ticks */ the_beat.ticks += ticks_one_subdivisions_worth; @@ -1278,11 +1281,14 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir) } else if (dir < 0) { - /* round to previous (even if we're on a subdivision) */ + /* round to previous (or same iff dir == RoundDownMaybe) */ uint32_t mod = the_beat.ticks % ticks_one_subdivisions_worth; - if (mod == 0) { + if (mod == 0 && dir == RoundDownMaybe) { + /* right on the subdivision, which is fine, so do nothing */ + + } else if (mod == 0) { /* right on the subdivision, so the difference is just the subdivision ticks */ difference = ticks_one_subdivisions_worth; } else { @@ -1382,6 +1388,9 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) } if ((*fi).is_bar() && (*fi).frame == frame) { + if (dir == RoundDownMaybe) { + return frame; + } --fi; } @@ -1400,6 +1409,9 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) /* find bar following 'frame' */ if ((*fi).is_bar() && (*fi).frame == frame) { + if (dir == RoundUpMaybe) { + return frame; + } ++fi; } @@ -1454,7 +1466,7 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) return 0; } - if ((*fi).frame >= frame) { + if ((*fi).frame > frame || ((*fi).frame == frame && dir == RoundDownAlways)) { DEBUG_TRACE (DEBUG::SnapBBT, "requested frame is on beat, step back\n"); --fi; } @@ -1462,7 +1474,7 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) (*fi).bar, (*fi).beat, (*fi).frame)); return (*fi).frame; } else if (dir > 0) { - if ((*fi).frame <= frame) { + if ((*fi).frame < frame || ((*fi).frame == frame && dir == RoundUpAlways)) { DEBUG_TRACE (DEBUG::SnapBBT, "requested frame is on beat, step forward\n"); ++fi; } |