Tempo ramps - rename meter_at() -> meter_at_frame() & make the ticker slightly more...
[ardour.git] / libs / ardour / tempo.cc
index 4a0151b22c7298df3c60b3ee446a656c638d5db3..36ac3a8203d03703ffccb8b2a001615d3eec14d5 100644 (file)
@@ -649,7 +649,7 @@ TempoMap::TempoMap (framecnt_t fr)
        _frame_rate = fr;
        BBT_Time start (1, 1, 0);
 
-       TempoSection *t = new TempoSection (0.0, 0, _default_tempo.beats_per_minute(), _default_tempo.note_type(), TempoSection::Constant, AudioTime);
+       TempoSection *t = new TempoSection (0.0, 0, _default_tempo.beats_per_minute(), _default_tempo.note_type(), TempoSection::Ramp, AudioTime);
        MeterSection *m = new MeterSection (0.0, 0, 0.0, start, _default_meter.divisions_per_bar(), _default_meter.note_divisor(), AudioTime);
 
        t->set_movable (false);
@@ -775,10 +775,10 @@ TempoMap::do_insert (MetricSection* section)
 
                if ((m->bbt().beats != 1) || (m->bbt().ticks != 0)) {
 
-                       pair<double, BBT_Time> corrected = make_pair (m->pulse(), m->bbt());
+                       pair<double, BBT_Time> corrected = make_pair (m->beat(), m->bbt());
                        corrected.second.beats = 1;
                        corrected.second.ticks = 0;
-                       corrected.first = bbt_to_beats_locked (_metrics, corrected.second);
+                       corrected.first = beat_at_bbt_locked (_metrics, corrected.second);
                        warning << string_compose (_("Meter changes can only be positioned on the first beat of a bar. Moving from %1 to %2"),
                                                   m->bbt(), corrected.second) << endmsg;
                        //m->set_pulse (corrected);
@@ -981,7 +981,7 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
 {
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               const double beat = bbt_to_beats_locked (_metrics, where);
+               const double beat = beat_at_bbt_locked (_metrics, where);
 
                if (ms.movable()) {
                        remove_meter_locked (ms);
@@ -999,9 +999,10 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
                        first_t.set_frame (first.frame());
                        first_t.set_pulse (0.0);
                        first_t.set_position_lock_style (AudioTime);
+                       recompute_map (_metrics);
                }
-               recompute_map (_metrics);
        }
+
        PropertyChanged (PropertyChange ());
 }
 
@@ -1013,7 +1014,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, const Timecode::BBT
 
        if (pls == AudioTime) {
                /* add meter-locked tempo */
-               add_tempo_locked (tempo_at_locked (_metrics, frame), pulse,  frame, TempoSection::Ramp, AudioTime, true, true);
+               add_tempo_locked (tempo_at_frame_locked (_metrics, frame), pulse,  frame, TempoSection::Ramp, AudioTime, true, true);
        }
 
        MeterSection* new_meter = new MeterSection (pulse, frame, beat, where, meter.divisions_per_bar(), meter.note_divisor(), pls);
@@ -1272,24 +1273,24 @@ TempoMap::recompute_meters (Metrics& metrics)
                        } else {
                                /* MusicTime */
                                double pulse = 0.0;
-                               pair<double, BBT_Time> new_beat;
+                               pair<double, BBT_Time> b_bbt;
                                if (prev_m) {
                                        const double beats = (meter->bbt().bars - prev_m->bbt().bars) * prev_m->divisions_per_bar();
                                        if (beats + prev_m->beat() != meter->beat()) {
                                                /* reordering caused a bbt change */
-                                               new_beat = make_pair (beats + prev_m->beat()
+                                               b_bbt = make_pair (beats + prev_m->beat()
                                                                   , BBT_Time ((beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0));
                                        } else {
-                                               new_beat = make_pair (beats + prev_m->beat(), meter->bbt());
+                                               b_bbt = make_pair (beats + prev_m->beat(), meter->bbt());
                                        }
                                        pulse = (beats / prev_m->note_divisor()) + prev_m->pulse();
                                } else {
                                        /* shouldn't happen - the first is audio-locked */
                                        pulse = pulse_at_beat_locked (metrics, meter->beat());
-                                       new_beat = make_pair (meter->beat(), meter->bbt());
+                                       b_bbt = make_pair (meter->beat(), meter->bbt());
                                }
 
-                               meter->set_beat (new_beat);
+                               meter->set_beat (b_bbt);
                                meter->set_pulse (pulse);
                                meter->set_frame (frame_at_pulse_locked (metrics, pulse));
                        }
@@ -1384,6 +1385,70 @@ TempoMap::metric_at (BBT_Time bbt) const
        return m;
 }
 
+double
+TempoMap::beat_at_frame (const framecnt_t& frame) const
+{
+       Glib::Threads::RWLock::ReaderLock lm (lock);
+       return beat_at_frame_locked (_metrics, frame);
+}
+
+/* meter / tempo section based */
+double
+TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
+{
+       const TempoSection& ts = tempo_section_at_locked (metrics, frame);
+       MeterSection* prev_m = 0;
+       MeterSection* next_m = 0;
+
+       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               MeterSection* m;
+               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
+                       if (prev_m && m->frame() > frame) {
+                               next_m = m;
+                               break;
+                       }
+                       prev_m = m;
+               }
+       }
+       if (frame < prev_m->frame()) {
+               return 0.0;
+       }
+       const double beat = prev_m->beat() + (ts.pulse_at_frame (frame, _frame_rate) - prev_m->pulse()) * prev_m->note_divisor();
+
+       if (next_m && next_m->beat() < beat) {
+               return next_m->beat();
+       }
+
+       return beat;
+}
+
+framecnt_t
+TempoMap::frame_at_beat (const double& beat) const
+{
+       Glib::Threads::RWLock::ReaderLock lm (lock);
+       return frame_at_beat_locked (_metrics, beat);
+}
+
+/* meter section based */
+framecnt_t
+TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
+{
+       const TempoSection& prev_t = tempo_section_at_beat_locked (metrics, beat);
+       MeterSection* prev_m = 0;
+
+       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               MeterSection* m;
+               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
+                       if (prev_m && m->beat() > beat) {
+                               break;
+                       }
+                       prev_m = m;
+               }
+       }
+
+       return prev_t.frame_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(), _frame_rate);
+}
+
 double
 TempoMap::pulse_at_beat (const double& beat) const
 {
@@ -1511,80 +1576,53 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
        return ret;
 }
 
-double
-TempoMap::beat_at_frame (const framecnt_t& frame) const
+const Tempo
+TempoMap::tempo_at_frame (const framepos_t& frame) const
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return beat_at_frame_locked (_metrics, frame);
+       return tempo_at_frame_locked (_metrics, frame);
 }
 
-/* meter / tempo section based */
-double
-TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
+const Tempo
+TempoMap::tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const
 {
-       const TempoSection& ts = tempo_section_at_locked (metrics, frame);
-       MeterSection* prev_m = 0;
-       MeterSection* next_m = 0;
+       TempoSection* prev_t = 0;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
-               MeterSection* m;
-               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
-                       if (prev_m && m->frame() > frame) {
-                               next_m = m;
-                               break;
+       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;
                        }
-                       prev_m = m;
+                       if ((prev_t) && t->frame() > frame) {
+                               /* t is the section past frame */
+                               const double ret_bpm = prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type();
+                               const Tempo ret_tempo (ret_bpm, prev_t->note_type());
+                               return ret_tempo;
+                       }
+                       prev_t = t;
                }
        }
-       if (frame < prev_m->frame()) {
-               return 0.0;
-       }
-       const double beat = prev_m->beat() + (ts.pulse_at_frame (frame, _frame_rate) - prev_m->pulse()) * prev_m->note_divisor();
 
-       if (next_m && next_m->beat() < beat) {
-               return next_m->beat();
-       }
-
-       return beat;
-}
+       const double ret = prev_t->beats_per_minute();
+       const Tempo ret_tempo (ret, prev_t->note_type ());
 
-framecnt_t
-TempoMap::frame_at_beat (const double& beat) const
-{
-       Glib::Threads::RWLock::ReaderLock lm (lock);
-       return frame_at_beat_locked (_metrics, beat);
+       return ret_tempo;
 }
 
-/* meter section based */
-framecnt_t
-TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
-{
-       const TempoSection& prev_t = tempo_section_at_beat_locked (metrics, beat);
-       MeterSection* prev_m = 0;
-
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
-               MeterSection* m;
-               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
-                       if (prev_m && m->beat() > beat) {
-                               break;
-                       }
-                       prev_m = m;
-               }
-       }
-
-       return prev_t.frame_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(), _frame_rate);
-}
 
 double
-TempoMap::bbt_to_beats (const Timecode::BBT_Time& bbt)
+TempoMap::beat_at_bbt (const Timecode::BBT_Time& bbt)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return bbt_to_beats_locked (_metrics, bbt);
+       return beat_at_bbt_locked (_metrics, bbt);
 }
 
 
 double
-TempoMap::bbt_to_beats_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const
+TempoMap::beat_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const
 {
        /* CALLER HOLDS READ LOCK */
 
@@ -1614,14 +1652,14 @@ TempoMap::bbt_to_beats_locked (const Metrics& metrics, const Timecode::BBT_Time&
 }
 
 Timecode::BBT_Time
-TempoMap::beats_to_bbt (const double& beats)
+TempoMap::bbt_at_beat (const double& beats)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return beats_to_bbt_locked (_metrics, beats);
+       return bbt_at_beat_locked (_metrics, beats);
 }
 
 Timecode::BBT_Time
-TempoMap::beats_to_bbt_locked (const Metrics& metrics, const double& b) const
+TempoMap::bbt_at_beat_locked (const Metrics& metrics, const double& b) const
 {
        /* CALLER HOLDS READ LOCK */
        MeterSection* prev_m = 0;
@@ -1671,13 +1709,57 @@ TempoMap::beats_to_bbt_locked (const Metrics& metrics, const double& b) const
        return ret;
 }
 
+double
+TempoMap::pulse_at_bbt (const Timecode::BBT_Time& bbt)
+{
+       Glib::Threads::RWLock::ReaderLock lm (lock);
+
+       return pulse_at_bbt_locked (_metrics, bbt);
+}
+
+double
+TempoMap::pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const
+{
+       /* CALLER HOLDS READ LOCK */
+
+       MeterSection* prev_m = 0;
+
+       /* because audio-locked meters have 'fake' integral beats,
+          there is no pulse offset here.
+       */
+       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               MeterSection* m;
+               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
+                       if (prev_m) {
+                               if (m->bbt().bars > bbt.bars) {
+                                       break;
+                               }
+                       }
+                       prev_m = m;
+               }
+       }
+
+       const double remaining_bars = bbt.bars - prev_m->bbt().bars;
+       const double remaining_pulses = remaining_bars * prev_m->divisions_per_bar() / prev_m->note_divisor();
+       const double ret = remaining_pulses + prev_m->pulse() + (((bbt.beats - 1) + (bbt.ticks / BBT_Time::ticks_per_beat)) / prev_m->note_divisor());
+
+       return ret;
+}
+
 Timecode::BBT_Time
-TempoMap::pulse_to_bbt (const double& pulse)
+TempoMap::bbt_at_pulse (const double& pulse)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
+
+       return bbt_at_pulse_locked (_metrics, pulse);
+}
+
+Timecode::BBT_Time
+TempoMap::bbt_at_pulse_locked (const Metrics& metrics, const double& pulse) const
+{
        MeterSection* prev_m = 0;
 
-       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
                MeterSection* m = 0;
 
                if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
@@ -1737,7 +1819,7 @@ TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt)
        Glib::Threads::RWLock::ReaderLock lm (lock);
        const double beat = beat_at_frame_locked (_metrics, frame);
 
-       bbt = beats_to_bbt_locked (_metrics, beat);
+       bbt = bbt_at_beat_locked (_metrics, beat);
 }
 
 framepos_t
@@ -1762,7 +1844,7 @@ TempoMap::frame_time_locked (const Metrics& metrics, const BBT_Time& bbt) const
 {
        /* HOLD THE READER LOCK */
 
-       const framepos_t ret = frame_at_beat_locked (metrics, bbt_to_beats_locked (metrics, bbt));
+       const framepos_t ret = frame_at_beat_locked (metrics, beat_at_bbt_locked (metrics, bbt));
        return ret;
 }
 
@@ -1784,8 +1866,8 @@ TempoMap::check_solved (const Metrics& metrics) const
                                        return false;
                                }
 
-                               /* precision check ensures pulses and frames align.*/
-                               if (t->frame() != prev_t->frame_at_pulse (t->pulse(), _frame_rate)) {
+                               /* precision check ensures tempo and frames align.*/
+                               if (t->frame() != prev_t->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate)) {
                                        if (!t->locked_to_meter()) {
                                                return false;
                                        }
@@ -2304,8 +2386,7 @@ TempoMap::can_solve_bbt (TempoSection* ts, const BBT_Time& bbt)
                }
        }
 
-       const double beat = bbt_to_beats_locked (copy, bbt);
-       const bool ret = solve_map_pulse (copy, tempo_copy, pulse_at_beat_locked (copy, beat));
+       const bool ret = solve_map_pulse (copy, tempo_copy, pulse_at_bbt_locked (copy, bbt));
 
        Metrics::const_iterator d = copy.begin();
        while (d != copy.end()) {
@@ -2333,7 +2414,7 @@ TempoMap::predict_tempo_position (TempoSection* section, const BBT_Time& bbt)
 
        TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, section);
 
-       const double beat = bbt_to_beats_locked (future_map, bbt);
+       const double beat = beat_at_bbt_locked (future_map, bbt);
 
        if (solve_map_pulse (future_map, tempo_copy, pulse_at_beat_locked (future_map, beat))) {
                ret.first = tempo_copy->pulse();
@@ -2352,7 +2433,7 @@ TempoMap::predict_tempo_position (TempoSection* section, const BBT_Time& bbt)
 }
 
 void
-TempoMap::gui_move_tempo (TempoSection* ts, const pair<double, framepos_t>& pulse)
+TempoMap::gui_move_tempo (TempoSection* ts, const framepos_t& frame)
 {
        Metrics future_map;
 
@@ -2360,8 +2441,9 @@ TempoMap::gui_move_tempo (TempoSection* ts, const pair<double, framepos_t>& puls
                {
                        Glib::Threads::RWLock::WriterLock lm (lock);
                        TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
-                       if (solve_map_pulse (future_map, tempo_copy, pulse.first)) {
-                               solve_map_pulse (_metrics, ts, pulse.first);
+                       const double pulse = pulse_at_frame_locked (future_map, frame);
+                       if (solve_map_pulse (future_map, tempo_copy, pulse)) {
+                               solve_map_pulse (_metrics, ts, pulse);
                                recompute_meters (_metrics);
                        }
                }
@@ -2371,8 +2453,8 @@ TempoMap::gui_move_tempo (TempoSection* ts, const pair<double, framepos_t>& puls
                {
                        Glib::Threads::RWLock::WriterLock lm (lock);
                        TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
-                       if (solve_map_frame (future_map, tempo_copy, pulse.second)) {
-                               solve_map_frame (_metrics, ts, pulse.second);
+                       if (solve_map_frame (future_map, tempo_copy, frame)) {
+                               solve_map_frame (_metrics, ts, frame);
                                recompute_meters (_metrics);
                        }
                }
@@ -2409,7 +2491,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const framepos_t& frame)
                        MeterSection* copy = copy_metrics_and_point (_metrics, future_map, ms);
 
                        const double beat = beat_at_frame_locked (_metrics, frame);
-                       const Timecode::BBT_Time bbt = beats_to_bbt_locked (_metrics, beat);
+                       const Timecode::BBT_Time bbt = bbt_at_beat_locked (_metrics, beat);
 
                        if (solve_map_bbt (future_map, copy, bbt)) {
                                solve_map_bbt (_metrics, ms, bbt);
@@ -2699,131 +2781,13 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir)
        return ret_frame;
 }
 
-void
-TempoMap::round_bbt (BBT_Time& when, const int32_t& sub_num, RoundMode dir)
-{
-       if (sub_num == -1) {
-               if (dir > 0) {
-                       ++when.bars;
-                       when.beats = 1;
-                       when.ticks = 0;
-               } else if (dir < 0) {
-                       when.beats = 1;
-                       when.ticks = 0;
-               } else {
-                       const double bpb = meter_section_at_beat (bbt_to_beats_locked (_metrics, when)).divisions_per_bar();
-                       if ((double) when.beats > bpb / 2.0) {
-                               ++when.bars;
-                       }
-                       when.beats = 1;
-                       when.ticks = 0;
-               }
-
-               return;
-
-       } else if (sub_num == 0) {
-               const double bpb = meter_section_at_beat (bbt_to_beats_locked (_metrics, when)).divisions_per_bar();
-               if ((double) when.ticks > BBT_Time::ticks_per_beat / 2.0) {
-                       ++when.beats;
-                       while ((double) when.beats > bpb) {
-                               ++when.bars;
-                               when.beats -= (uint32_t) floor (bpb);
-                       }
-               }
-               when.ticks = 0;
-
-               return;
-       }
-
-       const uint32_t ticks_one_subdivisions_worth = BBT_Time::ticks_per_beat / sub_num;
-
-       if (dir > 0) {
-               /* round to next (or same iff dir == RoundUpMaybe) */
-
-               uint32_t mod = when.ticks % ticks_one_subdivisions_worth;
-
-               if (mod == 0 && dir == RoundUpMaybe) {
-                       /* right on the subdivision, which is fine, so do nothing */
-
-               } else if (mod == 0) {
-                       /* right on the subdivision, so the difference is just the subdivision ticks */
-                       when.ticks += ticks_one_subdivisions_worth;
-
-               } else {
-                       /* not on subdivision, compute distance to next subdivision */
-
-                       when.ticks += ticks_one_subdivisions_worth - mod;
-               }
-
-               if (when.ticks >= BBT_Time::ticks_per_beat) {
-                       ++when.beats;
-                       const double bpb = meter_section_at_beat (bbt_to_beats_locked (_metrics, when)).divisions_per_bar();
-                       if ((double) when.beats > bpb) {
-                               ++when.bars;
-                               when.beats = 1;
-                       }
-                       when.ticks -= BBT_Time::ticks_per_beat;
-               }
-
-       } else if (dir < 0) {
-               /* round to previous (or same iff dir == RoundDownMaybe) */
-
-               uint32_t difference = when.ticks % ticks_one_subdivisions_worth;
-
-               if (difference == 0 && dir == RoundDownAlways) {
-                       /* right on the subdivision, but force-rounding down,
-                          so the difference is just the subdivision ticks */
-                       difference = ticks_one_subdivisions_worth;
-               }
-
-               if (when.ticks < difference) {
-                       --when.beats;
-                       const double bpb = meter_section_at_beat (bbt_to_beats_locked (_metrics, when)).divisions_per_bar();
-                       if ((double) when.beats < bpb) {
-                               --when.bars;
-                               //when.beats = 1;
-                       }
-                       when.ticks = BBT_Time::ticks_per_beat - when.ticks;
-               } else {
-                       when.ticks -= difference;
-               }
-
-       } else {
-               /* round to nearest */  double rem;
-               if ((rem = fmod ((double) when.ticks, (double) ticks_one_subdivisions_worth)) > (ticks_one_subdivisions_worth / 2.0)) {
-                       /* closer to the next subdivision, so shift forward */
-
-                       when.ticks = when.ticks + (ticks_one_subdivisions_worth - rem);
-
-                       if (when.ticks > Timecode::BBT_Time::ticks_per_beat) {
-                               ++when.beats;
-                               when.ticks -= Timecode::BBT_Time::ticks_per_beat;
-                       }
-
-               } else if (rem > 0) {
-                       /* closer to previous subdivision, so shift backward */
-
-                       if (rem > when.ticks) {
-                               if (when.beats == 0) {
-                                       /* can't go backwards past zero, so ... */
-                               }
-                               /* step back to previous beat */
-                               --when.beats;
-                               when.ticks = Timecode::BBT_Time::ticks_per_beat - rem;
-                       } else {
-                               when.ticks = when.ticks - rem;
-                       }
-               }
-       }
-}
-
 framepos_t
 TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
 
        const double beat_at_framepos = beat_at_frame_locked (_metrics, frame);
-       BBT_Time bbt (beats_to_bbt_locked (_metrics, beat_at_framepos));
+       BBT_Time bbt (bbt_at_beat_locked (_metrics, beat_at_framepos));
 
        switch (type) {
        case Bar:
@@ -2886,8 +2850,8 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
                pos = frame_at_beat_locked (_metrics, cnt);
                const TempoSection tempo = tempo_section_at_locked (_metrics, pos);
                const MeterSection meter = meter_section_at_locked (_metrics, pos);
-               const BBT_Time bbt = beats_to_bbt (cnt);
-               points.push_back (BBTPoint (meter, tempo_at_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func()));
+               const BBT_Time bbt = bbt_at_beat_locked (_metrics, cnt);
+               points.push_back (BBTPoint (meter, tempo_at_frame_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func()));
                ++cnt;
        }
 }
@@ -2998,42 +2962,6 @@ TempoMap::frames_per_beat_at (const framepos_t& frame, const framecnt_t& sr) con
        return ts_at->frames_per_beat (_frame_rate);
 }
 
-const Tempo
-TempoMap::tempo_at_locked (const Metrics& metrics, const framepos_t& frame) const
-{
-       TempoSection* prev_t = 0;
-
-       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->frame() > frame) {
-                               /* t is the section past frame */
-                               const double ret_bpm = prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type();
-                               const Tempo ret_tempo (ret_bpm, prev_t->note_type());
-                               return ret_tempo;
-                       }
-                       prev_t = t;
-               }
-       }
-
-       const double ret = prev_t->beats_per_minute();
-       const Tempo ret_tempo (ret, prev_t->note_type ());
-
-       return ret_tempo;
-}
-
-const Tempo
-TempoMap::tempo_at (const framepos_t& frame) const
-{
-       Glib::Threads::RWLock::ReaderLock lm (lock);
-       return tempo_at_locked (_metrics, frame);
-}
-
 const MeterSection&
 TempoMap::meter_section_at_locked (const Metrics& metrics, framepos_t frame) const
 {
@@ -3095,7 +3023,7 @@ TempoMap::meter_section_at_beat (double beat) const
 }
 
 const Meter&
-TempoMap::meter_at (framepos_t frame) const
+TempoMap::meter_at_frame (framepos_t frame) const
 {
        TempoMetric m (metric_at (frame));
        return m.meter();
@@ -3397,7 +3325,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                                                        continue;
                                                }
                                                const double beat = beat_at_pulse_locked (_metrics, t->pulse());
-                                               pair<double, BBT_Time> start = make_pair (beat, beats_to_bbt_locked (_metrics, beat));
+                                               pair<double, BBT_Time> start = make_pair (beat, bbt_at_beat_locked (_metrics, beat));
                                                ms->set_beat (start);
                                                ms->set_pulse (t->pulse());
                                        }
@@ -3542,7 +3470,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
 
-       BBT_Time pos_bbt = beats_to_bbt_locked (_metrics, beat_at_frame_locked (_metrics, pos));
+       BBT_Time pos_bbt = bbt_at_beat_locked (_metrics, beat_at_frame_locked (_metrics, pos));
        pos_bbt.ticks += op.ticks;
        if (pos_bbt.ticks >= BBT_Time::ticks_per_beat) {
                ++pos_bbt.beats;
@@ -3550,10 +3478,10 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
        }
        pos_bbt.beats += op.beats;
        /* the meter in effect will start on the bar */
-       double divisions_per_bar = meter_section_at_beat (bbt_to_beats_locked (_metrics, BBT_Time (pos_bbt.bars + op.bars, 1, 0))).divisions_per_bar();
+       double divisions_per_bar = meter_section_at_beat (beat_at_bbt_locked (_metrics, BBT_Time (pos_bbt.bars + op.bars, 1, 0))).divisions_per_bar();
        while (pos_bbt.beats >= divisions_per_bar + 1) {
                ++pos_bbt.bars;
-               divisions_per_bar = meter_section_at_beat (bbt_to_beats_locked (_metrics, BBT_Time (pos_bbt.bars + op.bars, 1, 0))).divisions_per_bar();
+               divisions_per_bar = meter_section_at_beat (beat_at_bbt_locked (_metrics, BBT_Time (pos_bbt.bars + op.bars, 1, 0))).divisions_per_bar();
                pos_bbt.beats -= divisions_per_bar;
        }
        pos_bbt.bars += op.bars;