Tempo ramps - check for impossible locations tempo dialog bbt entry. reorganise code.
authornick_m <mainsbridge@gmail.com>
Sun, 6 Mar 2016 19:35:32 +0000 (06:35 +1100)
committernick_m <mainsbridge@gmail.com>
Fri, 27 May 2016 13:38:11 +0000 (23:38 +1000)
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/tempo_dialog.cc
gtk2_ardour/tempo_dialog.h
libs/ardour/ardour/tempo.h
libs/ardour/tempo.cc
libs/ardour/test/tempo_test.cc

index f3cebf9a9c0f051985589d2ddff937b22928ca5e..ea8af8cfd641e2721af14a92474138c1b148d24e 100644 (file)
@@ -3183,9 +3183,9 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
        }
 
        framepos_t const pf = adjusted_current_frame (event);
-       double const baf = _editor->session()->tempo_map().beat_at_frame (pf);
        _marker->set_position (pf);
        if (_marker->meter().position_lock_style() == MusicTime) {
+               double const baf = _editor->session()->tempo_map().beat_at_frame (pf);
                _editor->session()->tempo_map().gui_move_meter (_real_section, _marker->meter(), baf);
        } else {
                _editor->session()->tempo_map().gui_move_meter (_real_section, _marker->meter(), pf);
index bd5ff205e908e71373fc8eb304f5dcbec1708a68..56ee463f9f8b82aadb59a2f3936df554da363ab2 100644 (file)
@@ -378,7 +378,7 @@ Editor::edit_tempo_section (TempoSection* section)
        if (tempo_dialog.get_lock_style() == MusicTime) {
                _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), beat, tempo_dialog.get_tempo_type());
        } else {
-               framepos_t const f = _session->tempo_map().compute_new_tempo_frame (section, Tempo (bpm, nt), beat);
+               framepos_t const f = _session->tempo_map().predict_tempo_frame (section, Tempo (bpm, nt), when);
                _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), f, tempo_dialog.get_tempo_type());
        }
        XMLNode &after = _session->tempo_map().get_state();
index 5d06f5ca3c118c1ea4ee6d39bf8a5180d4dc8571..eef19e22a5f686a8709497634293e6d628008ee3 100644 (file)
@@ -36,6 +36,8 @@ using namespace PBD;
 
 TempoDialog::TempoDialog (TempoMap& map, framepos_t frame, const string&)
        : ArdourDialog (_("New Tempo"))
+       , _map (&map)
+       , _section (0)
        , bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0)
        , bpm_spinner (bpm_adjustment)
        , when_bar_label (_("bar:"), ALIGN_LEFT, ALIGN_CENTER)
@@ -52,6 +54,8 @@ TempoDialog::TempoDialog (TempoMap& map, framepos_t frame, const string&)
 
 TempoDialog::TempoDialog (TempoMap& map, TempoSection& section, const string&)
        : ArdourDialog (_("Edit Tempo"))
+       , _map (&map)
+       , _section (&section)
        , bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0)
        , bpm_spinner (bpm_adjustment)
        , when_bar_label (_("bar:"), ALIGN_LEFT, ALIGN_CENTER)
@@ -269,7 +273,15 @@ TempoDialog::bpm_button_release (GdkEventButton*)
 bool
 TempoDialog::entry_key_release (GdkEventKey*)
 {
-       set_response_sensitive (RESPONSE_ACCEPT, is_user_input_valid());
+       Timecode::BBT_Time bbt;
+       get_bbt_time (bbt);
+
+       if (_section && is_user_input_valid()) {
+               set_response_sensitive (RESPONSE_ACCEPT, _map->bbt_valid (_section, Tempo (get_bpm(), get_note_type()), bbt));
+       } else {
+               set_response_sensitive (RESPONSE_ACCEPT, is_user_input_valid());
+       }
+
        return false;
 }
 
index 706085c688afbb5a6edabb11dad3c0308628bb33..38c14e8b273d2ed30f9c98f6c620eb42ea928fa8 100644 (file)
@@ -75,6 +75,9 @@ private:
        double last_t;
        gint64 first_t;
 
+       ARDOUR::TempoMap* _map;
+       ARDOUR::TempoSection* _section;
+
        Gtk::ComboBoxText pulse_selector;
        Gtk::Adjustment   bpm_adjustment;
        Gtk::SpinButton   bpm_spinner;
@@ -86,8 +89,6 @@ private:
        Gtk::Button  tap_tempo_button;
        Gtk::ComboBoxText tempo_type;
        Gtk::ComboBoxText lock_style;
-
-
 };
 
 class MeterDialog : public ArdourDialog
index ab752916f4b15d679ef9fcdf0d01483f58590aaa..5fb9275df8af2a370c2abe18cc077de41c3b2da1 100644 (file)
@@ -194,8 +194,8 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
        double tick_at_frame (framepos_t frame, framecnt_t frame_rate) const;
        framepos_t frame_at_tick (double tick, framecnt_t frame_rate) const;
 
-       void set_c_func_from_tempo_and_beat (double end_bpm, double end_beat, framecnt_t frame_rate);
-       double compute_c_func (double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const;
+       double compute_c_func_beat (double end_bpm, double end_beat, framecnt_t frame_rate);
+       double compute_c_func_frame (double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const;
 
        double get_c_func () const { return _c_func; }
        void set_c_func (double c_func) { _c_func = c_func; }
@@ -315,7 +315,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 
        template<class T> void apply_with_metrics (T& obj, void (T::*method)(const Metrics&)) {
                Glib::Threads::RWLock::ReaderLock lm (lock);
-               (obj.*method)(metrics);
+               (obj.*method)(_metrics);
        }
 
        void get_grid (std::vector<BBTPoint>&,
@@ -377,7 +377,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        void remove_tempo (const TempoSection&, bool send_signal);
        void remove_meter (const MeterSection&, bool send_signal);
 
-       framepos_t compute_new_tempo_frame (TempoSection* section, const Tempo& bpm, const double& beat);
+       framepos_t predict_tempo_frame (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt);
 
        void replace_tempo (const TempoSection&, const Tempo&, const double& where, TempoSection::Type type);
        void replace_tempo (const TempoSection&, const Tempo&, const framepos_t& frame, TempoSection::Type type);
@@ -386,6 +386,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        void gui_move_meter (MeterSection*, const Meter& mt, const framepos_t& frame);
        void gui_move_meter (MeterSection*, const Meter& mt, const double& beat);
 
+       bool bbt_valid (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt);
 
        void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where);
        void replace_meter (const MeterSection&, const Meter&, const framepos_t& frame);
@@ -409,7 +410,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
         */
        TempoMetric metric_at (framepos_t, Metrics::const_iterator* last=NULL) const;
 
-       Metrics::const_iterator metrics_end() { return metrics.end(); }
+       Metrics::const_iterator metrics_end() { return _metrics.end(); }
 
        void change_existing_tempo_at (framepos_t, double bpm, double note_type);
        void change_initial_tempo (double bpm, double note_type);
@@ -422,24 +423,24 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 
        framecnt_t frame_rate () const { return _frame_rate; }
 
-       PBD::Signal0<void> MetricPositionChanged;
-
        double bbt_to_beats (Timecode::BBT_Time bbt);
        Timecode::BBT_Time beats_to_bbt (double beats);
 
+       PBD::Signal0<void> MetricPositionChanged;
+
 private:
-       double bbt_to_beats_locked (Timecode::BBT_Time bbt);
-       Timecode::BBT_Time beats_to_bbt_locked (double beats);
-       double beat_at_frame_locked (framecnt_t frame) const;
-       framecnt_t frame_at_beat_locked (double beat) const;
-       double tick_at_frame_locked (framecnt_t frame) const;
-       framecnt_t frame_at_tick_locked (double tick) const;
-       framepos_t frame_time_locked (const Timecode::BBT_Time&);
-
-       Metrics get_new_order (TempoSection* section, const Tempo& bpm, const framepos_t& frame);
-       Metrics get_new_order (TempoSection* section, const Tempo& bpm, const double& beat);
-       Metrics get_new_order (MeterSection* section, const Meter& mt, const framepos_t& frame);
-       Metrics get_new_order (MeterSection* section, const Meter& mt, const double& beat);
+       double bbt_to_beats_locked (Metrics& metrics, Timecode::BBT_Time bbt);
+       Timecode::BBT_Time beats_to_bbt_locked (Metrics& metrics, double beats);
+       double beat_at_frame_locked (Metrics& metrics, framecnt_t frame) const;
+       framecnt_t frame_at_beat_locked (Metrics& metrics, double beat) const;
+       double tick_at_frame_locked (const Metrics& metrics, framecnt_t frame) const;
+       framecnt_t frame_at_tick_locked (const Metrics& metrics, double tick) const;
+       framepos_t frame_time_locked (Metrics& metrics, const Timecode::BBT_Time&);
+
+       void get_new_order (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame);
+       void get_new_order (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& beat);
+       void get_new_order (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame);
+       void get_new_order (Metrics& metrics, MeterSection* section, const Meter& mt, const double& beat);
 
        friend class ::BBTTest;
        friend class ::FrameposPlusBeatsTest;
@@ -448,13 +449,13 @@ private:
        static Tempo    _default_tempo;
        static Meter    _default_meter;
 
-       Metrics                       metrics;
+       Metrics                       _metrics;
        framecnt_t                    _frame_rate;
        mutable Glib::Threads::RWLock lock;
 
-       void recompute_tempos ();
-       void recompute_meters ();
-       void recompute_map (bool reassign_tempo_bbt, framepos_t end = -1);
+       void recompute_tempos (Metrics& metrics);
+       void recompute_meters (Metrics& metrics);
+       void recompute_map (Metrics& metrics, framepos_t end = -1);
 
        framepos_t round_to_type (framepos_t fr, RoundMode dir, BBTPointType);
 
@@ -474,6 +475,7 @@ private:
        bool remove_tempo_locked (const TempoSection&);
        bool remove_meter_locked (const MeterSection&);
 
+       TempoSection* copy_metrics_and_point (Metrics& copy, TempoSection* section);
 };
 
 }; /* namespace ARDOUR */
index abaadc1f0aa29bbb12a1c995298d627bed4574b5..0ea2a4385731687de9c7c49bc5c08ac4cd12148b 100644 (file)
@@ -374,17 +374,17 @@ https://www.zhdk.ch/fileadmin/data_subsites/data_icst/Downloads/Timegrid/ICST_Te
 
 */
 
-/* set this ramp's function constant using the end tempo and duration (beats into global start) of some later tempo section*/
-void
-TempoSection::set_c_func_from_tempo_and_beat (double end_bpm, double end_beat, framecnt_t frame_rate)
+/* compute this ramp's function constant using the end tempo and duration (beats into global start) of some later tempo section*/
+double
+TempoSection::compute_c_func_beat (double end_bpm, double end_beat, framecnt_t frame_rate)
 {
        double const log_tempo_ratio = log ((end_bpm * BBT_Time::ticks_per_beat) / ticks_per_minute());
-       _c_func = ticks_per_minute() *  (exp (log_tempo_ratio) - 1) / ((end_beat - beat()) * BBT_Time::ticks_per_beat);
+       return ticks_per_minute() *  (exp (log_tempo_ratio) - 1) / ((end_beat - beat()) * BBT_Time::ticks_per_beat);
 }
 
 /* compute the function constant from some later tempo section, given tempo (beats/min.) and distance (in frames) from session origin */
 double
-TempoSection::compute_c_func (double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const
+TempoSection::compute_c_func_frame (double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const
 {
        return c_func (end_bpm * BBT_Time::ticks_per_beat, frame_to_minute (end_frame - frame(), frame_rate));
 }
@@ -657,8 +657,8 @@ TempoMap::TempoMap (framecnt_t fr)
 
        /* note: frame time is correct (zero) for both of these */
 
-       metrics.push_back (t);
-       metrics.push_back (m);
+       _metrics.push_back (t);
+       _metrics.push_back (m);
 
 }
 
@@ -675,7 +675,7 @@ TempoMap::remove_tempo (const TempoSection& tempo, bool complete_operation)
                Glib::Threads::RWLock::WriterLock lm (lock);
                if ((removed = remove_tempo_locked (tempo))) {
                        if (complete_operation) {
-                               recompute_map (true);
+                               recompute_map (_metrics);
                        }
                }
        }
@@ -690,11 +690,11 @@ TempoMap::remove_tempo_locked (const TempoSection& tempo)
 {
        Metrics::iterator i;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                if (dynamic_cast<TempoSection*> (*i) != 0) {
                        if (tempo.frame() == (*i)->frame()) {
                                if ((*i)->movable()) {
-                                       metrics.erase (i);
+                                       _metrics.erase (i);
                                        return true;
                                }
                        }
@@ -713,7 +713,7 @@ TempoMap::remove_meter (const MeterSection& tempo, bool complete_operation)
                Glib::Threads::RWLock::WriterLock lm (lock);
                if ((removed = remove_meter_locked (tempo))) {
                        if (complete_operation) {
-                               recompute_map (true);
+                               recompute_map (_metrics);
                        }
                }
        }
@@ -728,11 +728,11 @@ TempoMap::remove_meter_locked (const MeterSection& tempo)
 {
        Metrics::iterator i;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                if (dynamic_cast<MeterSection*> (*i) != 0) {
                        if (tempo.frame() == (*i)->frame()) {
                                if ((*i)->movable()) {
-                                       metrics.erase (i);
+                                       _metrics.erase (i);
                                        return true;
                                }
                        }
@@ -759,7 +759,7 @@ TempoMap::do_insert (MetricSection* section)
                        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 (corrected.second);
+                       corrected.first = bbt_to_beats_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_beat (corrected);
@@ -773,7 +773,7 @@ TempoMap::do_insert (MetricSection* section)
           guaranteed that there is only one such match.
        */
 
-       for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
 
                TempoSection* const tempo = dynamic_cast<TempoSection*> (*i);
                TempoSection* const insert_tempo = dynamic_cast<TempoSection*> (section);
@@ -794,7 +794,7 @@ TempoMap::do_insert (MetricSection* section)
                                        *(dynamic_cast<Tempo*>(*i)) = *(dynamic_cast<Tempo*>(insert_tempo));
                                        need_add = false;
                                } else {
-                                       metrics.erase (i);
+                                       _metrics.erase (i);
                                }
                                break;
                        }
@@ -818,7 +818,7 @@ TempoMap::do_insert (MetricSection* section)
                                        *(dynamic_cast<Meter*>(*i)) = *(dynamic_cast<Meter*>(insert_meter));
                                        need_add = false;
                                } else {
-                                       metrics.erase (i);
+                                       _metrics.erase (i);
 
                                }
 
@@ -839,7 +839,7 @@ TempoMap::do_insert (MetricSection* section)
 
                Metrics::iterator i;
                if (insert_meter) {
-                       for (i = metrics.begin(); i != metrics.end(); ++i) {
+                       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                                MeterSection* const meter = dynamic_cast<MeterSection*> (*i);
 
                                if (meter) {
@@ -850,7 +850,7 @@ TempoMap::do_insert (MetricSection* section)
                                }
                        }
                } else if (insert_tempo) {
-                       for (i = metrics.begin(); i != metrics.end(); ++i) {
+                       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                                TempoSection* const tempo = dynamic_cast<TempoSection*> (*i);
 
                                if (tempo) {
@@ -862,7 +862,7 @@ TempoMap::do_insert (MetricSection* section)
                        }
                }
 
-               metrics.insert (i, section);
+               _metrics.insert (i, section);
                //dump (std::cerr);
        }
 }
@@ -881,7 +881,7 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const doubl
                        {
                                /* cannot move the first tempo section */
                                *static_cast<Tempo*>(&first) = tempo;
-                               recompute_map (false);
+                               recompute_map (_metrics);
                        }
                }
        }
@@ -895,7 +895,7 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
                TempoSection& first (first_tempo());
-               if (ts.beat() != first.beat()) {
+               if (ts.frame() != first.frame()) {
                        remove_tempo_locked (ts);
                        add_tempo_locked (tempo, frame, true, type);
                } else {
@@ -903,266 +903,13 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
                        {
                                /* cannot move the first tempo section */
                                *static_cast<Tempo*>(&first) = tempo;
-                               recompute_map (false);
+                               recompute_map (_metrics);
                        }
                }
        }
-
        PropertyChanged (PropertyChange ());
 }
 
-Metrics
-TempoMap::get_new_order (TempoSection* section, const Tempo& bpm, const framepos_t& frame)
-{
-       Metrics imaginary (metrics);
-       TempoSection* prev_ts = 0;
-
-       /*set frame and sort */
-       section->set_frame (frame);
-       MetricSectionFrameSorter fcmp;
-       imaginary.sort (fcmp);
-
-       /* recompute tempos */
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               TempoSection* t;
-               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
-                       if (prev_ts) {
-                               if (t == section) {
-                                       /* we have already set the frame - set the beat */
-                                       prev_ts->set_c_func (prev_ts->compute_c_func (bpm.beats_per_minute(), frame, _frame_rate));
-                                       section->set_beat (prev_ts->beat_at_tempo (bpm.beats_per_minute(), frame, _frame_rate));
-                                       prev_ts = t;
-                                       continue;
-                               }
-                               if (t->position_lock_style() == MusicTime) {
-                                       prev_ts->set_c_func_from_tempo_and_beat (t->beats_per_minute(), t->beat(), _frame_rate);
-                                       t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
-                               } else {
-                                       prev_ts->set_c_func (prev_ts->compute_c_func (t->beats_per_minute(), t->frame(), _frame_rate));
-                                       t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
-                               }
-                       }
-                       prev_ts = t;
-               }
-       }
-       MetricSectionSorter cmp;
-       imaginary.sort (cmp);
-/*
-       prev_ts = 0;
-       std::cerr << "dumping imaginary order ------" << std::endl;;
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
-                       if (prev_ts) {
-
-                               std::cerr << t->beats_per_minute() << " | " << t->beat() << " | " << t->frame() << std::endl;
-                               std::cerr << prev_ts->beats_per_minute() << " | " << prev_ts->beat() << " | " << prev_ts->frame() << std::endl;
-                               std::cerr << t->beats_per_minute() << " | " << prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame, _frame_rate) << " | " << prev_ts->tempo_at_beat(t->beat()) << " | " << prev_ts->frame_at_tempo(t->beats_per_minute(), t->beat(), _frame_rate) << std::endl;
-                               std::cerr << "   ------" << std::endl;;
-
-                       }
-                       prev_ts = t;
-               }
-       }
-       std::cerr << "end dump ------";
-*/
-       return imaginary;
-}
-
-Metrics
-TempoMap::get_new_order (TempoSection* section, const Tempo& bpm, const double& beat)
-{
-       Metrics imaginary (metrics);
-       TempoSection* prev_ts = 0;
-
-       /*set beat and sort */
-       section->set_beat (beat);
-       MetricSectionSorter cmp;
-       imaginary.sort (cmp);
-
-       /* recompute tempo positions */
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               TempoSection* t;
-               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
-                       if (prev_ts) {
-                               if (t == section) {
-                                       /* we've already set the beat - set the frame */
-                                       prev_ts->set_c_func_from_tempo_and_beat (bpm.beats_per_minute(), beat, _frame_rate);
-                                       section->set_frame (prev_ts->frame_at_tempo (bpm.beats_per_minute(), beat, _frame_rate));
-                                       prev_ts = t;
-                                       continue;
-                               }
-                               if (t->position_lock_style() == MusicTime) {
-                                       prev_ts->set_c_func_from_tempo_and_beat (t->beats_per_minute(), t->beat(), _frame_rate);
-                                       t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
-                               } else {
-                                       prev_ts->set_c_func (prev_ts->compute_c_func (t->beats_per_minute(), t->frame(), _frame_rate));
-                                       t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
-                               }
-                       }
-                       prev_ts = t;
-               }
-       }
-
-       MetricSectionFrameSorter fcmp;
-       imaginary.sort (fcmp);
-/*
-       prev_ts = 0;
-       std::cerr << "dumping imaginary order ------" << std::endl;;
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
-                       if (prev_ts) {
-
-                               std::cerr << t->beats_per_minute() << " | " << t->beat() << " | " << t->frame() << std::endl;
-                               std::cerr << "prev : " << prev_ts->beats_per_minute() << " | " << prev_ts->beat() << " | " << prev_ts->frame() << std::endl;
-                               std::cerr << "calculated : " << t->beats_per_minute() << " | " << prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate) << " | " << prev_ts->tempo_at_beat(t->beat()) << " | " << prev_ts->frame_at_tempo(t->beats_per_minute(), t->frame(), _frame_rate) << std::endl;
-                               std::cerr << "   ------" << std::endl;;
-
-                       }
-                       prev_ts = t;
-               }
-       }
-       std::cerr << "end dump ------";
-*/
-       return imaginary;
-}
-
-Metrics
-TempoMap::get_new_order(MeterSection* section, const Meter& mt, const double& beat)
-{
-       Metrics imaginary (metrics);
-       MeterSection* prev_ms = 0;
-
-       pair<double, BBT_Time> b_bbt = make_pair (beat, BBT_Time (1, 1, 0));
-       section->set_beat (b_bbt);
-       MetricSectionSorter cmp;
-       imaginary.sort (cmp);
-
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               MeterSection* m;
-               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
-                       if (prev_ms) {
-                               if (m->beat() > beat){
-                                       section->set_frame (frame_at_beat_locked (beat));
-                                       prev_ms = section;
-                                       continue;
-                               }
-                               if (m->position_lock_style() == MusicTime) {
-                                       m->set_frame (frame_at_beat_locked (m->beat()));
-                               } else {
-                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (m->frame()), BBT_Time (1, 1, 0));
-                                       m->set_beat (b_bbt);
-                               }
-                       }
-                       prev_ms = m;
-               }
-       }
-
-       MetricSectionFrameSorter fcmp;
-       imaginary.sort (fcmp);
-
-       return imaginary;
-}
-
-Metrics
-TempoMap::get_new_order(MeterSection* section, const Meter& mt, const framepos_t& frame)
-{
-       Metrics imaginary (metrics);
-       MeterSection* prev_ms = 0;
-
-       section->set_frame (frame);
-       MetricSectionFrameSorter fcmp;
-       imaginary.sort (fcmp);
-
-       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
-               MeterSection* m;
-               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
-                       if (prev_ms) {
-                               if (m->frame() > frame){
-                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (frame), BBT_Time (1, 1, 0));
-                                       section->set_beat (b_bbt);
-                                       prev_ms = section;
-                                       continue;
-                               }
-                               if (m->position_lock_style() == MusicTime) {
-                                       m->set_frame (frame_at_beat_locked (m->beat()));
-                               } else {
-                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (m->frame()), BBT_Time (1, 1, 0));
-                                       m->set_beat (b_bbt);
-                               }
-                       }
-                       prev_ms = m;
-               }
-       }
-
-       MetricSectionSorter cmp;
-       imaginary.sort (cmp);
-
-       return imaginary;
-}
-
-/**
-* This is for a gui that needs to know the frame of an audio-locked tempo section if it were to be placed at some beat.
-* It actually reorders and partially recomputes tha ramps, so calling this commits you to replacing the section immediately.
-* It will not emit a signal as you probably want to replace the tempo or do somethig else before that happens.
-* @param section - the section you want to alter
-* @param bpm - the new Tempo
-* @param beat - the beat where the altered tempo will fall
-* @return returns - the position in frames where the new tempo section will lie.
-*/
-framepos_t
-TempoMap::compute_new_tempo_frame (TempoSection* section, const Tempo& bpm, const double& beat)
-{
-       Glib::Threads::RWLock::WriterLock lm (lock);
-       Metrics new_order = get_new_order (section, bpm, beat);
-
-       return section->frame();
-}
-
-void
-TempoMap::gui_move_tempo (TempoSection* ts,  const Tempo& bpm, const framepos_t& frame)
-{
-       {
-               Glib::Threads::RWLock::WriterLock lm (lock);
-               Metrics new_order = get_new_order (ts, bpm, frame);
-
-               metrics.clear();
-               metrics = new_order;
-               recompute_map (false);
-       }
-
-       MetricPositionChanged (); // Emit Signal
-}
-
-void
-TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t&  frame)
-{
-       {
-               Glib::Threads::RWLock::WriterLock lm (lock);
-               Metrics new_order = get_new_order (ms, mt, frame);
-
-               metrics.clear();
-               metrics = new_order;
-               recompute_meters ();
-       }
-
-       MetricPositionChanged (); // Emit Signal
-}
-
-void
-TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double&  beat)
-{
-       {
-               Glib::Threads::RWLock::WriterLock lm (lock);
-               Metrics new_order = get_new_order (ms, mt, beat);
-
-               metrics.clear();
-               metrics = new_order;
-               recompute_meters ();
-       }
-
-       MetricPositionChanged (); // Emit Signal
-}
-
 void
 TempoMap::add_tempo (const Tempo& tempo, double where, ARDOUR::TempoSection::Type type)
 {
@@ -1194,7 +941,7 @@ TempoMap::add_tempo_locked (const Tempo& tempo, double where, bool recompute, AR
        do_insert (ts);
 
        if (recompute) {
-               recompute_map (false);
+               recompute_map (_metrics);
        }
 }
 
@@ -1206,7 +953,7 @@ TempoMap::add_tempo_locked (const Tempo& tempo, framepos_t frame, bool recompute
        do_insert (ts);
 
        if (recompute) {
-               recompute_map (false);
+               recompute_map (_metrics);
        }
 }
 
@@ -1218,11 +965,11 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
                MeterSection& first (first_meter());
                if (ms.beat() != first.beat()) {
                        remove_meter_locked (ms);
-                       add_meter_locked (meter, bbt_to_beats_locked (where), where, true);
+                       add_meter_locked (meter, bbt_to_beats_locked (_metrics, where), where, true);
                } else {
                        /* cannot move the first meter section */
                        *static_cast<Meter*>(&first) = meter;
-                       recompute_map (true);
+                       recompute_map (_metrics);
                }
        }
 
@@ -1241,7 +988,7 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
                } else {
                        /* cannot move the first meter section */
                        *static_cast<Meter*>(&first) = meter;
-                       recompute_map (true);
+                       recompute_map (_metrics);
                }
        }
 
@@ -1306,7 +1053,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo
        do_insert (new MeterSection (beat, where, meter.divisions_per_bar(), meter.note_divisor()));
 
        if (recompute) {
-               recompute_map (true);
+               recompute_map (_metrics);
        }
 
 }
@@ -1319,23 +1066,149 @@ TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, bool recompute
        do_insert (new MeterSection (frame, meter.divisions_per_bar(), meter.note_divisor()));
 
        if (recompute) {
-               recompute_map (true);
+               recompute_map (_metrics);
        }
 
 }
 
+/**
+* This is for a gui that needs to know the frame of a tempo section if it were to be moved to some bbt time,
+* taking any possible reordering as a consequence of this into account.
+* @param section - the section to be altered
+* @param bpm - the new Tempo
+* @param bbt - the bbt where the altered tempo will fall
+* @return returns - the position in frames where the new tempo section will lie.
+*/
+framepos_t
+TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BBT_Time& bbt)
+{
+       Glib::Threads::RWLock::ReaderLock lm (lock);
+       Metrics future_map;
+       TempoSection* new_section = copy_metrics_and_point (future_map, section);
+       double const beat = bbt_to_beats_locked (future_map, bbt);
+       get_new_order (future_map, new_section, bpm, beat);
+
+       return new_section->frame();
+}
+
+void
+TempoMap::gui_move_tempo (TempoSection* ts,  const Tempo& bpm, const framepos_t& frame)
+{
+       {
+               Glib::Threads::RWLock::WriterLock lm (lock);
+               get_new_order (_metrics, ts, bpm, frame);
+       }
+
+       MetricPositionChanged (); // Emit Signal
+}
+
+void
+TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t&  frame)
+{
+       {
+               Glib::Threads::RWLock::WriterLock lm (lock);
+               get_new_order (_metrics, ms, mt, frame);
+       }
+
+       MetricPositionChanged (); // Emit Signal
+}
+
+void
+TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double&  beat)
+{
+       {
+               Glib::Threads::RWLock::WriterLock lm (lock);
+               get_new_order (_metrics, ms, mt, beat);
+       }
+
+       MetricPositionChanged (); // Emit Signal
+}
+
+TempoSection*
+TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
+{
+       TempoSection* t;
+       TempoSection* ret = 0;
+       MeterSection* m;
+
+       for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (t == section) {
+                               if (t->position_lock_style() == MusicTime) {
+                                       ret = new TempoSection (t->beat(), t->beats_per_minute(), t->note_type(), t->type());
+                               } else {
+                                       ret = new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type());
+                               }
+                               copy.push_back (ret);
+                               continue;
+                       }
+                       if (t->position_lock_style() == MusicTime) {
+                               copy.push_back (new TempoSection (t->beat(), t->beats_per_minute(), t->note_type(), t->type()));
+                       } else {
+                               copy.push_back (new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type()));
+                       }
+               }
+               if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
+                       if (m->position_lock_style() == MusicTime) {
+                               copy.push_back (new MeterSection (m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor()));
+                       } else {
+                               copy.push_back (new MeterSection (m->frame(), m->bbt(), m->divisions_per_bar(), m->note_divisor()));
+
+                       }
+               }
+       }
+       recompute_map (copy);
+       return ret;
+}
+
+bool
+TempoMap::bbt_valid (TempoSection* ts,  const Tempo& bpm, const BBT_Time& bbt)
+{
+       Metrics copy;
+       TempoSection* new_section = 0;
+       bool ret = true;
+
+       {
+               Glib::Threads::RWLock::ReaderLock lm (lock);
+               new_section = copy_metrics_and_point (copy, ts);
+       }
+
+       double const beat = bbt_to_beats_locked (copy, bbt);
+       get_new_order (copy, new_section, bpm, beat);
+
+       /* invalid ordering means an impossible arrangement */
+       TempoSection* prev_ts = 0;
+       for (Metrics::const_iterator i = copy.begin(); i != copy.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+                               if (t->frame() < prev_ts->frame() || t->beat() < prev_ts->beat()) {
+                                       ret = false;
+                               }
+                       }
+                       prev_ts = t;
+               }
+       }
+       Metrics::const_iterator d = copy.begin();
+       while (d != copy.end()) {
+               delete (*d);
+               ++d;
+       }
+       return ret;
+}
+
 void
 TempoMap::change_initial_tempo (double beats_per_minute, double note_type)
 {
        Tempo newtempo (beats_per_minute, note_type);
        TempoSection* t;
 
-       for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
                        {
                                Glib::Threads::RWLock::WriterLock lm (lock);
                                *((Tempo*) t) = newtempo;
-                               recompute_map (false);
+                               recompute_map (_metrics);
                        }
                        PropertyChanged (PropertyChange ());
                        break;
@@ -1355,7 +1228,7 @@ TempoMap::change_existing_tempo_at (framepos_t where, double beats_per_minute, d
        /* find the TempoSection immediately preceding "where"
         */
 
-       for (first = 0, i = metrics.begin(), prev = 0; i != metrics.end(); ++i) {
+       for (first = 0, i = _metrics.begin(), prev = 0; i != _metrics.end(); ++i) {
 
                if ((*i)->frame() > where) {
                        break;
@@ -1386,7 +1259,7 @@ TempoMap::change_existing_tempo_at (framepos_t where, double beats_per_minute, d
                Glib::Threads::RWLock::WriterLock lm (lock);
                /* cannot move the first tempo section */
                *((Tempo*)prev) = newtempo;
-               recompute_map (false);
+               recompute_map (_metrics);
        }
 
        PropertyChanged (PropertyChange ());
@@ -1397,7 +1270,7 @@ TempoMap::first_meter () const
 {
        const MeterSection *m = 0;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((m = dynamic_cast<const MeterSection *> (*i)) != 0) {
                        return *m;
                }
@@ -1415,7 +1288,7 @@ TempoMap::first_meter ()
 
        /* CALLER MUST HOLD LOCK */
 
-       for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
                        return *m;
                }
@@ -1433,7 +1306,7 @@ TempoMap::first_tempo () const
 
        /* CALLER MUST HOLD LOCK */
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((t = dynamic_cast<const TempoSection *> (*i)) != 0) {
                        return *t;
                }
@@ -1449,7 +1322,7 @@ TempoMap::first_tempo ()
 {
        TempoSection *t = 0;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((t = dynamic_cast<TempoSection *> (*i)) != 0) {
                        return *t;
                }
@@ -1460,7 +1333,7 @@ TempoMap::first_tempo ()
        return *t;
 }
 void
-TempoMap::recompute_tempos ()
+TempoMap::recompute_tempos (Metrics& metrics)
 {
        TempoSection* prev_ts = 0;
 
@@ -1470,21 +1343,23 @@ TempoMap::recompute_tempos ()
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
                        if (prev_ts) {
                                if (t->position_lock_style() == AudioTime) {
-                                       if (prev_ts->type() == TempoSection::Ramp) {
-                                               prev_ts->set_c_func (prev_ts->compute_c_func (t->beats_per_minute(), t->frame(), _frame_rate));
-                                               t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               /* compute c from t */
+                                               prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate));
                                        } else {
-                                               prev_ts->set_c_func (0.0);
-                                               t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate));
                                        }
+                                       t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
+
                                } else {
-                                       if (prev_ts->type() == TempoSection::Ramp) {
-                                               prev_ts->set_c_func_from_tempo_and_beat (t->beats_per_minute(), t->beat(), _frame_rate);
-                                               t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate));
                                        } else {
-                                               prev_ts->set_c_func (0.0);
-                                               t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
+                                               /* compute c from t */
+                                               prev_ts->set_c_func(t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate));
                                        }
+                                       t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
+
                                }
                        }
                        prev_ts = t;
@@ -1494,7 +1369,7 @@ TempoMap::recompute_tempos ()
 
 /* tempos must be positioned correctly */
 void
-TempoMap::recompute_meters ()
+TempoMap::recompute_meters (Metrics& metrics)
 {
        MeterSection* meter = 0;
 
@@ -1505,18 +1380,18 @@ TempoMap::recompute_meters ()
                                pair<double, BBT_Time> pr;
                                BBT_Time const where (1, 1, 0);
 
-                               pr.first = beat_at_frame_locked (meter->frame());
+                               pr.first = beat_at_frame_locked (metrics, meter->frame());
                                pr.second = where;
                                meter->set_beat (pr);
                        } else {
-                               meter->set_frame (frame_at_tick_locked (meter->tick()));
+                               meter->set_frame (frame_at_tick_locked (metrics, meter->tick()));
                        }
                }
        }
 }
 
 void
-TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
+TempoMap::recompute_map (Metrics& metrics, framepos_t end)
 {
        /* CALLER MUST HOLD WRITE LOCK */
 
@@ -1537,8 +1412,8 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
                return;
        }
 
-       recompute_tempos();
-       recompute_meters();
+       recompute_tempos (metrics);
+       recompute_meters (metrics);
 }
 
 
@@ -1555,7 +1430,7 @@ TempoMap::metric_at (framepos_t frame, Metrics::const_iterator* last) const
           now see if we can find better candidates.
        */
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
 
                if ((*i)->frame() > frame) {
                        break;
@@ -1584,7 +1459,7 @@ TempoMap::metric_at (BBT_Time bbt) const
           now see if we can find better candidates.
        */
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                MeterSection* mw;
                if ((mw = dynamic_cast<MeterSection*> (*i)) != 0) {
                        BBT_Time section_start (mw->bbt());
@@ -1612,18 +1487,18 @@ TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt)
                warning << string_compose (_("tempo map asked for BBT time at frame %1\n"), frame) << endmsg;
                return;
        }
-       bbt = beats_to_bbt_locked (beat_at_frame_locked (frame));
+       bbt = beats_to_bbt_locked (_metrics, beat_at_frame_locked (_metrics, frame));
 }
 
 double
 TempoMap::bbt_to_beats (Timecode::BBT_Time bbt)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return bbt_to_beats_locked (bbt);
+       return bbt_to_beats_locked (_metrics, bbt);
 }
 
 double
-TempoMap::bbt_to_beats_locked (Timecode::BBT_Time bbt)
+TempoMap::bbt_to_beats_locked (Metrics& metrics, Timecode::BBT_Time bbt)
 {
        /* CALLER HOLDS READ LOCK */
 
@@ -1656,10 +1531,9 @@ TempoMap::bbt_to_beats_locked (Timecode::BBT_Time bbt)
                }
        }
 
-       double const remaining_bars = (bbt.bars - bars_offset - 1) - accumulated_bars;
+       double const remaining_bars = ((bbt.bars - bars_offset) - 1) - accumulated_bars;
        double const remaining_bars_in_beats = remaining_bars * prev_ms->divisions_per_bar();
        double const ret = remaining_bars_in_beats + accumulated_beats + (bbt.beats - 1) + (bbt.ticks / BBT_Time::ticks_per_beat);
-       std::cerr << "ret : " << ret << " bbt : " << bbt.bars << "|" << bbt.beats << "|" << bbt.ticks << std::endl;
 
        return ret;
 }
@@ -1668,11 +1542,11 @@ Timecode::BBT_Time
 TempoMap::beats_to_bbt (double beats)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return beats_to_bbt_locked (beats);
+       return beats_to_bbt_locked (_metrics, beats);
 }
 
 Timecode::BBT_Time
-TempoMap::beats_to_bbt_locked (double beats)
+TempoMap::beats_to_bbt_locked (Metrics& metrics, double beats)
 {
        /* CALLER HOLDS READ LOCK */
 
@@ -1684,12 +1558,11 @@ TempoMap::beats_to_bbt_locked (double beats)
 
                if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
 
-                       if (m->beat() > beats) {
-                               /* this is the meter after the one our beat is on*/
-                               break;
-                       }
-
                        if (prev_ms) {
+                               if (m->beat() > beats) {
+                                       /* this is the meter after the one our beat is on*/
+                                       break;
+                               }
                                if(m->position_lock_style() == AudioTime) {
                                        accumulated_bars = 0;
                                } else {
@@ -1732,7 +1605,7 @@ TempoMap::beats_to_bbt_locked (double beats)
 }
 
 double
-TempoMap::tick_at_frame_locked (framecnt_t frame) const
+TempoMap::tick_at_frame_locked (const Metrics& metrics, framecnt_t frame) const
 {
        /* HOLD (at least) THE READER LOCK */
 
@@ -1760,7 +1633,7 @@ TempoMap::tick_at_frame_locked (framecnt_t frame) const
 }
 
 framecnt_t
-TempoMap::frame_at_tick_locked (double tick) const
+TempoMap::frame_at_tick_locked (const Metrics& metrics, double tick) const
 {
        /* HOLD THE READER LOCK */
 
@@ -1792,27 +1665,27 @@ double
 TempoMap::beat_at_frame (framecnt_t frame) const
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return tick_at_frame_locked (frame) / BBT_Time::ticks_per_beat;
+       return tick_at_frame_locked (_metrics, frame) / BBT_Time::ticks_per_beat;
 }
 
 double
-TempoMap::beat_at_frame_locked (framecnt_t frame) const
+TempoMap::beat_at_frame_locked (Metrics& metrics, framecnt_t frame) const
 {
-       return tick_at_frame_locked (frame) / BBT_Time::ticks_per_beat;
+       return tick_at_frame_locked (metrics, frame) / BBT_Time::ticks_per_beat;
 }
 
 framecnt_t
 TempoMap::frame_at_beat (double beat) const
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       return frame_at_tick_locked (beat * BBT_Time::ticks_per_beat);
+       return frame_at_tick_locked (_metrics, beat * BBT_Time::ticks_per_beat);
 }
 
 framecnt_t
-TempoMap::frame_at_beat_locked (double beat) const
+TempoMap::frame_at_beat_locked (Metrics& metrics, double beat) const
 {
 
-       return frame_at_tick_locked (beat * BBT_Time::ticks_per_beat);
+       return frame_at_tick_locked (metrics, beat * BBT_Time::ticks_per_beat);
 }
 
 framepos_t
@@ -1828,19 +1701,270 @@ TempoMap::frame_time (const BBT_Time& bbt)
        }
        Glib::Threads::RWLock::ReaderLock lm (lock);
 
-       return frame_time_locked (bbt);;
+       return frame_time_locked (_metrics, bbt);;
 }
 
 framepos_t
-TempoMap::frame_time_locked (const BBT_Time& bbt)
+TempoMap::frame_time_locked (Metrics& metrics, const BBT_Time& bbt)
 {
        /* HOLD THE READER LOCK */
 
-       framepos_t const ret = frame_at_beat_locked (bbt_to_beats_locked (bbt));
+       framepos_t const ret = frame_at_beat_locked (metrics, bbt_to_beats_locked (metrics, bbt));
 
        return ret;
 }
 
+void
+TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
+{
+       TempoSection* prev_ts = 0;
+
+       section->set_frame (frame);
+       MetricSectionFrameSorter fcmp;
+       imaginary.sort (fcmp);
+
+       /* recompute our tempo section position */
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+                               if (t == section) {
+                                       /* we've already set the frame - set the beat */
+                                       if (prev_ts->position_lock_style() == MusicTime) {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_frame (bpm.beats_per_minute(), frame, _frame_rate));
+
+                                       } else {
+                                               prev_ts->set_c_func (section->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate));
+                                       }
+                                       section->set_beat (prev_ts->beat_at_tempo (bpm.beats_per_minute(), frame, _frame_rate));
+                                       prev_ts = t;
+                                       continue;
+                               }
+                               if (t->position_lock_style() == AudioTime) {
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               /* compute c from t */
+                                               prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate));
+                                       } else {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate));
+                                       }
+                                       t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
+
+                               } else {
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate));
+                                       } else {
+                                               /* compute c from t */
+                                               prev_ts->set_c_func(t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate));
+                                       }
+                                       t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate));
+
+                               }
+                       }
+                       prev_ts = t;
+               }
+       }
+       recompute_meters (imaginary);
+       imaginary.sort (fcmp);
+
+       if (section->position_lock_style() == MusicTime) {
+               /* we're setting the frame */
+               section->set_position_lock_style (AudioTime);
+               recompute_map (imaginary);
+               section->set_position_lock_style (MusicTime);
+       } else {
+               recompute_map (imaginary);
+       }
+/*
+       prev_ts = 0;
+       std::cerr << "dumping frame order ------" << std::endl;;
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+
+                               std::cerr << "current      : " << t->beats_per_minute() << " | " << t->beat() << " | " << t->frame() << std::endl;
+                               std::cerr << "previous     : " << prev_ts->beats_per_minute() << " | " << prev_ts->beat() << " | " << prev_ts->frame() << std::endl;
+                               std::cerr << "calculated   : " << prev_ts->tempo_at_beat(t->beat()) << " | " << prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate) <<  " | " << prev_ts->frame_at_tempo(t->beats_per_minute(), t->beat(), _frame_rate) << std::endl;
+                               std::cerr << "------" << std::endl;
+
+                       }
+                       prev_ts = t;
+               }
+       }
+       std::cerr << "end dump ------" << std::endl;
+*/
+}
+
+void
+TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& beat)
+{
+       TempoSection* prev_ts = 0;
+
+       section->set_beat (beat);
+       MetricSectionSorter cmp;
+       imaginary.sort (cmp);
+
+       /* recompute tempo positions */
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+                               if (t == section) {
+                                       /* we've already set the beat - set the frame */
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_beat (bpm.beats_per_minute(), beat, _frame_rate));
+                                       } else {
+                                               prev_ts->set_c_func (t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate));
+                                       }
+                                       t->set_frame (prev_ts->frame_at_tempo (bpm.beats_per_minute(), beat, _frame_rate));
+                                       prev_ts = t;
+                                       continue;
+                               }
+                               if (t->position_lock_style() == AudioTime) {
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               /* compute c from t */
+                                               prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate));
+                                       } else {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate));
+                                       }
+                                       t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate));
+
+                               } else {
+                                       if (prev_ts->position_lock_style() == AudioTime) {
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate));
+                                       } else {
+                                               /* compute c from t (fixed music time to fixed music time)*/
+                                               prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate));
+                                       }
+                                       t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(),   t->beat(), _frame_rate));
+                               }
+                       }
+                       prev_ts = t;
+               }
+       }
+       recompute_meters (imaginary);
+       imaginary.sort (cmp);
+
+       if (section->position_lock_style() == AudioTime) {
+               /* we're setting the beat */
+               section->set_position_lock_style (MusicTime);
+               recompute_map (imaginary);
+               section->set_position_lock_style (AudioTime);
+       } else {
+               recompute_map (imaginary);
+       }
+       /*
+       prev_ts = 0;
+       std::cerr << "dumping beat order ------" << std::endl;
+       std::cerr << "section    : " << section->beats_per_minute() << " | " << section->beat() << " | " << section->frame() << std::endl;
+       std::cerr << "------------------------------------" << std::endl;
+
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+
+                               std::cerr << "current    : " << t->beats_per_minute() << " | " << t->beat() << " | " << t->frame() << std::endl;
+                               std::cerr << "prev       : " << prev_ts->beats_per_minute() << " | " << prev_ts->beat() << " | " << prev_ts->frame() << std::endl;
+                               std::cerr << "calculated : " << prev_ts->tempo_at_beat(t->beat()) << " | " << prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate) << " | " << prev_ts->frame_at_tempo(t->beats_per_minute(), t->beat(), _frame_rate) << std::endl;
+                               std::cerr << "   ------" << std::endl;;
+
+                       }
+                       prev_ts = t;
+               }
+       }
+       std::cerr << "end dump ------";
+       prev_ts = 0;
+       */
+}
+
+void
+TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const double& beat)
+{
+       MeterSection* prev_ms = 0;
+
+       pair<double, BBT_Time> b_bbt = make_pair (beat, BBT_Time (1, 1, 0));
+       section->set_beat (b_bbt);
+       MetricSectionSorter cmp;
+       imaginary.sort (cmp);
+
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               MeterSection* m;
+               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
+                       if (prev_ms) {
+                               if (m->beat() > beat){
+                                       section->set_frame (frame_at_beat_locked (imaginary, beat));
+                                       prev_ms = section;
+                                       continue;
+                               }
+                               if (m->position_lock_style() == MusicTime) {
+                                       m->set_frame (frame_at_beat_locked (imaginary, m->beat()));
+                               } else {
+                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (imaginary, m->frame()), BBT_Time (1, 1, 0));
+                                       m->set_beat (b_bbt);
+                               }
+                       }
+                       prev_ms = m;
+               }
+       }
+
+       MetricSectionFrameSorter fcmp;
+       imaginary.sort (fcmp);
+
+       if (section->position_lock_style() == AudioTime) {
+               /* we're setting the beat */
+               section->set_position_lock_style (MusicTime);
+               recompute_meters (imaginary);
+               section->set_position_lock_style (AudioTime);
+       } else {
+               recompute_meters (imaginary);
+       }
+
+}
+
+void
+TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
+{
+       MeterSection* prev_ms = 0;
+
+       section->set_frame (frame);
+       MetricSectionFrameSorter fcmp;
+       imaginary.sort (fcmp);
+
+       for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               MeterSection* m;
+               if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
+                       if (prev_ms) {
+                               if (m->frame() > frame){
+                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (imaginary, frame), BBT_Time (1, 1, 0));
+                                       section->set_beat (b_bbt);
+                                       prev_ms = section;
+                                       continue;
+                               }
+                               if (m->position_lock_style() == MusicTime) {
+                                       m->set_frame (frame_at_beat_locked (imaginary, m->beat()));
+                               } else {
+                                       pair<double, BBT_Time> b_bbt = make_pair (beat_at_frame_locked (imaginary, m->frame()), BBT_Time (1, 1, 0));
+                                       m->set_beat (b_bbt);
+                               }
+                       }
+                       prev_ms = m;
+               }
+       }
+
+       MetricSectionSorter cmp;
+       imaginary.sort (cmp);
+
+       if (section->position_lock_style() == MusicTime) {
+               /* we're setting the frame */
+               section->set_position_lock_style (AudioTime);
+               recompute_map (imaginary);
+               section->set_position_lock_style (MusicTime);
+       } else {
+               recompute_map (imaginary);
+       }
+}
 
 framecnt_t
 TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
@@ -1851,7 +1975,7 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
        TempoSection* first = 0;
        TempoSection* second = 0;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                TempoSection* t;
 
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
@@ -1893,7 +2017,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
 
-       uint32_t ticks = (uint32_t) floor (tick_at_frame_locked (fr) + 0.5);
+       uint32_t ticks = (uint32_t) floor (tick_at_frame_locked (_metrics, fr) + 0.5);
        uint32_t beats = (uint32_t) floor (ticks / BBT_Time::ticks_per_beat);
        uint32_t ticks_one_subdivisions_worth = (uint32_t)BBT_Time::ticks_per_beat / sub_num;
 
@@ -1979,7 +2103,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir)
                        /* on the subdivision, do nothing */
                }
        }
-       return frame_at_tick_locked ((beats * BBT_Time::ticks_per_beat) + ticks);
+       return frame_at_tick_locked (_metrics, (beats * BBT_Time::ticks_per_beat) + ticks);
 }
 
 framepos_t
@@ -1987,9 +2111,9 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
 
-       double const beat_at_framepos = beat_at_frame_locked (frame);
+       double const beat_at_framepos = beat_at_frame_locked (_metrics, frame);
 
-       BBT_Time bbt (beats_to_bbt_locked (beat_at_framepos));
+       BBT_Time bbt (beats_to_bbt_locked (_metrics, beat_at_framepos));
 
        switch (type) {
        case Bar:
@@ -2025,11 +2149,11 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
 
        case Beat:
                if (dir < 0) {
-                       return frame_at_beat_locked (floor (beat_at_framepos));
+                       return frame_at_beat_locked (_metrics, floor (beat_at_framepos));
                } else if (dir > 0) {
-                       return frame_at_beat_locked (ceil (beat_at_framepos));
+                       return frame_at_beat_locked (_metrics, ceil (beat_at_framepos));
                } else {
-                       return frame_at_beat_locked (floor (beat_at_framepos + 0.5));
+                       return frame_at_beat_locked (_metrics, floor (beat_at_framepos + 0.5));
                }
                break;
        }
@@ -2042,24 +2166,18 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
                    framepos_t lower, framepos_t upper)
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
-       double const upper_beat = floor (beat_at_frame_locked (upper));
-       double cnt = ceil (beat_at_frame_locked (lower));
-       MeterSection old_meter = meter_section_at (lower);
+       uint32_t const upper_beat = (uint32_t) floor (beat_at_frame_locked (_metrics, upper));
+       uint32_t cnt = (uint32_t) ceil (beat_at_frame_locked (_metrics, lower));
 
        while (cnt <= upper_beat) {
-               MeterSection const meter = meter_section_at (cnt);
-               if (meter.beat() != old_meter.beat()) {
-                       if (meter.position_lock_style () == AudioTime) {
-                               cnt = meter.beat();
-                       }
-                       old_meter = meter;
-               }
-               framecnt_t const pos = frame_at_beat_locked (cnt);
+               framecnt_t const pos = frame_at_beat_locked (_metrics, cnt);
+               MeterSection const meter = meter_section_at (pos);
+
                Tempo const tempo = tempo_at (pos);
-               BBT_Time const bbt = beats_to_bbt_locked ((double) cnt);
+               BBT_Time const bbt = beats_to_bbt_locked (_metrics, (double) cnt);
 
                points.push_back (BBTPoint (meter, tempo, pos, bbt.bars, bbt.beats));
-               cnt += 1.0;
+               ++cnt;
        }
 }
 
@@ -2071,7 +2189,7 @@ TempoMap::tempo_section_at (framepos_t frame) const
        Metrics::const_iterator i;
        TempoSection* prev = 0;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                TempoSection* t;
 
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
@@ -2104,7 +2222,7 @@ TempoMap::frames_per_beat_at (framepos_t frame, framecnt_t sr) const
        const TempoSection* ts_after = 0;
        Metrics::const_iterator i;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                TempoSection* t;
 
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
@@ -2133,7 +2251,7 @@ TempoMap::tempo_at (framepos_t frame) const
 
        Metrics::const_iterator i;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                TempoSection* t;
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
                        if ((prev_ts) && t->frame() > frame) {
@@ -2157,7 +2275,7 @@ TempoMap::meter_section_at (framepos_t frame) const
        Metrics::const_iterator i;
        MeterSection* prev = 0;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                MeterSection* t;
 
                if ((t = dynamic_cast<MeterSection*> (*i)) != 0) {
@@ -2186,7 +2304,7 @@ TempoMap::meter_section_at (double beat) const
        Metrics::const_iterator i;
        MeterSection* prev = 0;
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                MeterSection* t;
 
                if ((t = dynamic_cast<MeterSection*> (*i)) != 0) {
@@ -2222,7 +2340,7 @@ TempoMap::get_state ()
 
        {
                Glib::Threads::RWLock::ReaderLock lm (lock);
-               for (i = metrics.begin(); i != metrics.end(); ++i) {
+               for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                        root->add_child_nocopy ((*i)->get_state());
                }
        }
@@ -2238,9 +2356,9 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
 
                XMLNodeList nlist;
                XMLNodeConstIterator niter;
-               Metrics old_metrics (metrics);
+               Metrics old_metrics (_metrics);
                MeterSection* last_meter = 0;
-               metrics.clear();
+               _metrics.clear();
 
                nlist = node.children();
 
@@ -2251,7 +2369,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
 
                                try {
                                        TempoSection* ts = new TempoSection (*child);
-                                       metrics.push_back (ts);
+                                       _metrics.push_back (ts);
 
                                        if (ts->bar_offset() < 0.0) {
                                                if (last_meter) {
@@ -2262,7 +2380,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
 
                                catch (failed_constructor& err){
                                        error << _("Tempo map: could not set new state, restoring old one.") << endmsg;
-                                       metrics = old_metrics;
+                                       _metrics = old_metrics;
                                        break;
                                }
 
@@ -2270,13 +2388,13 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
 
                                try {
                                        MeterSection* ms = new MeterSection (*child);
-                                       metrics.push_back (ms);
+                                       _metrics.push_back (ms);
                                        last_meter = ms;
                                }
 
                                catch (failed_constructor& err) {
                                        error << _("Tempo map: could not set new state, restoring old one.") << endmsg;
-                                       metrics = old_metrics;
+                                       _metrics = old_metrics;
                                        break;
                                }
                        }
@@ -2284,10 +2402,10 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
 
                if (niter == nlist.end()) {
                        MetricSectionSorter cmp;
-                       metrics.sort (cmp);
+                       _metrics.sort (cmp);
                }
                /* check for legacy sessions where bbt was the base musical unit for tempo */
-               for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                        MeterSection* prev_ms;
                        TempoSection* prev_ts;
                        if ((prev_ms = dynamic_cast<MeterSection*>(*i)) != 0) {
@@ -2308,9 +2426,9 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
                   ardour2 somehow allowed.
                */
 
-               Metrics::iterator prev = metrics.end();
-               for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
-                       if (prev != metrics.end()) {
+               Metrics::iterator prev = _metrics.end();
+               for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+                       if (prev != _metrics.end()) {
                                MeterSection* ms;
                                MeterSection* prev_ms;
                                TempoSection* ts;
@@ -2332,7 +2450,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
                        prev = i;
                }
 
-               recompute_map (true, -1);
+               recompute_map (_metrics);
        }
 
        PropertyChanged (PropertyChange ());
@@ -2347,7 +2465,7 @@ TempoMap::dump (std::ostream& o) const
        const MeterSection* m;
        const TempoSection* t;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
 
                if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
                        o << "Tempo @ " << *i << " (Bar-offset: " << t->bar_offset() << ") " << t->beats_per_minute() << " BPM (pulse = 1/" << t->note_type() << ") at " << t->beat() << " frame= " << t->frame() << " (movable? "
@@ -2365,7 +2483,7 @@ TempoMap::n_tempos() const
        Glib::Threads::RWLock::ReaderLock lm (lock);
        int cnt = 0;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if (dynamic_cast<const TempoSection*>(*i) != 0) {
                        cnt++;
                }
@@ -2380,7 +2498,7 @@ TempoMap::n_meters() const
        Glib::Threads::RWLock::ReaderLock lm (lock);
        int cnt = 0;
 
-       for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+       for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                if (dynamic_cast<const MeterSection*>(*i) != 0) {
                        cnt++;
                }
@@ -2394,7 +2512,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
 {
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                        if ((*i)->frame() >= where && (*i)->movable ()) {
                                (*i)->set_frame ((*i)->frame() + amount);
                        }
@@ -2422,7 +2540,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                bool first = true;
                MetricSection* prev = 0;
 
-               for (i = metrics.begin(); i != metrics.end(); ++i) {
+               for (i = _metrics.begin(); i != _metrics.end(); ++i) {
 
                        BBT_Time bbt;
                        //TempoMetric metric (*meter, *tempo);
@@ -2445,7 +2563,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                                                ms->set_beat (start);
                                        }
                                        if ((t = dynamic_cast<TempoSection*>(prev)) != 0) {
-                                               pair<double, BBT_Time> start = make_pair (t->beat(), beats_to_bbt_locked (t->beat()));
+                                               pair<double, BBT_Time> start = make_pair (t->beat(), beats_to_bbt_locked (_metrics, t->beat()));
                                                ms->set_beat (start);
                                        }
                                        ms->set_frame (prev->frame());
@@ -2459,7 +2577,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                        // cerr << bbt << endl;
 
                        if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
-                               t->set_beat (beat_at_frame_locked (m->frame()));
+                               t->set_beat (beat_at_frame_locked (_metrics, m->frame()));
                                tempo = t;
                                // cerr << "NEW TEMPO, frame = " << (*i)->frame() << " beat = " << (*i)->beat() <<endl;
                        } else if ((m = dynamic_cast<MeterSection*>(*i)) != 0) {
@@ -2484,7 +2602,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                                                bbt.beats = 1;
                                        }
                                }
-                               pair<double, BBT_Time> start = make_pair (beat_at_frame_locked (m->frame()), bbt);
+                               pair<double, BBT_Time> start = make_pair (beat_at_frame_locked (_metrics, m->frame()), bbt);
                                m->set_beat (start);
                                meter = m;
                                // cerr << "NEW METER, frame = " << (*i)->frame() << " beat = " << (*i)->beat() <<endl;
@@ -2496,7 +2614,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
                        prev = (*i);
                }
 
-               recompute_map (true);
+               recompute_map (_metrics);
        }
 
 
@@ -2515,7 +2633,7 @@ TempoMap::remove_time (framepos_t where, framecnt_t amount)
        bool meter_after = false; // is there a meter marker likewise?
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
+               for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                        if ((*i)->frame() >= where && (*i)->frame() < where+amount) {
                                metric_kill_list.push_back(*i);
                                TempoSection *lt = dynamic_cast<TempoSection*> (*i);
@@ -2551,12 +2669,12 @@ TempoMap::remove_time (framepos_t where, framecnt_t amount)
 
                //remove all the remaining metrics
                for (std::list<MetricSection*>::iterator i = metric_kill_list.begin(); i != metric_kill_list.end(); ++i) {
-                       metrics.remove(*i);
+                       _metrics.remove(*i);
                        moved = true;
                }
 
                if (moved) {
-                       recompute_map (true);
+                       recompute_map (_metrics);
                }
        }
        PropertyChanged (PropertyChange ());
@@ -2603,7 +2721,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
 
        /* find the starting metrics for tempo & meter */
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
 
                if ((*i)->frame() > effective_pos) {
                        break;
@@ -2616,7 +2734,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
                }
        }
 
-       for (i = metrics.begin(); i != metrics.end(); ++i) {
+       for (i = _metrics.begin(); i != _metrics.end(); ++i) {
                if ((*i)->frame() > effective_pos) {
                        if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
                                next_tempo = t;
@@ -2650,7 +2768,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
                   to or after the start of the next metric section? in which case, use it.
                */
 
-               if (i != metrics.end()) {
+               if (i != _metrics.end()) {
                        if ((*i)->frame() <= pos) {
 
                                /* about to change tempo or meter, so add the
@@ -2702,7 +2820,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op) const
                   to or after the start of the next metric section? in which case, use it.
                */
 
-               if (i != metrics.end()) {
+               if (i != _metrics.end()) {
                        if ((*i)->frame() <= pos) {
 
                                /* about to change tempo or meter, so add the
index 638e1107614f153624bd217dfa8801e34732ad7e..aa425134aeff22f9d5db64ab6fedccef0f7352b2 100644 (file)
@@ -41,10 +41,10 @@ TempoTest::recomputeMapTest ()
        Meter meterB (3, 4);
        map.add_meter (meterB, 12.0, BBT_Time (4, 1, 0));
 
-       list<MetricSection*>::iterator i = map.metrics.begin();
+       list<MetricSection*>::iterator i = map._metrics.begin();
        CPPUNIT_ASSERT_EQUAL (framepos_t (0), (*i)->frame ());
 
-       i = map.metrics.end();
+       i = map._metrics.end();
        --i;
        CPPUNIT_ASSERT_EQUAL (framepos_t (288e3), (*i)->frame ());
 }