Tempo ramps - fix various thinkos.
authornick_m <mainsbridge@gmail.com>
Mon, 7 Mar 2016 14:11:08 +0000 (01:11 +1100)
committernick_m <mainsbridge@gmail.com>
Fri, 27 May 2016 13:38:11 +0000 (23:38 +1000)
gtk2_ardour/tempo_dialog.cc
libs/ardour/ardour/tempo.h
libs/ardour/tempo.cc

index eef19e22a5f686a8709497634293e6d628008ee3..0d982a408540cfd504871a4d56a03ae4cb3eff0c 100644 (file)
@@ -277,7 +277,7 @@ TempoDialog::entry_key_release (GdkEventKey*)
        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));
+               set_response_sensitive (RESPONSE_ACCEPT, _map->can_solve_bbt (_section, Tempo (get_bpm(), get_note_type()), bbt));
        } else {
                set_response_sensitive (RESPONSE_ACCEPT, is_user_input_valid());
        }
index 5fb9275df8af2a370c2abe18cc077de41c3b2da1..10f01643bf812dea41a1447c1cd6c303d21e4e78 100644 (file)
@@ -386,7 +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);
+       bool can_solve_bbt (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);
@@ -437,10 +437,10 @@ private:
        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);
+       bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame);
+       bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& beat);
+       void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame);
+       void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const double& beat);
 
        friend class ::BBTTest;
        friend class ::FrameposPlusBeatsTest;
index 0ea2a4385731687de9c7c49bc5c08ac4cd12148b..63441b0d08f88f5cead3c3b4d4cd8457550f0bc1 100644 (file)
@@ -1084,19 +1084,39 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB
 {
        Glib::Threads::RWLock::ReaderLock lm (lock);
        Metrics future_map;
+       framepos_t ret = 0;
        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);
+       if (solve_map (future_map, new_section, bpm, beat)) {
+               ret = new_section->frame();
+       } else {
+               ret = frame_at_beat_locked (_metrics, beat);
+       }
 
-       return new_section->frame();
+       Metrics::const_iterator d = future_map.begin();
+       while (d != future_map.end()) {
+               delete (*d);
+               ++d;
+       }
+       return ret;
 }
 
 void
 TempoMap::gui_move_tempo (TempoSection* ts,  const Tempo& bpm, const framepos_t& frame)
 {
+       Metrics future_map;
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               get_new_order (_metrics, ts, bpm, frame);
+               TempoSection* new_section = copy_metrics_and_point (future_map, ts);
+               if (solve_map (future_map, new_section, bpm, frame)) {
+                       solve_map (_metrics, ts, bpm, frame);
+               }
+       }
+
+       Metrics::const_iterator d = future_map.begin();
+       while (d != future_map.end()) {
+               delete (*d);
+               ++d;
        }
 
        MetricPositionChanged (); // Emit Signal
@@ -1107,7 +1127,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t&
 {
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               get_new_order (_metrics, ms, mt, frame);
+               solve_map (_metrics, ms, mt, frame);
        }
 
        MetricPositionChanged (); // Emit Signal
@@ -1118,7 +1138,7 @@ 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);
+               solve_map (_metrics, ms, mt, beat);
        }
 
        MetricPositionChanged (); // Emit Signal
@@ -1162,7 +1182,7 @@ TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
 }
 
 bool
-TempoMap::bbt_valid (TempoSection* ts,  const Tempo& bpm, const BBT_Time& bbt)
+TempoMap::can_solve_bbt (TempoSection* ts,  const Tempo& bpm, const BBT_Time& bbt)
 {
        Metrics copy;
        TempoSection* new_section = 0;
@@ -1174,26 +1194,14 @@ TempoMap::bbt_valid (TempoSection* ts,  const Tempo& bpm, const BBT_Time& bbt)
        }
 
        double const beat = bbt_to_beats_locked (copy, bbt);
-       get_new_order (copy, new_section, bpm, beat);
+       ret = solve_map (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;
 }
 
@@ -1343,21 +1351,11 @@ TempoMap::recompute_tempos (Metrics& metrics)
                if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
                        if (prev_ts) {
                                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));
-                                       }
+                                       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));
-                                       }
+                                       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));
 
                                }
@@ -1714,10 +1712,11 @@ TempoMap::frame_time_locked (Metrics& metrics, const BBT_Time& bbt)
        return ret;
 }
 
-void
-TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
+bool
+TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
 {
        TempoSection* prev_ts = 0;
+       bool ret = true;
 
        section->set_frame (frame);
        MetricSectionFrameSorter fcmp;
@@ -1730,40 +1729,24 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
                        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));
-                                       }
+                                       prev_ts->set_c_func (prev_ts->compute_c_func_frame (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() == 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));
-                                       }
+                                       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));
-                                       }
+                                       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 (fcmp);
 
        if (section->position_lock_style() == MusicTime) {
@@ -1774,7 +1757,22 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
        } else {
                recompute_map (imaginary);
        }
-/*
+
+       /*
+       prev_ts = 0;
+       for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+                               if (t->frame() < prev_ts->frame()) {
+                                       ret = false;
+                               }
+                       }
+                       prev_ts = t;
+               }
+       }
+
+       /*
        prev_ts = 0;
        std::cerr << "dumping frame order ------" << std::endl;;
        for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
@@ -1793,13 +1791,16 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
                }
        }
        std::cerr << "end dump ------" << std::endl;
-*/
+       */
+
+       return ret;
 }
 
-void
-TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& beat)
+bool
+TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& beat)
 {
        TempoSection* prev_ts = 0;
+       bool ret = true;
 
        section->set_beat (beat);
        MetricSectionSorter cmp;
@@ -1812,31 +1813,17 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
                        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));
-                                       }
+                                       prev_ts->set_c_func (prev_ts->compute_c_func_beat (bpm.beats_per_minute(), 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));
-                                       }
+                                       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));
-                                       }
+                                       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));
                                }
                        }
@@ -1844,8 +1831,8 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
                }
        }
        recompute_meters (imaginary);
-       imaginary.sort (cmp);
 
+       imaginary.sort (cmp);
        if (section->position_lock_style() == AudioTime) {
                /* we're setting the beat */
                section->set_position_lock_style (MusicTime);
@@ -1854,6 +1841,19 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
        } else {
                recompute_map (imaginary);
        }
+       prev_ts = 0;
+       for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
+               TempoSection* t;
+               if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                       if (prev_ts) {
+                               if (t->beat() < prev_ts->beat()) {
+                                       ret = false;
+                               }
+                       }
+                       prev_ts = t;
+               }
+       }
+
        /*
        prev_ts = 0;
        std::cerr << "dumping beat order ------" << std::endl;
@@ -1877,10 +1877,12 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo&
        std::cerr << "end dump ------";
        prev_ts = 0;
        */
+
+       return ret;
 }
 
 void
-TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const double& beat)
+TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& beat)
 {
        MeterSection* prev_ms = 0;
 
@@ -1910,7 +1912,7 @@ TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter&
        }
 
        MetricSectionFrameSorter fcmp;
-       imaginary.sort (fcmp);
+       //imaginary.sort (fcmp);
 
        if (section->position_lock_style() == AudioTime) {
                /* we're setting the beat */
@@ -1924,7 +1926,7 @@ TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter&
 }
 
 void
-TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
+TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
 {
        MeterSection* prev_ms = 0;