diff options
author | nick_m <mainsbridge@gmail.com> | 2017-01-27 00:41:17 +1100 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2017-02-04 22:57:36 +1100 |
commit | 59daffea1d78cb55b35fe19c135cc4ab472bd01d (patch) | |
tree | 45e514f2e4f5a1935e360fd4fa3e2475ec217006 /libs/ardour/tempo.cc | |
parent | a21a414615505269bf770ad2358482e698e841af (diff) |
rework snap
snap now fills in a struct (MusicFrame) which contins a snapped frame
along with a music divisor.
this gives useful information wrt magnetic snap which may or may not
have rounded to an exact musical position.
region position may now be set musically (using quarter notes for now).
this patch fixes several problems in the current code:
- dragging a list of music-locked regions now maintains correct
musical offsets within the list.
- splitting regions using magnetic snap works correctly (#7192)
- cut drag should now work correctly with magnetic snap.
- musical length of split midi regions is no longer frame based.
Diffstat (limited to 'libs/ardour/tempo.cc')
-rw-r--r-- | libs/ardour/tempo.cc | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 469bbac4de..d690896c15 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -3676,13 +3676,13 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir) return 0; } -framepos_t +MusicFrame TempoMap::round_to_bar (framepos_t fr, RoundMode dir) { return round_to_type (fr, dir, Bar); } -framepos_t +MusicFrame TempoMap::round_to_beat (framepos_t fr, RoundMode dir) { return round_to_type (fr, dir, Beat); @@ -3784,7 +3784,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir) return ret_frame; } -framepos_t +MusicFrame TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMode dir) { Glib::Threads::RWLock::ReaderLock lm (lock); @@ -3865,7 +3865,7 @@ TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMo if (rem > ticks) { if (beats == 0) { /* can't go backwards past zero, so ... */ - return 0; + return MusicFrame (0, 0); } /* step back to previous beat */ --beats; @@ -3880,35 +3880,46 @@ TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMo } } - const framepos_t ret_frame = frame_at_minute (minute_at_pulse_locked (_metrics, (beats + (ticks / BBT_Time::ticks_per_beat)) / 4.0)); + MusicFrame ret (0, 0); + ret.frame = frame_at_minute (minute_at_pulse_locked (_metrics, (beats + (ticks / BBT_Time::ticks_per_beat)) / 4.0)); + ret.division = sub_num; - return ret_frame; + return ret; } -framepos_t +MusicFrame TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) { Glib::Threads::RWLock::ReaderLock lm (lock); - - const double beat_at_framepos = max (0.0, beat_at_minute_locked (_metrics, minute_at_frame (frame))); + const double minute = minute_at_frame (frame); + const double beat_at_framepos = max (0.0, beat_at_minute_locked (_metrics, minute)); BBT_Time bbt (bbt_at_beat_locked (_metrics, beat_at_framepos)); + MusicFrame ret (0, 0); switch (type) { case Bar: + ret.division = -1; + if (dir < 0) { /* find bar previous to 'frame' */ if (bbt.bars > 0) --bbt.bars; bbt.beats = 1; bbt.ticks = 0; - return frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); + + ret.frame = frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); + + return ret; } else if (dir > 0) { /* find bar following 'frame' */ ++bbt.bars; bbt.beats = 1; bbt.ticks = 0; - return frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); + + ret.frame = frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); + + return ret; } else { /* true rounding: find nearest bar */ framepos_t raw_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); @@ -3919,26 +3930,39 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type) framepos_t next_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt)); if ((raw_ft - prev_ft) > (next_ft - prev_ft) / 2) { - return next_ft; + ret.frame = next_ft; + + return ret; } else { - return prev_ft; + --bbt.bars; + ret.frame = prev_ft; + + return ret; } } break; case Beat: + ret.division = 1; + if (dir < 0) { - return frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos))); + ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos))); + + return ret; } else if (dir > 0) { - return frame_at_minute (minute_at_beat_locked (_metrics, ceil (beat_at_framepos))); + ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, ceil (beat_at_framepos))); + + return ret; } else { - return frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos + 0.5))); + ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos + 0.5))); + + return ret; } break; } - return 0; + return MusicFrame (0, 0); } void |