mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-30 08:53:08 +01:00
Add "maybe" rounding modes for rounding only if necessary.
This commit is contained in:
parent
fd9ccc7058
commit
d63161426f
4 changed files with 47 additions and 15 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue