Tempo ramps - tempos now musically snap to their future.

This commit is contained in:
nick_m 2016-03-29 02:23:29 +11:00
parent 59df9880a4
commit daa07ce6e0
6 changed files with 92 additions and 3 deletions

View File

@ -2136,6 +2136,32 @@ Editor::snap_type() const
return _snap_type;
}
bool
Editor::snap_musical() const
{
switch (_snap_type) {
case SnapToBeatDiv128:
case SnapToBeatDiv64:
case SnapToBeatDiv32:
case SnapToBeatDiv28:
case SnapToBeatDiv24:
case SnapToBeatDiv20:
case SnapToBeatDiv16:
case SnapToBeatDiv14:
case SnapToBeatDiv12:
case SnapToBeatDiv10:
case SnapToBeatDiv8:
case SnapToBeatDiv7:
case SnapToBeatDiv6:
case SnapToBeatDiv5:
case SnapToBeatDiv4:
case SnapToBeatDiv3:
case SnapToBeatDiv2:
return true;
}
return false;
}
SnapMode
Editor::snap_mode() const
{

View File

@ -171,6 +171,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Editing::SnapMode snap_mode () const;
Editing::SnapType snap_type () const;
bool snap_musical () const;
void undo (uint32_t n = 1);
void redo (uint32_t n = 1);

View File

@ -3316,7 +3316,20 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
_marker->hide();
}
framepos_t const pf = adjusted_current_frame (event);
framepos_t pf;
if (!_editor->snap_musical()) {
pf = adjusted_current_frame (event);
} else {
pf = adjusted_current_frame (event);
Timecode::BBT_Time when;
_editor->session()->tempo_map().bbt_time (pf, when);
if (_editor->snap_type() == SnapToBar) {
_editor->session()->tempo_map().round_bbt (when, -1);
} else {
_editor->session()->tempo_map().round_bbt (when, _editor->get_grid_beat_divisions (0));
}
pf = _editor->session()->tempo_map().predict_tempo_frame (_real_section, Tempo (_real_section->beats_per_minute(), _real_section->note_type()), when);
}
Tempo const tp = _marker->tempo();
if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {

View File

@ -59,7 +59,6 @@ TempoLines::draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
framecnt_t leftmost_frame,
framecnt_t frame_rate)
{
const double fpb = grid.begin()->tempo.frames_per_beat(frame_rate);
const uint32_t base = UIConfiguration::instance().color_mod("measure line beat", "measure line beat");
for (unsigned l = 1; l < divisions; ++l) {
@ -82,7 +81,8 @@ TempoLines::draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
grid.begin()->tempo.pulses_per_minute()) + 1) / grid.begin()->c;
f = grid.begin()->frame + (framecnt_t) floor ((time_at_pulse * 60.0 * frame_rate) + 0.5);
} else {
f = grid.begin()->frame + (l * (fpb / (double)divisions));
const double fpb = grid.begin()->tempo.frames_per_beat (frame_rate);
f = grid.begin()->frame + (l * (fpb / (double) divisions));
}
if (f > leftmost_frame) {

View File

@ -403,6 +403,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
framepos_t round_to_bar (framepos_t frame, RoundMode dir);
framepos_t round_to_beat (framepos_t frame, RoundMode dir);
framepos_t round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir);
void round_bbt (Timecode::BBT_Time& when, const int32_t& snap_divisor);
void set_length (framepos_t frames);

View File

@ -2479,6 +2479,54 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir)
return ret_frame;
}
void
TempoMap::round_bbt (BBT_Time& when, const int32_t& sub_num)
{
if (sub_num == -1) {
const double bpb = meter_at (bbt_to_beats_locked (_metrics, when)).note_divisor();
if ((double) when.beats > bpb / 2.0) {
++when.bars;
}
when.beats = 1;
when.ticks = 0;
return;
} else if (sub_num == 0) {
if (when.ticks > BBT_Time::ticks_per_beat / 2) {
++when.beats;
when.ticks = 0;
} else {
when.ticks = 0;
}
return;
}
const uint32_t ticks_one_subdivisions_worth = BBT_Time::ticks_per_beat / sub_num;
double rem;
if ((rem = fmod ((double) when.ticks, (double) ticks_one_subdivisions_worth)) > (ticks_one_subdivisions_worth / 2.0)) {
/* closer to the next subdivision, so shift forward */
when.ticks = when.ticks + (ticks_one_subdivisions_worth - rem);
if (when.ticks > Timecode::BBT_Time::ticks_per_beat) {
++when.beats;
when.ticks -= Timecode::BBT_Time::ticks_per_beat;
}
} else if (rem > 0) {
/* closer to previous subdivision, so shift backward */
if (rem > when.ticks) {
if (when.beats == 0) {
/* can't go backwards past zero, so ... */
}
/* step back to previous beat */
--when.beats;
when.ticks = Timecode::BBT_Time::ticks_per_beat - rem;
} else {
when.ticks = when.ticks - rem;
}
}
}
framepos_t
TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
{