From 4ddb6b74f5c0fe445b49e9abb5527afecc60dd8b Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 10 Aug 2016 00:48:53 +1000 Subject: [PATCH] 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). --- libs/ardour/tempo.cc | 25 +++++++++++++++++++++++-- 1 file 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 (*i); + break; + } + prev_m = static_cast (*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 */ -- 2.30.2