diff options
-rw-r--r-- | gtk2_ardour/editor.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 34 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_tempodisplay.cc | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 3 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 148 |
6 files changed, 58 insertions, 133 deletions
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 6057326ab3..0fd9fccec1 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -2254,6 +2254,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD friend class RegionSpliceDrag; friend class RegionRippleDrag; friend class TrimDrag; + friend class BBTRulerDrag; friend class MeterMarkerDrag; friend class TempoMarkerDrag; friend class CursorDrag; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 4ccb1c0ba5..3533eb8163 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3478,32 +3478,47 @@ TempoMarkerDrag::aborted (bool moved) BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i) + , _pulse (0.0) + , _beat (0.0) , _tempo (0) , before_state (0) { DEBUG_TRACE (DEBUG::Drags, "New BBTRulerDrag\n"); + } void BBTRulerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) { Drag::start_grab (event, cursor); + 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()); - _tempo = const_cast<TempoSection*> (&map.tempo_section_at (adjusted_current_frame (event, false))); - if (!_tempo) { - Drag::abort(); - } + _tempo = const_cast<TempoSection*> (&map.tempo_section_at (raw_grab_frame())); + sstr << "^" << fixed << setprecision(3) << map.tempo_at (adjusted_current_frame (event)).beats_per_minute() << "\n"; + sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute(); + show_verbose_cursor_text (sstr.str()); + finished (event, false); } void BBTRulerDrag::setup_pointer_frame_offset () { TempoMap& map (_editor->session()->tempo_map()); - _pointer_frame_offset = raw_grab_frame() - map.frame_at_beat (floor (map.beat_at_frame (raw_grab_frame()))); + const double beat_at_frame = map.beat_at_frame (raw_grab_frame()); + const uint32_t divisions = _editor->get_grid_beat_divisions (0); + if (divisions > 0) { + _beat = floor (beat_at_frame) + (floor (((beat_at_frame - floor (beat_at_frame)) * divisions)) / divisions); + } else { + /* while it makes some sense for the user to determine the division to 'grab', + grabbing a bar often leads to confusing results wrt the actual tempo section being altered + and the result over steep tempo curves. Use sixteenths. + */ + _beat = floor (beat_at_frame) + (floor (((beat_at_frame - floor (beat_at_frame)) * 4)) / 4); + } + _pulse = map.pulse_at_beat (_beat); + _pointer_frame_offset = raw_grab_frame() - map.frame_at_beat (_beat); } void @@ -3521,10 +3536,11 @@ BBTRulerDrag::motion (GdkEvent* event, bool first_move) if (Keyboard::modifier_state_contains (event->button.state, ArdourKeyboard::constraint_modifier())) { /* adjust previous tempo to match pointer frame */ - _editor->session()->tempo_map().gui_dilate_tempo (_tempo, last_pointer_frame(), pf); + _editor->session()->tempo_map().gui_dilate_tempo (_tempo, map.frame_at_pulse (_pulse), pf, _pulse); } ostringstream sstr; - sstr << fixed << setprecision(3) << map.tempo_at (pf).beats_per_minute(); + sstr << "^" << fixed << setprecision(3) << map.tempo_at (pf).beats_per_minute() << "\n"; + sstr << "<" << fixed << setprecision(3) << _tempo->beats_per_minute(); show_verbose_cursor_text (sstr.str()); } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index f75c9a681d..abec31a00b 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -764,6 +764,8 @@ public: void setup_pointer_frame_offset (); private: + double _pulse; + double _beat; ARDOUR::TempoSection* _tempo; XMLNode* before_state; }; diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 0b133e3051..435ee90a21 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -244,7 +244,8 @@ Editor::compute_current_bbt_points (std::vector<TempoMap::BBTPoint>& grid, frame /* prevent negative values of leftmost from creeping into tempomap */ - _session->tempo_map().get_grid (grid, max (leftmost, (framepos_t) 0), rightmost); + const double lower_beat = floor (_session->tempo_map().beat_at_frame (leftmost)); + _session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost); } void diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 81fad2e0fc..9274758958 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -398,9 +398,8 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void gui_move_meter (MeterSection*, const framepos_t& frame); void gui_move_meter (MeterSection*, const Timecode::BBT_Time& bbt); bool gui_change_tempo (TempoSection*, const Tempo& bpm); - void gui_dilate_next_tempo (const framepos_t& frame, const framepos_t& end_frame); void gui_dilate_tempo (MeterSection*, const framepos_t& frame); - void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame); + void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame, const double& pulse); bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt); diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index e3d25948de..b4982ebe2b 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -2783,118 +2783,16 @@ TempoMap::gui_dilate_tempo (MeterSection* ms, const framepos_t& frame) } void -TempoMap::gui_dilate_next_tempo (const framepos_t& frame, const framepos_t& end_frame) -{ - Metrics future_map; - TempoSection* ts = 0; - - { - Glib::Threads::RWLock::WriterLock lm (lock); - - for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) { - TempoSection* t = 0; - if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { - if (t->frame() > end_frame) { - ts = t; - break; - } - } - } - - if (!ts) { - ts = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, frame - 1)); - } - - TempoSection* next_t = copy_metrics_and_point (_metrics, future_map, ts); - TempoSection* prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (future_map, next_t->frame() - 1)); - TempoSection* prev_to_prev_t = 0; - const frameoffset_t fr_off = end_frame - frame; - - 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)); - } - - - /* 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 (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) { - contribution = prev_t->beats_per_minute() / (prev_t->beats_per_minute() + next_t->beats_per_minute()); - } - - frameoffset_t prev_t_frame_contribution = fr_off; - - 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); - 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())); - - } else { - /* prev to prev is irrelevant */ - - 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(); - } - } - } else { - /* 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())); - } else { - /* prev_to_prev_t is irrelevant */ - - if (end_frame != prev_t->frame()) { - new_bpm = prev_t->beats_per_minute() * ((frame - prev_t->frame()) / (double) (end_frame - prev_t->frame())); - } else { - new_bpm = prev_t->beats_per_minute(); - } - } - } - } else { - const double end_minute = ((next_t->frame() + prev_t_frame_contribution - prev_t->frame()) / (double) _frame_rate) / 60.0; - const double pulse_delta_at_next = prev_t->pulse_at_frame ((next_t->frame()) + prev_t_frame_contribution, _frame_rate) - next_t->pulse(); - const double target_pulse = (next_t->pulse() - prev_t->pulse()) + (pulse_delta_at_next); - - new_bpm = (prev_t->tempo_at_frame (next_t->frame() - prev_t_frame_contribution, _frame_rate)) * (double) prev_t->note_type(); - - } - - next_t->set_beats_per_minute (new_bpm); - recompute_tempos (future_map); - recompute_meters (future_map); - - if (check_solved (future_map, true)) { - ts->set_beats_per_minute (new_bpm); - recompute_tempos (_metrics); - recompute_meters (_metrics); - } - } - - Metrics::const_iterator d = future_map.begin(); - while (d != future_map.end()) { - delete (*d); - ++d; - } - - MetricPositionChanged (); // Emit Signal -} +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) + */ -void -TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const framepos_t& end_frame) -{ Metrics future_map; { @@ -2926,22 +2824,23 @@ TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const fra 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 (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 prev_t_frame_contribution = fr_off - (contribution * (double) fr_off); - 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); + 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 */ @@ -2968,14 +2867,21 @@ TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const fra } } } else { - const frameoffset_t halfway = ((next_t->frame() + prev_t->frame()) / 2.0); - const frameoffset_t halfway_off = halfway + prev_t_frame_contribution; - const double halfway_pulse = prev_t->pulse_at_frame (halfway, _frame_rate); - const double halfway_off_minute = ((halfway_off - prev_t->frame()) / (double) _frame_rate) / 60.0; - new_bpm = (((halfway_pulse - prev_t->pulse()) * prev_t->c_func()) - / (exp (halfway_off_minute * prev_t->c_func()) - 1.0)) * (double) prev_t->note_type(); + double frame_ratio; + double pulse_ratio; + const framepos_t pulse_pos = prev_t->frame_at_pulse (pulse, _frame_rate); + + if (prev_to_prev_t) { + 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()) / (double) (end_pulse - prev_to_prev_t->pulse())); + } else { + + frame_ratio = (((pulse_pos - fr_off) - prev_t->frame()) / (double) ((pulse_pos) - prev_t->frame())); + pulse_ratio = ((start_pulse) / (double) (end_pulse)); + } + new_bpm = prev_t->beats_per_minute() * (pulse_ratio * frame_ratio); } prev_t->set_beats_per_minute (new_bpm); |