summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-12-11 21:14:35 +0000
committerCarl Hetherington <carl@carlh.net>2011-12-11 21:14:35 +0000
commit748b24009bb1b4b104411eb75527d2ec09415c91 (patch)
tree3e9b30bbc553180abe7bf81eae060e86aaa073e4 /libs
parent32c4217994956bb85b4b09508b83dbc9b9ebad23 (diff)
Similar hacks to framepos_minus_beats to handle -ve
positions as were appled to framepos_plus_beats. git-svn-id: svn://localhost/ardour2/branches/3.0@10984 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/tempo.cc21
-rw-r--r--libs/ardour/test/framepos_minus_beats_test.cc4
2 files changed, 22 insertions, 3 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 351b5979e6..dc811aff83 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -2024,6 +2024,15 @@ TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
for (i = metrics->begin(); i != metrics->end(); ++i) {
+ /* This is a bit of a hack, but pos could be -ve, and if it is,
+ we consider the initial metric changes (at time 0) to actually
+ be in effect at pos.
+ */
+ framepos_t f = (*i)->frame ();
+ if (pos < 0 && f == 0) {
+ f = pos;
+ }
+
if ((*i)->frame() > pos) {
break;
}
@@ -2038,9 +2047,13 @@ TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
}
}
+ bool no_more_metrics = false;
+
/* Move i back to the metric before "pos" */
if (i != metrics->begin ()) {
--i;
+ } else {
+ no_more_metrics = true;
}
/* We now have:
@@ -2052,11 +2065,11 @@ TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
while (beats) {
- /* End of this section (looking backwards) */
- framepos_t end = i == metrics->end() ? max_framepos : (*i)->frame ();
+ /* Distance to the end of this section in frames */
+ framecnt_t distance_frames = no_more_metrics ? max_framepos : (pos - (*i)->frame());
/* Distance to the end in beats */
- Evoral::MusicalTime distance_beats = (pos - end) / tempo->frames_per_beat (_frame_rate, *meter);
+ Evoral::MusicalTime distance_beats = distance_frames / tempo->frames_per_beat (_frame_rate, *meter);
/* Amount to subtract this time */
double const sub = min (distance_beats, beats);
@@ -2112,6 +2125,8 @@ TempoMap::framepos_minus_beats (framepos_t pos, Evoral::MusicalTime beats) const
break;
}
}
+ } else {
+ no_more_metrics = true;
}
}
diff --git a/libs/ardour/test/framepos_minus_beats_test.cc b/libs/ardour/test/framepos_minus_beats_test.cc
index f80f57d969..01bafc1606 100644
--- a/libs/ardour/test/framepos_minus_beats_test.cc
+++ b/libs/ardour/test/framepos_minus_beats_test.cc
@@ -27,6 +27,10 @@ FrameposMinusBeatsTest::singleTempoTest ()
/* Subtract 1 beat from beat 3 of the first bar */
framepos_t r = map.framepos_minus_beats (frames_per_beat * 2, 1);
CPPUNIT_ASSERT_EQUAL (r, framepos_t (frames_per_beat * 1));
+
+ /* Subtract 4 beats from 3 beats in, to go beyond zero */
+ r = map.framepos_minus_beats (frames_per_beat * 3, 4);
+ CPPUNIT_ASSERT_EQUAL (r, framepos_t (- frames_per_beat));
}
/* Test adding things that overlap a tempo change */