summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2016-03-26 04:48:29 +1100
committernick_m <mainsbridge@gmail.com>2016-05-27 23:38:12 +1000
commit69b6379b232f7017892b897f4838f273392f4dc2 (patch)
treec08074af385857c564af73dd39eb73d742c812de
parent1be5a427378e511427b2bff2ee0cd6a0709791b9 (diff)
Tempo ramps - pressing constraint modifier keys during tempo drag changes tempo with vertical movement, incorporating beat constraint (if present).
- makes it easy to find suitable accelerandos for hit points in conjunction with playhead position, beat-locked tempos and initial meter frame.
-rw-r--r--gtk2_ardour/editor_drag.cc29
-rw-r--r--gtk2_ardour/editor_drag.h2
-rw-r--r--gtk2_ardour/editor_mouse.cc2
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc3
-rw-r--r--libs/ardour/ardour/tempo.h2
-rw-r--r--libs/ardour/tempo.cc34
6 files changed, 57 insertions, 15 deletions
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index 77c3e3928e..71367d7a62 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -3312,17 +3312,24 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
_marker->hide();
}
- framepos_t const pf = adjusted_current_frame (event, false);
+ framepos_t const pf = adjusted_current_frame (event);
Tempo const tp = _marker->tempo();
_marker->set_position (pf);
- /* just here for a check/laugh
- if (_real_section->position_lock_style() == MusicTime) {
- const double baf = _editor->session()->tempo_map().beat_at_frame (pf);
- _editor->session()->tempo_map().gui_move_tempo_beat (_real_section, tp, baf);
+
+ if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {
+ double new_bpm = tp.beats_per_minute() + ((grab_y() - current_pointer_y()) / 4.0);
+ _real_section->set_beats_per_minute (new_bpm);
+ _editor->session()->tempo_map().gui_change_tempo (_real_section, Tempo (new_bpm, _real_section->note_type()));
} else {
- */
- _editor->session()->tempo_map().gui_move_tempo_frame (_real_section, tp, pf);
- //}
+ /* just here for a check/laugh
+ if (_real_section->position_lock_style() == MusicTime) {
+ const double baf = _editor->session()->tempo_map().beat_at_frame (pf);
+ _editor->session()->tempo_map().gui_move_tempo_beat (_real_section, tp, baf);
+ } else {
+ */
+ _editor->session()->tempo_map().gui_move_tempo_frame (_real_section, tp, pf);
+ //}
+ }
show_verbose_cursor_time (pf);
}
@@ -3362,11 +3369,11 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
} else {
if (_marker->tempo().position_lock_style() == MusicTime) {
- double const pulse = map.predict_tempo_pulse (_real_section, _marker->tempo(), _real_section->frame());
- map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
+ double const pulse = map.predict_tempo_pulse (_real_section, Tempo (_real_section->beats_per_minute(), _real_section->note_type()), _real_section->frame());
+ map.replace_tempo (*_real_section, Tempo (_real_section->beats_per_minute(), _real_section->note_type())
, pulse, _marker->tempo().type());
} else {
- map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
+ map.replace_tempo (*_real_section, Tempo (_real_section->beats_per_minute(), _real_section->note_type())
, _real_section->frame(), _marker->tempo().type());
}
diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h
index 26029299ce..1864514753 100644
--- a/gtk2_ardour/editor_drag.h
+++ b/gtk2_ardour/editor_drag.h
@@ -727,7 +727,7 @@ public:
}
bool y_movement_matters () const {
- return false;
+ return true;
}
void setup_pointer_frame_offset ();
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index a1a7b793b6..49aaac68bf 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -684,7 +684,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
new TempoMarkerDrag (
this,
item,
- Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
+ Keyboard::modifier_state_equals (event->button.state, Keyboard::CopyModifier)
),
event
);
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 02b7027442..b6db6280e4 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -143,6 +143,9 @@ Editor::marker_position_changed ()
if ((tempo_marker = dynamic_cast<TempoMarker*> (*x)) != 0) {
if ((ts = &tempo_marker->tempo()) != 0) {
tempo_marker->set_position (ts->frame ());
+ char buf[64];
+ snprintf (buf, sizeof (buf), "%.2f", ts->beats_per_minute());
+ tempo_marker->set_name (buf);
}
}
if ((meter_marker = dynamic_cast<MeterMarker*> (*x)) != 0) {
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index 780455ff4b..7ee093de64 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -56,6 +56,7 @@ class LIBARDOUR_API Tempo {
: _beats_per_minute (bpm), _note_type(type) {}
double beats_per_minute () const { return _beats_per_minute; }
+ void set_beats_per_minute (double bpm) { _beats_per_minute = bpm; }
double note_type () const { return _note_type; }
double pulses_per_minute () const { return _beats_per_minute / _note_type; }
/** audio samples per beat
@@ -387,6 +388,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
void gui_move_tempo_beat (TempoSection*, const Tempo& bpm, const double& frame);
void gui_move_meter (MeterSection*, const Meter& mt, const framepos_t& frame);
void gui_move_meter (MeterSection*, const Meter& mt, const double& beat);
+ bool gui_change_tempo (TempoSection*, const Tempo& bpm);
bool can_solve_bbt (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt);
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index f2c44b2500..7ae36f41c5 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -1159,6 +1159,34 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat
MetricPositionChanged (); // Emit Signal
}
+bool
+TempoMap::gui_change_tempo (TempoSection* ts, const Tempo& bpm)
+{
+ Metrics future_map;
+ bool can_solve = false;
+ {
+ Glib::Threads::RWLock::WriterLock lm (lock);
+ TempoSection* new_section = copy_metrics_and_point (future_map, ts);
+ new_section->set_beats_per_minute (bpm.beats_per_minute());
+ recompute_tempos (future_map);
+
+ if (check_solved (future_map, true)) {
+ ts->set_beats_per_minute (bpm.beats_per_minute());
+ recompute_map (_metrics);
+ can_solve = true;
+ }
+ }
+
+ Metrics::const_iterator d = future_map.begin();
+ while (d != future_map.end()) {
+ delete (*d);
+ ++d;
+ }
+ if (can_solve) {
+ MetricPositionChanged (); // Emit Signal
+ }
+ return can_solve;
+}
TempoSection*
TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
{
@@ -1949,6 +1977,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
MetricSectionSorter cmp;
section->set_frame (frame);
+
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
@@ -1970,7 +1999,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
}
if (section_prev) {
- section_prev->set_c_func (section_prev->compute_c_func_pulse (section->pulses_per_minute(), section->pulse(), _frame_rate));
+ section_prev->set_c_func (section_prev->compute_c_func_frame (bpm.pulses_per_minute(), frame, _frame_rate));
section->set_pulse (section_prev->pulse_at_frame (frame, _frame_rate));
}
@@ -2029,6 +2058,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
TempoSection* section_prev = 0;
section->set_pulse (pulse);
+ section->set_beats_per_minute (bpm.beats_per_minute());
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
TempoSection* t;
@@ -2050,7 +2080,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
}
}
if (section_prev) {
- section_prev->set_c_func (section_prev->compute_c_func_pulse (section->pulses_per_minute(), pulse, _frame_rate));
+ section_prev->set_c_func (section_prev->compute_c_func_pulse (bpm.pulses_per_minute(), pulse, _frame_rate));
section->set_frame (section_prev->frame_at_pulse (pulse, _frame_rate));
}