diff options
author | nick_m <mainsbridge@gmail.com> | 2016-05-27 04:17:49 +1000 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2016-05-27 23:38:18 +1000 |
commit | 1d8522950073a918770acb953c04f6b37c5a74e6 (patch) | |
tree | dfc753c84204e5e5a6e44fc055985d9c80b4b0b9 | |
parent | e2330739ed40f28c0958db1660404d38a31f86ca (diff) |
Tempo ramps - fix up previous commit.
-rw-r--r-- | libs/ardour/tempo.cc | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 7b7d44b934..c79c966794 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -219,14 +219,14 @@ TempoSection::tempo_at_frame (const framepos_t& f, const framecnt_t& frame_rate) /** returns the zero-based frame (relative to session) where the tempo in whole pulses per minute occurs in this section. - beat b is only used for constant tempos. + pulse p is only used for constant tempos. note that the tempo map may have multiple such values. */ framepos_t -TempoSection::frame_at_tempo (const double& ppm, const double& b, const framecnt_t& frame_rate) const +TempoSection::frame_at_tempo (const double& ppm, const double& p, const framecnt_t& frame_rate) const { if (_type == Constant || _c_func == 0.0) { - return ((b - pulse()) * frames_per_pulse (frame_rate)) + frame(); + return ((p - pulse()) * frames_per_pulse (frame_rate)) + frame(); } return minute_to_frame (time_at_pulse_tempo (ppm), frame_rate) + frame(); @@ -1612,7 +1612,8 @@ TempoMap::tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame return ret_tempo; } -/** returns the frame at which the supplied tempo occurs, or 0. +/** returns the frame at which the supplied tempo occurs, or + * the frame of the last tempo section (search exhausted) * only the position of the first occurence will be returned * (extend me) */ @@ -1628,25 +1629,37 @@ framepos_t TempoMap::frame_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const { TempoSection* prev_t = 0; + const double tempo_ppm = tempo.beats_per_minute() / tempo.note_type(); Metrics::const_iterator i; for (i = _metrics.begin(); i != _metrics.end(); ++i) { TempoSection* t; if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + if (!t->active()) { continue; } - if ((prev_t) && t->beats_per_minute() / t->note_type() > tempo.beats_per_minute() / tempo.note_type()) { - /* t has a greater tempo */ - const framepos_t ret_frame = prev_t->frame_at_tempo (tempo.beats_per_minute() / tempo.note_type(), 1.0, _frame_rate); - return ret_frame; + + const double t_ppm = t->beats_per_minute() / t->note_type(); + + if (t_ppm == tempo_ppm) { + return t->frame(); + } + + if (prev_t) { + const double prev_t_ppm = prev_t->beats_per_minute() / prev_t->note_type(); + + if ((t_ppm > tempo_ppm && prev_t_ppm < tempo_ppm) || (t_ppm < tempo_ppm && prev_t_ppm > tempo_ppm)) { + const framepos_t ret_frame = prev_t->frame_at_tempo (tempo_ppm, prev_t->pulse(), _frame_rate); + return ret_frame; + } } prev_t = t; } } - return 0; + return prev_t->frame(); } |