return ret_frame;
}
-void
-TempoMap::round_bbt (BBT_Time& when, const int32_t& sub_num, RoundMode dir)
-{
- if (sub_num == -1) {
- if (dir > 0) {
- ++when.bars;
- when.beats = 1;
- when.ticks = 0;
- } else if (dir < 0) {
- when.beats = 1;
- when.ticks = 0;
- } else {
- const double bpb = meter_section_at_beat (beat_at_bbt_locked (_metrics, when)).divisions_per_bar();
- if ((double) when.beats > bpb / 2.0) {
- ++when.bars;
- }
- when.beats = 1;
- when.ticks = 0;
- }
-
- return;
-
- } else if (sub_num == 0) {
- const double bpb = meter_section_at_beat (beat_at_bbt_locked (_metrics, when)).divisions_per_bar();
- if ((double) when.ticks > BBT_Time::ticks_per_beat / 2.0) {
- ++when.beats;
- while ((double) when.beats > bpb) {
- ++when.bars;
- when.beats -= (uint32_t) floor (bpb);
- }
- }
- when.ticks = 0;
-
- return;
- }
-
- const uint32_t ticks_one_subdivisions_worth = BBT_Time::ticks_per_beat / sub_num;
-
- if (dir > 0) {
- /* round to next (or same iff dir == RoundUpMaybe) */
-
- uint32_t mod = when.ticks % ticks_one_subdivisions_worth;
-
- 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 */
- when.ticks += ticks_one_subdivisions_worth;
-
- } else {
- /* not on subdivision, compute distance to next subdivision */
-
- when.ticks += ticks_one_subdivisions_worth - mod;
- }
-
- if (when.ticks >= BBT_Time::ticks_per_beat) {
- ++when.beats;
- const double bpb = meter_section_at_beat (beat_at_bbt_locked (_metrics, when)).divisions_per_bar();
- if ((double) when.beats > bpb) {
- ++when.bars;
- when.beats = 1;
- }
- when.ticks -= BBT_Time::ticks_per_beat;
- }
-
- } else if (dir < 0) {
- /* round to previous (or same iff dir == RoundDownMaybe) */
-
- uint32_t difference = when.ticks % ticks_one_subdivisions_worth;
-
- if (difference == 0 && dir == RoundDownAlways) {
- /* right on the subdivision, but force-rounding down,
- so the difference is just the subdivision ticks */
- difference = ticks_one_subdivisions_worth;
- }
-
- if (when.ticks < difference) {
- --when.beats;
- const double bpb = meter_section_at_beat (beat_at_bbt_locked (_metrics, when)).divisions_per_bar();
- if ((double) when.beats < bpb) {
- --when.bars;
- //when.beats = 1;
- }
- when.ticks = BBT_Time::ticks_per_beat - when.ticks;
- } else {
- when.ticks -= difference;
- }
-
- } else {
- /* round to nearest */ double rem;
- if ((rem = fmod ((double) when.ticks, (double) ticks_one_subdivisions_worth)) > (ticks_one_subdivisions_worth / 2.0)) {
- /* closer to the next subdivision, so shift forward */
-
- when.ticks = when.ticks + (ticks_one_subdivisions_worth - rem);
-
- if (when.ticks > Timecode::BBT_Time::ticks_per_beat) {
- ++when.beats;
- when.ticks -= Timecode::BBT_Time::ticks_per_beat;
- }
-
- } else if (rem > 0) {
- /* closer to previous subdivision, so shift backward */
-
- if (rem > when.ticks) {
- if (when.beats == 0) {
- /* can't go backwards past zero, so ... */
- }
- /* step back to previous beat */
- --when.beats;
- when.ticks = Timecode::BBT_Time::ticks_per_beat - rem;
- } else {
- when.ticks = when.ticks - rem;
- }
- }
- }
-}
-
framepos_t
TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
{