summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-12-10 16:06:29 +0000
committerCarl Hetherington <carl@carlh.net>2011-12-10 16:06:29 +0000
commit6e211e27e2027da328b6fe117f10e1962c007afb (patch)
tree69bb4b49eacdf2ae8f41d7dcefda3ac1391074b5 /libs/ardour
parent6b27595c4e7f92fc996932ea1d5b98cfccdc8892 (diff)
Slightly simpler implementation of framewalk_to_beats.
git-svn-id: svn://localhost/ardour2/branches/3.0@10967 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/tempo.h2
-rw-r--r--libs/ardour/tempo.cc111
2 files changed, 30 insertions, 83 deletions
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index aa4266f35a..a6f7a36541 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -249,7 +249,7 @@ class TempoMap : public PBD::StatefulDestructible
framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b) const;
framepos_t framepos_plus_beats (framepos_t, Evoral::MusicalTime) const;
- double framewalk_to_beats (framepos_t pos, framecnt_t distance) const;
+ Evoral::MusicalTime framewalk_to_beats (framepos_t pos, framecnt_t distance) const;
void change_existing_tempo_at (framepos_t, double bpm, double note_type);
void change_initial_tempo (double bpm, double note_type);
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 97ec1224f0..7a653547da 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -2135,29 +2135,15 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
return pos;
}
-
/** Count the number of beats that are equivalent to distance when starting at pos */
-double
+Evoral::MusicalTime
TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance) const
{
Metrics::const_iterator i;
- double beats = 0;
- const MeterSection* meter;
- const MeterSection* m;
const TempoSection* tempo;
- const TempoSection* t;
- double frames_per_beat;
-
- double ddist = distance;
- double dpos = pos;
-
- meter = &first_meter ();
- tempo = &first_tempo ();
-
- assert (meter);
- assert (tempo);
-
- /* find the starting metrics for tempo & meter */
+ const MeterSection* meter;
+
+ /* Find the starting metrics for tempo & meter */
for (i = metrics->begin(); i != metrics->end(); ++i) {
@@ -2165,6 +2151,9 @@ TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance) const
break;
}
+ const TempoSection* t;
+ const MeterSection* m;
+
if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
tempo = t;
} else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
@@ -2179,83 +2168,41 @@ TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance) const
i -> for first new metric after "pos", possibly metrics->end()
*/
- /* now comes the complicated part. we have to add one beat a time,
- checking for a new metric on every beat.
- */
-
- frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
-
- double last_dpos = 0;
-
- while (ddist > 0) {
-
- /* if we're nearly at the end, but have a fractional beat left,
- compute the fraction and then its all over
- */
-
- if (ddist < frames_per_beat) {
- beats += ddist / frames_per_beat;
- break;
- }
-
- /* walk one beat */
+ Evoral::MusicalTime beats = 0;
- last_dpos = dpos;
- ddist -= frames_per_beat;
- dpos += frames_per_beat;
- beats += 1.0;
+ while (distance) {
- /* check if we need to use a new metric section: has adding frames moved us
- to or after the start of the next metric section? in which case, use it.
- */
-
- if (i != metrics->end()) {
-
- double const f = (*i)->frame ();
-
- if (f <= (framepos_t) dpos) {
-
- /* We just went past a tempo/meter section start at (*i)->frame(),
- which will be on a beat.
-
- So what we have is
-
- (*i)->frame() [f]
- beat beat beat beat
- | | | |
- | | | |
- ^ ^
- | |
- | new
- | dpos [q]
- last
- dpos [p]
+ /* End of this section */
+ framepos_t const end = i == metrics->end() ? max_framepos : (*i)->frame ();
- We need to go back to last_dpos (1 beat ago) and re-add
- (f - p) beats using the old frames per beat and (q - f) beats
- using the new.
- */
+ /* Distance to the end in frames */
+ framecnt_t const distance_to_end = end - pos;
- beats -= 1;
- beats += (f - last_dpos) / frames_per_beat;
+ /* Amount to subtract this time */
+ double const sub = min (distance, distance_to_end);
- if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
- tempo = t;
- } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
- meter = m;
- }
- ++i;
- frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
+ /* Update */
+ distance -= sub;
+ beats += sub / tempo->frames_per_beat (_frame_rate, *meter);
- beats += (dpos - f) / frames_per_beat;
+ /* Move on if there's anything to move to */
+ if (i != metrics->end ()) {
+ const TempoSection* t;
+ const MeterSection* m;
+
+ if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
+ tempo = t;
+ } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {
+ meter = m;
}
+
+ ++i;
}
}
return beats;
}
-
/** Compare the time of this with that of another MetricSection.
* @param with_bbt True to compare using start(), false to use frame().
* @return -1 for less than, 0 for equal, 1 for greater than.