summaryrefslogtreecommitdiff
path: root/libs/ardour/tempo.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-08-27 03:09:30 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-08-27 03:09:30 +0000
commit3845af6ce92ef15637ffb09410f442e7b4a104c3 (patch)
tree218a29f23c83c3ac57c857d3b1f599f1e6d97a14 /libs/ardour/tempo.cc
parentc6be9b688802198e04a07dc902c49d1d6b66340e (diff)
lots of MIDI editing stuff. to be explained on the website when its done
git-svn-id: svn://localhost/ardour2/branches/3.0@5596 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/tempo.cc')
-rw-r--r--libs/ardour/tempo.cc98
1 files changed, 82 insertions, 16 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 3056016752..a2307901bc 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -1099,30 +1099,91 @@ TempoMap::round_to_beat (nframes_t fr, int dir)
}
nframes_t
-
-TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num)
+TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num, int dir)
{
BBT_Time the_beat;
uint32_t ticks_one_half_subdivisions_worth;
uint32_t ticks_one_subdivisions_worth;
+ uint32_t difference;
bbt_time(fr, the_beat);
ticks_one_subdivisions_worth = (uint32_t)Meter::ticks_per_beat / sub_num;
ticks_one_half_subdivisions_worth = ticks_one_subdivisions_worth / 2;
+
+ if (dir > 0) {
+
+ /* round to next */
- if (the_beat.ticks % ticks_one_subdivisions_worth > ticks_one_half_subdivisions_worth) {
- uint32_t difference = ticks_one_subdivisions_worth - (the_beat.ticks % ticks_one_subdivisions_worth);
- if (the_beat.ticks + difference >= (uint32_t)Meter::ticks_per_beat) {
- the_beat.beats++;
- the_beat.ticks += difference;
- the_beat.ticks -= (uint32_t)Meter::ticks_per_beat;
- } else {
- the_beat.ticks += difference;
- }
- } else {
- the_beat.ticks -= the_beat.ticks % ticks_one_subdivisions_worth;
+ uint32_t mod = the_beat.ticks % ticks_one_subdivisions_worth;
+
+ if (mod == 0) {
+ /* right on the subdivision, so the difference is just the subdivision ticks */
+ difference = ticks_one_subdivisions_worth;
+
+ } else {
+ /* not on subdivision, compute distance to next subdivision */
+
+ difference = ticks_one_subdivisions_worth - mod;
+ }
+
+ if (the_beat.ticks + difference >= (uint32_t)Meter::ticks_per_beat) {
+ the_beat.beats++;
+ the_beat.ticks += difference;
+ the_beat.ticks -= (uint32_t)Meter::ticks_per_beat;
+ } else {
+ the_beat.ticks += difference;
+ }
+
+ } else if (dir < 0) {
+
+ /* round to previous */
+
+ uint32_t mod = the_beat.ticks % ticks_one_subdivisions_worth;
+
+ if (mod == 0) {
+ /* right on the subdivision, so the difference is just the subdivision ticks */
+ difference = ticks_one_subdivisions_worth;
+ cerr << "On the sub, move by 1 sub = " << difference << endl;
+ } else {
+ /* not on subdivision, compute distance to previous subdivision, which
+ is just the modulus.
+ */
+
+ difference = mod;
+ cerr << "off the sub, move by 1 sub = " << difference << endl;
+ }
+
+
+ cerr << "ticks = " << the_beat.ticks << endl;
+
+ if (the_beat.ticks < difference) {
+ cerr << "backup beats, set ticks to "
+ << (uint32_t)Meter::ticks_per_beat - difference << endl;
+ the_beat.beats--;
+ the_beat.ticks = (uint32_t)Meter::ticks_per_beat - difference;
+ } else {
+ cerr << " reduce ticks\n";
+ the_beat.ticks -= difference;
+ }
+
+ } else {
+ /* round to nearest */
+
+ if (the_beat.ticks % ticks_one_subdivisions_worth > ticks_one_half_subdivisions_worth) {
+ difference = ticks_one_subdivisions_worth - (the_beat.ticks % ticks_one_subdivisions_worth);
+ if (the_beat.ticks + difference >= (uint32_t)Meter::ticks_per_beat) {
+ the_beat.beats++;
+ the_beat.ticks += difference;
+ the_beat.ticks -= (uint32_t)Meter::ticks_per_beat;
+ } else {
+ the_beat.ticks += difference;
+ }
+ } else {
+ // difference = ticks_one_subdivisions_worth - (the_beat.ticks % ticks_one_subdivisions_worth);
+ the_beat.ticks -= the_beat.ticks % ticks_one_subdivisions_worth;
+ }
}
return frame_time (the_beat);
@@ -1139,7 +1200,9 @@ TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type)
switch (type) {
case Bar:
if (dir < 0) {
- /* relax */
+ if (bbt.bars > 1) {
+ bbt.bars--;
+ }
} else if (dir > 0) {
if (bbt.beats > 0) {
bbt.bars++;
@@ -1157,7 +1220,9 @@ TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type)
case Beat:
if (dir < 0) {
- /* relax */
+ if (bbt.beats > 1) {
+ bbt.beats--;
+ }
} else if (dir > 0) {
if (bbt.ticks > 0) {
bbt.beats++;
@@ -1178,11 +1243,12 @@ TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type)
}
- /*
+ /*
cerr << "for " << frame << " round to " << bbt << " using "
<< metric.start()
<< endl;
*/
+
return metric.frame() + count_frames_between (metric.start(), bbt);
}