Tempo ramps - remove unused code, small meter dilation drag cleanup.
[ardour.git] / libs / ardour / tempo.cc
index 30b4935c3de1557c2ed4e16d4dbe1cb1e14ee107..8c710ad180896a95f7284e9ffb050f37540dc119 100644 (file)
@@ -2553,28 +2553,6 @@ TempoMap::gui_move_tempo_beat (TempoSection* ts, const double& beat)
        MetricPositionChanged (); // Emit Signal
 }
 
-void
-TempoMap::gui_move_tempo_pulse (TempoSection* ts, const double& pulse)
-{
-       Metrics future_map;
-       {
-               Glib::Threads::RWLock::WriterLock lm (lock);
-               TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
-               if (solve_map (future_map, tempo_copy, pulse)) {
-                       solve_map (_metrics, ts, pulse);
-                       recompute_meters (_metrics);
-               }
-       }
-
-       Metrics::const_iterator d = future_map.begin();
-       while (d != future_map.end()) {
-               delete (*d);
-               ++d;
-       }
-
-       MetricPositionChanged (); // Emit Signal
-}
-
 void
 TempoMap::gui_move_meter (MeterSection* ms, const framepos_t&  frame)
 {
@@ -2733,12 +2711,6 @@ TempoMap::gui_dilate_tempo (MeterSection* ms, const framepos_t& frame)
                                new_bpm = prev_t->tempo_at_frame (prev_t->frame() + fr_off, _frame_rate) * (double) prev_t->note_type();
                        }
 
-                       const double diff = (prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type()) - prev_t->beats_per_minute();
-                       if (diff > -0.1 && diff  < 0.1) {
-                               new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
-                                                                       / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
-                       }
-
                } else if (prev_t->c_func() > 0.0) {
                        if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
                                new_bpm = prev_t->tempo_at_frame (prev_t->frame() - frame_contribution, _frame_rate) * (double) prev_t->note_type();
@@ -2746,13 +2718,13 @@ TempoMap::gui_dilate_tempo (MeterSection* ms, const framepos_t& frame)
                                /* prev_to_prev_t is irrelevant */
                                new_bpm = prev_t->tempo_at_frame (prev_t->frame() - fr_off, _frame_rate) * (double) prev_t->note_type();
                        }
+               }
 
-                       /* limits - a bit clunky, but meh */
-                       const double diff = (prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type()) - prev_t->beats_per_minute();
-                       if (diff > -0.1 && diff  < 0.1) {
-                               new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
-                                                                       / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
-                       }
+               /* limits - a bit clunky, but meh */
+               const double diff = (prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type()) - prev_t->beats_per_minute();
+               if (diff > -1.0 && diff  < 1.0) {
+                       new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
+                                                               / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
                }
 
                prev_t->set_beats_per_minute (new_bpm);
@@ -2783,18 +2755,25 @@ TempoMap::gui_dilate_tempo (MeterSection* ms, const framepos_t& frame)
 }
 
 void
-TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame)
-{
-       Metrics future_map;
-       TempoSection* ts = 0;
+TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const framepos_t& end_frame, const double& pulse)
+{
+       /*
+         Ts (future prev_t)   Tnext
+         |                    |
+         |     [drag^]        |
+         |----------|----------
+               e_f  pulse(frame)
+       */
 
+       Metrics future_map;
 
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               ts = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, frame - 1));
+
                if (!ts) {
                        return;
                }
+
                TempoSection* prev_t = copy_metrics_and_point (_metrics, future_map, ts);
                TempoSection* prev_to_prev_t = 0;
                const frameoffset_t fr_off = end_frame - frame;
@@ -2803,32 +2782,38 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                        prev_to_prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (future_map, prev_t->frame() - 1));
                }
 
+               TempoSection* next_t = 0;
+               for (Metrics::iterator i = future_map.begin(); i != future_map.end(); ++i) {
+                       TempoSection* t = 0;
+                       if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+                               if (t->frame() > ts->frame()) {
+                                       next_t = t;
+                                       break;
+                               }
+                       }
+               }
+
                /* the change in frames is the result of changing the slope of at most 2 previous tempo sections.
                   constant to constant is straightforward, as the tempo prev to prev_t has constant slope.
                */
                double contribution = 0.0;
+               double start_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
 
-               if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
-                       /* prev to prev_t's position will remain constant in terms of frame and pulse. lets use frames. */
-                       contribution = prev_to_prev_t->beats_per_minute() / (prev_to_prev_t->beats_per_minute() + prev_t->beats_per_minute());
+               if (next_t && prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
+                       contribution = (prev_t->frame() - prev_to_prev_t->frame()) / (double) (next_t->frame() - prev_to_prev_t->frame());
                }
 
-               frameoffset_t frame_contribution = contribution * (double) fr_off;
-               frameoffset_t prev_t_frame_contribution = fr_off - frame_contribution;
-
-               const double start_tempo = prev_t->tempo_at_frame (frame, _frame_rate);
-               const double end_tempo = prev_t->tempo_at_frame (frame + prev_t_frame_contribution, _frame_rate);
-               const double start_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
-               const double end_pulse = prev_t->pulse_at_frame (end_frame, _frame_rate);
-               const double dpulse = (start_pulse) / (end_pulse);
-               double new_bpm = prev_t->tempo_at_frame (prev_t->frame() - prev_t_frame_contribution, _frame_rate) * (double) prev_t->note_type();
+               frameoffset_t prev_t_frame_contribution = fr_off - (contribution * (double) fr_off);
+               double end_pulse = prev_t->pulse_at_frame (end_frame, _frame_rate);
+               double new_bpm;
 
                if (prev_t->type() == TempoSection::Constant || prev_t->c_func() == 0.0) {
 
                        if (prev_t->position_lock_style() == MusicTime) {
                                if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
-                                       new_bpm = prev_t->beats_per_minute() * ((frame - prev_t->frame())
-                                                                               / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
+
+                                       new_bpm = prev_t->beats_per_minute() * ((frame - prev_to_prev_t->frame())
+                                                                               / (double) ((frame + prev_t_frame_contribution) - prev_to_prev_t->frame()));
 
                                } else {
                                        /* prev to prev is irrelevant */
@@ -2854,35 +2839,22 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                                        }
                                }
                        }
-               } else if (prev_t->c_func() < 0.0) {
+               } else {
 
-                       const double end_minute = (((frame + prev_t_frame_contribution) - prev_t->frame()) / (double) _frame_rate) / 60.0;
-                       const double future_c = log (end_tempo / (new_bpm / (double) prev_t->note_type())) / end_minute;
+                       double frame_ratio;
+                       double pulse_ratio;
+                       const framepos_t pulse_pos = prev_t->frame_at_pulse (pulse, _frame_rate);
 
-                       const double dtempo = (start_tempo) / (end_tempo);
-                       const double dframe = (frame) / (double) ((frame + prev_t_frame_contribution));
+                       if (prev_to_prev_t) {
 
-                       /* limits - a bit clunky, but meh */
-                       if (future_c > -10.1 && future_c  < 10.1) {
-                               new_bpm = prev_t->beats_per_minute() * (dpulse / dtempo);
+                               frame_ratio = (((pulse_pos - fr_off) - prev_to_prev_t->frame()) / (double) ((pulse_pos) - prev_to_prev_t->frame()));
+                               pulse_ratio = ((start_pulse - prev_to_prev_t->pulse()) / (end_pulse - prev_to_prev_t->pulse()));
                        } else {
-                               new_bpm = prev_t->beats_per_minute() * (dframe / dtempo);
-                       }
 
-               } else if (prev_t->c_func() > 0.0) {
-
-                       const double end_minute = (((frame + prev_t_frame_contribution) - prev_t->frame()) / (double) _frame_rate) / 60.0;
-                       const double future_c = log (end_tempo / (new_bpm / (double) prev_t->note_type())) / end_minute;
-
-                       const double dtempo = (end_tempo) / (start_tempo);
-                       const double dframe = (frame) / (double) ((frame + prev_t_frame_contribution));
-
-                       /* limits - a bit clunky, but meh */
-                       if (future_c > -10.1 && future_c  < 10.1) {
-                               new_bpm = prev_t->beats_per_minute() * (dpulse / dtempo);
-                       } else {
-                               new_bpm = prev_t->beats_per_minute() * (dframe / dtempo);
+                               frame_ratio = (((pulse_pos - fr_off) - prev_t->frame()) / (double) ((pulse_pos) - prev_t->frame()));
+                               pulse_ratio = (start_pulse / end_pulse);
                        }
+                       new_bpm = prev_t->beats_per_minute() * (pulse_ratio * frame_ratio);
                }
 
                prev_t->set_beats_per_minute (new_bpm);
@@ -2890,9 +2862,7 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                recompute_meters (future_map);
 
                if (check_solved (future_map, true)) {
-
-                       prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, frame - 1));
-                       prev_t->set_beats_per_minute (new_bpm);
+                       ts->set_beats_per_minute (new_bpm);
                        recompute_tempos (_metrics);
                        recompute_meters (_metrics);
                }