summaryrefslogtreecommitdiff
path: root/libs/ardour/tempo.cc
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2017-01-27 00:41:17 +1100
committernick_m <mainsbridge@gmail.com>2017-02-04 22:57:36 +1100
commit59daffea1d78cb55b35fe19c135cc4ab472bd01d (patch)
tree45e514f2e4f5a1935e360fd4fa3e2475ec217006 /libs/ardour/tempo.cc
parenta21a414615505269bf770ad2358482e698e841af (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.cc58
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