Tempo ramps - improve constraint mod + bbt dragging begavior.
authornick_m <mainsbridge@gmail.com>
Mon, 9 May 2016 19:25:53 +0000 (05:25 +1000)
committernick_m <mainsbridge@gmail.com>
Fri, 27 May 2016 13:38:16 +0000 (23:38 +1000)
gtk2_ardour/editor_drag.cc
gtk2_ardour/tempo_curve.cc
libs/ardour/tempo.cc

index 52b5ab6d1aa7c31e05b58e05517d355112e0365f..0116f9feaa14e1f4d7c7341d9c42fa6c5c63aff7 100644 (file)
@@ -3481,27 +3481,31 @@ BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i)
        , before_state (0)
 {
        DEBUG_TRACE (DEBUG::Drags, "New BBTRulerDrag\n");
-
 }
 
 void
 BBTRulerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 {
        Drag::start_grab (event, cursor);
-       show_verbose_cursor_time (adjusted_current_frame (event));
+       TempoMap& map (_editor->session()->tempo_map());
+       ostringstream sstr;
+       sstr << fixed << setprecision(3) << map.tempo_at (adjusted_current_frame (event)).beats_per_minute();
+       show_verbose_cursor_text (sstr.str());
 }
 
 void
 BBTRulerDrag::setup_pointer_frame_offset ()
 {
-       _pointer_frame_offset = 0;
+       TempoMap& map (_editor->session()->tempo_map());
+       _pointer_frame_offset = raw_grab_frame() - map.frame_at_beat (ceil (map.beat_at_frame (raw_grab_frame())));
 }
 
 void
 BBTRulerDrag::motion (GdkEvent* event, bool first_move)
 {
+       TempoMap& map (_editor->session()->tempo_map());
+
        if (first_move) {
-               TempoMap& map (_editor->session()->tempo_map());
                /* get current state */
                before_state = &map.get_state();
                _editor->begin_reversible_command (_("dilate tempo"));
@@ -3513,7 +3517,9 @@ BBTRulerDrag::motion (GdkEvent* event, bool first_move)
                /* adjust previous tempo to match pointer frame */
                _editor->session()->tempo_map().gui_dilate_tempo (last_pointer_frame(), pf);
        }
-       show_verbose_cursor_time (pf);
+       ostringstream sstr;
+       sstr << fixed << setprecision(3) << map.tempo_at (pf).beats_per_minute();
+       show_verbose_cursor_text (sstr.str());
 }
 
 void
index 8604f7abba3335ddb1de2277b27d58245453d61e..37feb9870dd32430957469d51302270890ff4cf6 100644 (file)
@@ -78,14 +78,16 @@ TempoCurve::TempoCurve (PublicEditor& ed, ArdourCanvas::Container& parent, guint
         * make sure they can both be used to lookup this object.
         */
 
-       group->set_data ("marker", this);
+       _curve->set_data ("tempo curve", this);
+       _background->set_data ("tempo curve", this);
 
        if (handle_events) {
                //group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this));
        }
+
        set_position (_tempo.frame(), UINT32_MAX);
-       _curve->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), group, this));
-       _background->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), group, this));
+       _curve->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), _curve, this));
+       _background->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), _background, this));
 
 }
 
index 7fd41b12c157387a0bf0c05b7be3ea0402dd79f3..30b4935c3de1557c2ed4e16d4dbe1cb1e14ee107 100644 (file)
@@ -2798,7 +2798,6 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                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;
-               double new_bpm = 0.0;
 
                if (prev_t && prev_t->pulse() > 0.0) {
                        prev_to_prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (future_map, prev_t->frame() - 1));
@@ -2808,30 +2807,34 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                   constant to constant is straightforward, as the tempo prev to prev_t has constant slope.
                */
                double contribution = 0.0;
-               frameoffset_t frame_contribution = 0;
-               frameoffset_t prev_t_frame_contribution = fr_off;
 
                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_t->frame() - prev_to_prev_t->frame()) / (double) (frame - prev_to_prev_t->frame());
-                       frame_contribution = contribution * (double) fr_off;
-                       prev_t_frame_contribution -= frame_contribution;
+                       contribution = prev_to_prev_t->beats_per_minute() / (prev_to_prev_t->beats_per_minute() + prev_t->beats_per_minute());
                }
 
+               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();
+
                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()));
+                                                                               / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
 
                                } else {
                                        /* prev to prev is irrelevant */
-                                       const double meter_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
-                                       const double frame_pulse = prev_t->pulse_at_frame (end_frame, _frame_rate);
 
-                                       if (frame_pulse != prev_t->pulse()) {
-                                               new_bpm = prev_t->beats_per_minute() * ((meter_pulse - prev_t->pulse()) / (frame_pulse - prev_t->pulse()));
+                                       if (start_pulse != prev_t->pulse()) {
+                                               new_bpm = prev_t->beats_per_minute() * ((start_pulse - prev_t->pulse()) / (end_pulse - prev_t->pulse()));
                                        } else {
                                                new_bpm = prev_t->beats_per_minute();
                                        }
@@ -2840,7 +2843,7 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame
                                /* AudioTime */
                                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()));
+                                                                               / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
                                } else {
                                        /* prev_to_prev_t is irrelevant */
 
@@ -2852,38 +2855,33 @@ TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_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();
-                       } else {
-                               /* 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();
 
-                       }
-                       const double end_minute = ((end_frame - prev_t->frame()) / (double) _frame_rate) / 60.0;
-                       const double end_tempo = prev_t->tempo_at_frame (end_frame, _frame_rate);
+                       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 = (start_tempo) / (end_tempo);
+                       const double dframe = (frame) / (double) ((frame + prev_t_frame_contribution));
+
                        /* limits - a bit clunky, but meh */
-                       if (future_c > -20.1 && future_c  < 20.1) {
-                               new_bpm = prev_t->beats_per_minute() * ((frame - prev_t->frame())
-                                                                       / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
+                       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);
                        }
 
                } 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();
-                       } else {
-                               /* 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();
-                       }
-                       const double end_minute = ((end_frame - prev_t->frame()) / (double) _frame_rate) / 60.0;
-                       const double end_tempo = prev_t->tempo_at_frame (end_frame, _frame_rate);
+
+                       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 > -20.1 && future_c  < 20.1) {
-                               new_bpm = prev_t->beats_per_minute() * ((frame - prev_t->frame())
-                                                                       / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
+                       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);
                        }
                }