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());
} 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;
} 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;
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);
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;
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;
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;
} 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 {
}
if ((*fi).is_bar() && (*fi).frame == frame) {
+ if (dir == RoundDownMaybe) {
+ return frame;
+ }
--fi;
}
/* find bar following 'frame' */
if ((*fi).is_bar() && (*fi).frame == frame) {
+ if (dir == RoundUpMaybe) {
+ return frame;
+ }
++fi;
}
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;
}
(*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;
}