Fix off-by-one in body_range().
[ardour.git] / libs / ardour / tempo.cc
index ef74c09c2783c0c12786ac383d85e34dccb478b5..e64a1169333023bf72021c3f86b144cbe549d6d4 100644 (file)
 
 #include <algorithm>
 #include <stdexcept>
+#include <cmath>
 
 #include <unistd.h>
 
-#include <cmath>
-
 #include <glibmm/thread.h>
 #include "pbd/xml++.h"
 #include "evoral/types.hpp"
 #include "ardour/debug.h"
 #include "ardour/tempo.h"
-#include "ardour/utils.h"
 
 #include "i18n.h"
 #include <locale.h>
@@ -1195,7 +1193,7 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
 }
 
 framecnt_t
-TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir
+TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int /*dir*/
 {
        if (bbt.bars == 0 && bbt.beats == 0 && bbt.ticks == 0) {
                return 0;
@@ -1806,7 +1804,7 @@ TempoMap::framepos_plus_beats (framepos_t pos, Evoral::MusicalTime beats) const
 {
        Glib::RWLock::ReaderLock lm (lock);
        Metrics::const_iterator next_tempo;
-       const TempoSection* tempo;
+       const TempoSection* tempo = 0;
 
        /* Find the starting tempo metric */
 
@@ -1889,7 +1887,7 @@ TempoMap::framepos_plus_beats (framepos_t pos, Evoral::MusicalTime beats) const
        return pos;
 }
 
-/** Subtract some (fractional) beats to a frame position, and return the result in frames */
+/** Subtract some (fractional) beats from a frame position, and return the result in frames */
 framepos_t
 TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
 {
@@ -2177,10 +2175,18 @@ TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance) const
        while (distance) {
 
                /* End of this section */
-               framepos_t const end = ((next_tempo == metrics.end()) ? max_framepos : (*next_tempo)->frame ());
-
-               /* Distance to the end in frames */
-               framecnt_t const distance_to_end = end - pos;
+               framepos_t end;
+               /* Distance to `end' in frames */
+               framepos_t distance_to_end;
+
+               if (next_tempo == metrics.end ()) {
+                       /* We can't do (end - pos) if end is max_framepos, as it will overflow if pos is -ve */
+                       end = max_framepos;
+                       distance_to_end = max_framepos;
+               } else {
+                       end = (*next_tempo)->frame ();
+                       distance_to_end = end - pos;
+               }
 
                /* Amount to subtract this time */
                double const sub = min (distance, distance_to_end);