summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2016-08-10 00:48:53 +1000
committernick_m <mainsbridge@gmail.com>2016-08-10 00:48:53 +1000
commit4ddb6b74f5c0fe445b49e9abb5527afecc60dd8b (patch)
treec2bccf13e1d2a1bd424b05d2e3078fd6c1410b57 /libs
parent73db972ab7b2c53506481dbb2f5606a0ca03eee9 (diff)
Allow -ve framepos handling in TempoMap::framepos_plus_beats()
- also handles frame positions previous to the initial meter (beat_at_frame() would return 0 in this case).
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/tempo.cc25
1 files changed, 23 insertions, 2 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 56f88d33d9..11da2fc81d 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -3799,11 +3799,32 @@ TempoMap::remove_time (framepos_t where, framecnt_t amount)
* pos can be -ve, if required.
*/
framepos_t
-TempoMap::framepos_plus_beats (framepos_t pos, Evoral::Beats beats) const
+TempoMap::framepos_plus_beats (framepos_t frame, Evoral::Beats beats) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- return frame_at_beat_locked (_metrics, beat_at_frame_locked (_metrics, pos) + beats.to_double());
+ const TempoSection& ts = tempo_section_at_frame_locked (_metrics, frame);
+ MeterSection* prev_m = 0;
+ MeterSection* next_m = 0;
+
+ for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+ if (!(*i)->is_tempo()) {
+ if (prev_m && (*i)->frame() > frame) {
+ next_m = static_cast<MeterSection*> (*i);
+ break;
+ }
+ prev_m = static_cast<MeterSection*> (*i);
+ }
+ }
+
+ double pos_beat = prev_m->beat() + (ts.pulse_at_frame (frame, _frame_rate) - prev_m->pulse()) * prev_m->note_divisor();
+
+ /* audio locked meters fake their beat */
+ if (next_m && next_m->beat() < pos_beat) {
+ pos_beat = next_m->beat();
+ }
+
+ return frame_at_beat_locked (_metrics, pos_beat + beats.to_double());
}
/** Subtract some (fractional) beats from a frame position, and return the result in frames */