Rework tempo marker editing menu functions
authornick_m <mainsbridge@gmail.com>
Thu, 20 Jul 2017 14:17:58 +0000 (00:17 +1000)
committernick_m <mainsbridge@gmail.com>
Fri, 21 Jul 2017 16:15:20 +0000 (02:15 +1000)
Setting a tempo to 'Continue' via right click puts it in a permanent state
of continuing the previous section's end tempo (basically what
'Lock Continue' should have been). This can be disabled (unlocked) by
selecting 'Don't Continue'.

Remove the previous temporary 'Continue' function.

Reorganise menu to separate position lock style from more commonly
used functions.

gtk2_ardour/editor.h
gtk2_ardour/editor_markers.cc
libs/ardour/ardour/tempo.h
libs/ardour/tempo.cc

index a598ef98d6e46e348b5089565fd11b2a283ab057..e5b231aa0f1ffbac9449b455b9cdd92d2052730a 100644 (file)
@@ -1701,7 +1701,6 @@ private:
        void toggle_marker_lock_style ();
        void toggle_tempo_clamped ();
        void toggle_tempo_type ();
-       void continue_previous_tempo ();
        void ramp_to_next_tempo ();
        void toggle_marker_menu_lock ();
        void toggle_marker_menu_glue ();
index 6fda0ad3f1de86a53208444075f8974c06b05083..996b5878bde2a92ffc1ce8b6ddd76c0789e6df33 100644 (file)
@@ -1000,15 +1000,14 @@ Editor::build_tempo_marker_menu (TempoMarker* loc, bool can_remove)
 
        if (!loc->tempo().initial()) {
                if (loc->tempo().clamped()) {
-                       items.push_back (MenuElem (_("Unlock Continue"), sigc::mem_fun(*this, &Editor::toggle_tempo_clamped)));
+                       items.push_back (MenuElem (_("Don't Continue"), sigc::mem_fun(*this, &Editor::toggle_tempo_clamped)));
                } else {
-                       items.push_back (MenuElem (_("Lock Continue"), sigc::mem_fun(*this, &Editor::toggle_tempo_clamped)));
+                       items.push_back (MenuElem (_("Continue"), sigc::mem_fun(*this, &Editor::toggle_tempo_clamped)));
                }
+       }
 
-               TempoSection* prev_ts = _session->tempo_map().previous_tempo_section (&loc->tempo());
-               if (prev_ts && prev_ts->end_note_types_per_minute() != loc->tempo().note_types_per_minute()) {
-                       items.push_back (MenuElem (_("Continue"), sigc::mem_fun(*this, &Editor::continue_previous_tempo)));
-               }
+       if (loc->tempo().type() == TempoSection::Ramp) {
+               items.push_back (MenuElem (_("Set Constant"), sigc::mem_fun(*this, &Editor::toggle_tempo_type)));
        }
 
        TempoSection* next_ts = _session->tempo_map().next_tempo_section (&loc->tempo());
@@ -1016,16 +1015,16 @@ Editor::build_tempo_marker_menu (TempoMarker* loc, bool can_remove)
                items.push_back (MenuElem (_("Ramp to Next"), sigc::mem_fun(*this, &Editor::ramp_to_next_tempo)));
        }
 
-       if (loc->tempo().type() == TempoSection::Ramp) {
-               items.push_back (MenuElem (_("Set Constant"), sigc::mem_fun(*this, &Editor::toggle_tempo_type)));
-       }
-
        if (loc->tempo().position_lock_style() == AudioTime && can_remove) {
+               items.push_back (SeparatorElem());
                items.push_back (MenuElem (_("Lock to Music"), sigc::mem_fun(*this, &Editor::toggle_marker_lock_style)));
        } else if (can_remove) {
+               items.push_back (SeparatorElem());
                items.push_back (MenuElem (_("Lock to Audio"), sigc::mem_fun(*this, &Editor::toggle_marker_lock_style)));
        }
 
+       items.push_back (SeparatorElem());
+
        items.push_back (MenuElem (_("Edit..."), sigc::mem_fun(*this, &Editor::marker_menu_edit)));
        items.push_back (MenuElem (_("Remove"), sigc::mem_fun(*this, &Editor::marker_menu_remove)));
        items.back().set_sensitive (can_remove);
@@ -1505,35 +1504,6 @@ Editor::toggle_tempo_clamped ()
        }
 }
 
-void
-Editor::continue_previous_tempo ()
-{
-       TempoMarker* tm;
-       MeterMarker* mm;
-       dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm);
-
-       if (tm) {
-               TempoMap& tmap (_session->tempo_map());
-               TempoSection* tsp = &tm->tempo();
-               TempoSection* prev_ts = tmap.previous_tempo_section (&tm->tempo());
-               if (prev_ts) {
-                       const Tempo tempo (prev_ts->end_note_types_per_minute(), tsp->note_type(), tsp->end_note_types_per_minute());
-                       const double pulse = tsp->pulse();
-                       const framepos_t frame = tsp->frame();
-                       const PositionLockStyle pls = tsp->position_lock_style();
-
-                       begin_reversible_command (_("continue previous tempo"));
-                       XMLNode &before = _session->tempo_map().get_state();
-
-                       tmap.replace_tempo (*tsp, tempo, pulse, frame, pls);
-
-                       XMLNode &after = _session->tempo_map().get_state();
-                       _session->add_command(new MementoCommand<TempoMap>(_session->tempo_map(), &before, &after));
-                       commit_reversible_command ();
-               }
-       }
-}
-
 void
 Editor::ramp_to_next_tempo ()
 {
index 5e62f3432dd57d780767bed78dd2cb8a76bab843..6ae03cb88008e96341995a4668dfb6fcdc19d5aa 100644 (file)
@@ -607,7 +607,7 @@ private:
        void do_insert (MetricSection* section);
 
        TempoSection* add_tempo_locked (const Tempo&, double pulse, double minute
-                              , PositionLockStyle pls, bool recompute, bool locked_to_meter = false);
+                                       , PositionLockStyle pls, bool recompute, bool locked_to_meter = false, bool clamped = false);
 
        MeterSection* add_meter_locked (const Meter&, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls, bool recompute);
 
index e1b68426493faa903f6cff869d578c51bb2eacb6..570a03f8cbaa6aa3ff2810b14165f83c3c480067 100644 (file)
@@ -1030,7 +1030,8 @@ TempoMap::add_tempo (const Tempo& tempo, const double& pulse, const framepos_t&
        TempoSection* ts = 0;
        {
                Glib::Threads::RWLock::WriterLock lm (lock);
-               ts = add_tempo_locked (tempo, pulse, minute_at_frame (frame), pls, true, false);
+               /* here we default to not clamped for a new tempo section. preference? */
+               ts = add_tempo_locked (tempo, pulse, minute_at_frame (frame), pls, true, false, false);
 
                recompute_map (_metrics);
        }
@@ -1064,11 +1065,11 @@ TempoMap::replace_tempo (TempoSection& ts, const Tempo& tempo, const double& pul
                                }
                        } else {
                                remove_tempo_locked (ts);
-                               new_ts = add_tempo_locked (tempo, pulse, minute_at_frame (frame), pls, true, locked_to_meter);
-                               new_ts->set_clamped (ts_clamped);
-
-                               if (new_ts && new_ts->type() == TempoSection::Constant) {
-                                       new_ts->set_end_note_types_per_minute (new_ts->note_types_per_minute());
+                               new_ts = add_tempo_locked (tempo, pulse, minute_at_frame (frame), pls, true, locked_to_meter, ts_clamped);
+                               /* enforce clampedness of next tempo section */
+                               TempoSection* next_t = next_tempo_section_locked (_metrics, new_ts);
+                               if (next_t && next_t->clamped()) {
+                                       next_t->set_note_types_per_minute (new_ts->end_note_types_per_minute());
                                }
                        }
 
@@ -1091,10 +1092,11 @@ TempoMap::replace_tempo (TempoSection& ts, const Tempo& tempo, const double& pul
 
 TempoSection*
 TempoMap::add_tempo_locked (const Tempo& tempo, double pulse, double minute
-                           , PositionLockStyle pls, bool recompute, bool locked_to_meter)
+                           , PositionLockStyle pls, bool recompute, bool locked_to_meter, bool clamped)
 {
        TempoSection* t = new TempoSection (pulse, minute, tempo, pls, _frame_rate);
        t->set_locked_to_meter (locked_to_meter);
+       t->set_clamped (clamped);
 
        do_insert (t);
 
@@ -1102,11 +1104,7 @@ TempoMap::add_tempo_locked (const Tempo& tempo, double pulse, double minute
        for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
                TempoSection* const this_t = dynamic_cast<TempoSection*>(*i);
                if (this_t) {
-                       bool const ipm = t->position_lock_style() == MusicTime;
-                       bool const lm = t->locked_to_meter();
-
-                       if ((ipm && this_t->pulse() == t->pulse()) || (!ipm && this_t->frame() == t->frame())
-                           || (lm && this_t->pulse() == t->pulse())) {
+                       if (this_t == t) {
                                if (prev_tempo && prev_tempo->type() == TempoSection::Ramp) {
                                        prev_tempo->set_end_note_types_per_minute (t->note_types_per_minute());
                                }
@@ -1190,7 +1188,7 @@ TempoMap::add_meter_locked (const Meter& meter, const BBT_Time& bbt, framepos_t
        if (pls == AudioTime) {
                /* add meter-locked tempo at the natural time in the current map (frame may differ). */
                Tempo const tempo_at_time = tempo_at_minute_locked (_metrics, time_minutes);
-               TempoSection* mlt = add_tempo_locked (tempo_at_time, pulse, time_minutes, AudioTime, true, true);
+               TempoSection* mlt = add_tempo_locked (tempo_at_time, pulse, time_minutes, AudioTime, true, true, false);
 
                if (!mlt) {
                        return 0;
@@ -1406,6 +1404,7 @@ TempoMap::recompute_tempi (Metrics& metrics)
                                        continue;
                                }
                        }
+
                        if (prev_t) {
                                if (t->position_lock_style() == AudioTime) {
                                        prev_t->set_c (prev_t->compute_c_minute (prev_t->end_note_types_per_minute(), t->minute()));
@@ -3370,9 +3369,9 @@ TempoMap::gui_stretch_tempo (TempoSection* ts, const framepos_t frame, const fra
                        return;
                }
 
-               TempoSection* prev_t = copy_metrics_and_point (_metrics, future_map, ts);
+               TempoSection* ts_copy = copy_metrics_and_point (_metrics, future_map, ts);
 
-               if (!prev_t) {
+               if (!ts_copy) {
                        return;
                }
 
@@ -3380,32 +3379,31 @@ TempoMap::gui_stretch_tempo (TempoSection* ts, const framepos_t frame, const fra
                framepos_t const min_dframe = 2;
 
                double new_bpm;
-               if (prev_t->clamped()) {
-                       TempoSection* next_t = next_tempo_section_locked (future_map, prev_t);
-                       TempoSection* prev_to_prev_t = previous_tempo_section_locked (future_map, prev_t);
-                       /* 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;
-                       if (next_t && prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
-                               contribution = (prev_t->pulse() - prev_to_prev_t->pulse()) / (double) (next_t->pulse() - prev_to_prev_t->pulse());
+               if (ts_copy->clamped()) {
+                       TempoSection* next_t = next_tempo_section_locked (future_map, ts_copy);
+                       TempoSection* prev_to_ts_copy = previous_tempo_section_locked (future_map, ts_copy);
+                        /* 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 ts_copy has constant slope.
+                        */                     double contribution = 0.0;
+                       if (next_t && prev_to_ts_copy && prev_to_ts_copy->type() == TempoSection::Ramp) {
+                               contribution = (ts_copy->pulse() - prev_to_ts_copy->pulse()) / (double) (next_t->pulse() - prev_to_ts_copy->pulse());
                        }
                        framepos_t const fr_off = end_frame - frame;
-                       frameoffset_t const prev_t_frame_contribution = fr_off - (contribution * (double) fr_off);
+                       frameoffset_t const ts_copy_frame_contribution = fr_off - (contribution * (double) fr_off);
 
-                       if (frame > prev_to_prev_t->frame() + min_dframe && (frame + prev_t_frame_contribution) > prev_to_prev_t->frame() + min_dframe) {
-                               new_bpm = prev_t->note_types_per_minute() * ((start_qnote - (prev_to_prev_t->pulse() * 4.0))
-                                                                            / (end_qnote - (prev_to_prev_t->pulse() * 4.0)));
+                       if (frame > prev_to_ts_copy->frame() + min_dframe && (frame + ts_copy_frame_contribution) > prev_to_ts_copy->frame() + min_dframe) {
+                               new_bpm = ts_copy->note_types_per_minute() * ((start_qnote - (prev_to_ts_copy->pulse() * 4.0))
+                                                                            / (end_qnote - (prev_to_ts_copy->pulse() * 4.0)));
                        } else {
-                               new_bpm = prev_t->note_types_per_minute();
+                               new_bpm = ts_copy->note_types_per_minute();
                        }
                } else {
-                       if (frame > prev_t->frame() + min_dframe && end_frame > prev_t->frame() + min_dframe) {
+                       if (frame > ts_copy->frame() + min_dframe && end_frame > ts_copy->frame() + min_dframe) {
 
-                               new_bpm = prev_t->note_types_per_minute() * ((frame - prev_t->frame())
-                                                                            / (double) (end_frame - prev_t->frame()));
+                               new_bpm = ts_copy->note_types_per_minute() * ((frame - ts_copy->frame())
+                                                                            / (double) (end_frame - ts_copy->frame()));
                        } else {
-                               new_bpm = prev_t->note_types_per_minute();
+                               new_bpm = ts_copy->note_types_per_minute();
                        }
 
                        new_bpm = min (new_bpm, (double) 1000.0);
@@ -3419,17 +3417,12 @@ TempoMap::gui_stretch_tempo (TempoSection* ts, const framepos_t frame, const fra
                        goto out;
                }
 
-               if (prev_t && prev_t->type() == TempoSection::Ramp) {
-                       prev_t->set_note_types_per_minute (new_bpm);
-               } else {
-                       prev_t->set_end_note_types_per_minute (new_bpm);
-                       prev_t->set_note_types_per_minute (new_bpm);
-               }
+               ts_copy->set_note_types_per_minute (new_bpm);
 
-               if (prev_t->clamped()) {
+               if (ts_copy->clamped()) {
                        TempoSection* prev = 0;
-                       if ((prev = previous_tempo_section_locked (future_map, prev_t)) != 0) {
-                               prev->set_end_note_types_per_minute (prev_t->note_types_per_minute());
+                       if ((prev = previous_tempo_section_locked (future_map, ts_copy)) != 0) {
+                               prev->set_end_note_types_per_minute (ts_copy->note_types_per_minute());
                        }
                }
 
@@ -3437,18 +3430,15 @@ TempoMap::gui_stretch_tempo (TempoSection* ts, const framepos_t frame, const fra
                recompute_meters (future_map);
 
                if (check_solved (future_map)) {
-                       if (prev_t && prev_t->type() == TempoSection::Ramp) {
-                               ts->set_note_types_per_minute (new_bpm);
-                       } else {
-                               ts->set_end_note_types_per_minute (new_bpm);
-                               ts->set_note_types_per_minute (new_bpm);
-                       }
+                       ts->set_note_types_per_minute (new_bpm);
+
                        if (ts->clamped()) {
                                TempoSection* prev = 0;
                                if ((prev = previous_tempo_section_locked (_metrics, ts)) != 0) {
                                        prev->set_end_note_types_per_minute (ts->note_types_per_minute());
                                }
                        }
+
                        recompute_tempi (_metrics);
                        recompute_meters (_metrics);
                }