libtemporal: redesign TempoMap::get_grid() to iterate over _points rather than separated _tempos and _meters
This commit is contained in:
parent
8124bec5a1
commit
c2401c3097
|
@ -1661,55 +1661,16 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
{
|
{
|
||||||
assert (!_tempos.empty());
|
assert (!_tempos.empty());
|
||||||
assert (!_meters.empty());
|
assert (!_meters.empty());
|
||||||
|
assert (!_points.empty());
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose (">>> GRID START %1 .. %2 (barmod = %3)\n", start, end, bar_mod));
|
DEBUG_TRACE (DEBUG::Grid, string_compose (">>> GRID START %1 .. %2 (barmod = %3)\n", start, end, bar_mod));
|
||||||
|
|
||||||
Tempos::iterator t (_tempos.begin());
|
TempoPoint* tp = 0;
|
||||||
Meters::iterator m (_meters.begin());
|
MeterPoint* mp = 0;
|
||||||
MusicTimes::iterator b (_bartimes.begin());
|
Points::iterator p;
|
||||||
|
|
||||||
TempoMetric metric = metric_at (start, false);
|
/* initial values required, but will be reset before we begin */
|
||||||
BBT_Time bbt = metric.bbt_at (start);
|
TempoMetric metric (_tempos.front(), _meters.front());
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("start %1 is %2\n", start, bbt));
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/* Sanity Check */
|
|
||||||
|
|
||||||
if (DEBUG_ENABLED(PBD::DEBUG::Grid)) {
|
|
||||||
TempoMetric emetric = metric_at (end, false);
|
|
||||||
BBT_Time ebbt = metric_at (end).bbt_at (end);
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("get grid between %1..%2 [ %4 .. %5 ] { %6 .. %7 } at bar_mod = %3\n",
|
|
||||||
start, end, bar_mod, start, end, bbt, ebbt));
|
|
||||||
|
|
||||||
if (metric.quarters_at (bbt).diff (metric.quarters_at_superclock (start)) > Beats::ticks (1)) {
|
|
||||||
cerr << "MM1: " << start << " / " << metric.quarters_at_superclock (start) << " vs. "
|
|
||||||
<< metric.superclock_at (bbt) << " / " << metric.quarters_at (bbt)
|
|
||||||
<< " delta "
|
|
||||||
<< start - metric.superclock_at (bbt)
|
|
||||||
<< " dB "
|
|
||||||
<< metric.quarters_at (bbt).diff (metric.quarters_at_superclock (start))
|
|
||||||
<< "\n\tused " << metric
|
|
||||||
<< endl;
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (emetric.quarters_at (ebbt).diff (emetric.quarters_at_superclock (end)) > Beats::ticks (1)) {
|
|
||||||
cerr << "MM2: " << end << " / " << emetric.quarters_at_superclock (end) << " vs. "
|
|
||||||
<< emetric.superclock_at (ebbt) << " / " << emetric.quarters_at (ebbt)
|
|
||||||
<< " delta "
|
|
||||||
<< end - emetric.superclock_at (ebbt)
|
|
||||||
<< " dB "
|
|
||||||
<< emetric.quarters_at (ebbt).diff (emetric.quarters_at_superclock (end))
|
|
||||||
<< "\n\tused " << emetric
|
|
||||||
<< endl;
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// dump (cerr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* first task: get to the right starting point for the requested
|
/* first task: get to the right starting point for the requested
|
||||||
* grid. if bar_mod is zero, then we'll start on the next beat after
|
* grid. if bar_mod is zero, then we'll start on the next beat after
|
||||||
|
@ -1718,6 +1679,38 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
* grid, depending on whether or not it is a multiple of bar_mod.
|
* grid, depending on whether or not it is a multiple of bar_mod.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
for (tp = &_tempos.front(), mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->sclock() < start; ++p) {
|
||||||
|
|
||||||
|
TempoPoint* tpp;
|
||||||
|
MeterPoint* mpp;
|
||||||
|
|
||||||
|
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||||
|
tp = tpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||||
|
mp = mpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset metric */
|
||||||
|
|
||||||
|
metric = TempoMetric (*tp, *mp);
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("metric in effect at %1 = %2\n", start, metric));
|
||||||
|
|
||||||
|
/* p now points to either the point *after* start, or the end of the
|
||||||
|
* _points list.
|
||||||
|
*
|
||||||
|
* metric is the TempoMetric that is in effect at start
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* determine the BBT at start */
|
||||||
|
|
||||||
|
BBT_Time bbt = metric.bbt_at (start);
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("start %1 is %2\n", start, bbt));
|
||||||
|
|
||||||
if (bar_mod == 0) {
|
if (bar_mod == 0) {
|
||||||
|
|
||||||
/* round to next beat, then find the tempo/meter/bartime points
|
/* round to next beat, then find the tempo/meter/bartime points
|
||||||
|
@ -1734,15 +1727,24 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("new bbt for start (rounded up) = %1\n", bbt));
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("new bbt for start (rounded up) = %1\n", bbt));
|
||||||
|
|
||||||
for (Tempos::iterator tt = _tempos.begin(); tt != _tempos.end() && tt->sclock() < start; ++tt) { t = tt; }
|
for (tp = &_tempos.front(), mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->sclock() < start; ++p) {
|
||||||
for (Meters::iterator mm = _meters.begin(); mm != _meters.end() && mm->sclock() < start; ++mm) { m = mm; }
|
|
||||||
for (MusicTimes::iterator bb = _bartimes.begin(); bb != _bartimes.end() && bb->sclock() < start; ++bb) { b = bb; }
|
TempoPoint* tpp;
|
||||||
|
MeterPoint* mpp;
|
||||||
|
|
||||||
|
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||||
|
tp = tpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||||
|
mp = mpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* reset metric */
|
/* reset metric */
|
||||||
|
|
||||||
metric = TempoMetric (*t, *m);
|
metric = TempoMetric (*tp, *mp);
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("metric in effect at %1 = %2\n", start, metric));
|
|
||||||
|
|
||||||
/* recompute superclock position */
|
/* recompute superclock position */
|
||||||
|
|
||||||
|
@ -1762,32 +1764,46 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* this rounding cannot change the meter in effect, because it
|
|
||||||
remains within the bar. But it could change the tempo (which
|
|
||||||
are only quantized to grid positions within a bar).
|
|
||||||
*/
|
|
||||||
|
|
||||||
BBT_Time bar = bbt.round_down_to_bar ();
|
BBT_Time bar = bbt.round_down_to_bar ();
|
||||||
|
|
||||||
|
/* adjust to match bar_mod (i.e. we only want every 4th bar)
|
||||||
|
*/
|
||||||
|
|
||||||
if (bar_mod != 1) {
|
if (bar_mod != 1) {
|
||||||
bar.bars -= bar.bars % bar_mod;
|
bar.bars -= bar.bars % bar_mod;
|
||||||
++bar.bars;
|
++bar.bars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the rounding we've just done cannot change the meter in
|
||||||
|
effect, because it remains within the bar. But it could
|
||||||
|
change the tempo (which are only quantized to grid positions
|
||||||
|
within a bar). So if it has generated a new BBT time,
|
||||||
|
recompute the metric.
|
||||||
|
*/
|
||||||
|
|
||||||
if (bar != bbt) {
|
if (bar != bbt) {
|
||||||
|
|
||||||
bbt = bar;
|
bbt = bar;
|
||||||
|
|
||||||
for (Tempos::iterator tt = _tempos.begin(); tt != _tempos.end() && tt->bbt() < bbt; ++tt) { t = tt; }
|
for (tp = &_tempos.front(), mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->sclock() < start; ++p) {
|
||||||
for (Meters::iterator mm = _meters.begin(); mm != _meters.end() && mm->bbt() < bbt; ++mm) { m = mm; }
|
|
||||||
for (MusicTimes::iterator bb = _bartimes.begin(); bb != _bartimes.end() && bb->bbt() < bbt; ++bb) { b = bb; }
|
|
||||||
|
|
||||||
/* t, m and b are now all iterators for the tempo, meter and
|
TempoPoint* tpp;
|
||||||
* position markers BEFORE pos. b may be _bartimes.end(), but
|
MeterPoint* mpp;
|
||||||
* the other two are guaranteed to be valid references into
|
|
||||||
* the tempos and meters
|
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||||
*/
|
tp = tpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||||
|
mp = mpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset metric */
|
||||||
|
|
||||||
|
metric = TempoMetric (*tp, *mp);
|
||||||
|
|
||||||
metric = TempoMetric (*t, *m);
|
|
||||||
start = metric.superclock_at (bbt);
|
start = metric.superclock_at (bbt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1795,128 +1811,38 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance t, m and b so that the point to the *next*
|
|
||||||
* tempo/meter/position marker (if any)
|
|
||||||
*/
|
|
||||||
|
|
||||||
Tempos::iterator nxt_t = t; ++nxt_t;
|
|
||||||
Meters::iterator nxt_m = m; ++nxt_m;
|
|
||||||
MusicTimes::iterator nxt_b = b; ++nxt_b;
|
|
||||||
|
|
||||||
/* at this point:
|
/* at this point:
|
||||||
*
|
*
|
||||||
* - metric is a TempoMetric that describes the situation at pos
|
* - metric is a TempoMetric that describes the situation at start
|
||||||
* - t, m and b reference tempo, meter and position markers at or prior to pos (if any)
|
* - p is an iterator pointin to either the end of the _points list, or
|
||||||
* - nxt_t, nxt_m, nxt_b reference the tempo, meter and position markers after pos (if any)
|
* the next point in the list after start.
|
||||||
*
|
|
||||||
* t and m must be valid; b, nxt_t, nxt_m, nxt_b may all refer to ::end() of their respective containers.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* outer loop: compute next marker position, if any, and then set limit to the earlier of that position or @param e.
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("start filling points with start = %1 end = %2 with limit @ %3\n", start, end, *p));
|
||||||
* Then run the inner loop to actually add grid points up until limit. Repeat till done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("start filling points with start = %1 end = %2\n", start, end));
|
|
||||||
|
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
|
|
||||||
bool advance_tempo = false;
|
Temporal::Beats beats = metric.quarters_at_superclock (start);
|
||||||
bool advance_meter = false;
|
|
||||||
bool advance_bartime = false;
|
|
||||||
Point* first_of_three = 0;
|
|
||||||
superclock_t limit = INT64_MAX;
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("start %5 end %6 bbt %7 find first/limit with limit = %1 next_t %2 next_m %3 next_b %4\n",
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("start %1 end %2 bbt %3 find first/limit with limit @ = %4\n", start, end, bbt, *p));
|
||||||
limit,
|
|
||||||
(nxt_t != _tempos.end() ? nxt_t->sclock() : -1),
|
|
||||||
(nxt_m != _meters.end() ? nxt_m->sclock() : -1),
|
|
||||||
(nxt_b != _bartimes.end() ? nxt_b->sclock() : -1),
|
|
||||||
start, end, bbt));
|
|
||||||
|
|
||||||
if (nxt_t != _tempos.end() && limit >= nxt_t->sclock()) {
|
while (start < p->sclock() && start < end) {
|
||||||
first_of_three = &*nxt_t;
|
|
||||||
limit = first_of_three->sclock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_m != _meters.end() && limit >= nxt_m->sclock()) {
|
/* add point to grid, perhaps */
|
||||||
first_of_three = &*nxt_m;
|
|
||||||
limit = first_of_three->sclock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_b != _bartimes.end() && limit >= nxt_b->sclock()) {
|
if ((bar_mod != 0) && bbt.is_bar() && (bbt.bars % bar_mod != 0)) {
|
||||||
first_of_three = &*nxt_b;
|
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
||||||
limit = first_of_three->sclock();
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("after checking fo3 = %1\n", (first_of_three ? first_of_three->sclock() : -1)));
|
|
||||||
|
|
||||||
if (first_of_three) {
|
|
||||||
if (nxt_m != _meters.end() && nxt_m->sclock() == first_of_three->sclock()) {
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, "will advance to next meter\n");
|
|
||||||
advance_meter = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_t != _tempos.end() && nxt_t->sclock() == first_of_three->sclock()) {
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, "will advance to next tempo\n");
|
|
||||||
advance_tempo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((nxt_b != _bartimes.end()) && (nxt_b->sclock() == first_of_three->sclock())) {
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, "will advance to next bartime\n");
|
|
||||||
advance_bartime = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
limit = std::min (end, first_of_three->sclock());
|
|
||||||
} else {
|
|
||||||
limit = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start >= end) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start >= limit && nxt_t == _tempos.end() && nxt_m == _meters.end() && nxt_b == _bartimes.end()) {
|
|
||||||
|
|
||||||
/* reached the end, no more tempos, meters or bartimes
|
|
||||||
to consider, so just finish up.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("reached end, no more t/m/b, finish between %1 .. %2\n", start, end));
|
|
||||||
|
|
||||||
const superclock_t step = metric.superclocks_per_grid_at (start);
|
|
||||||
|
|
||||||
while (start < end) {
|
|
||||||
const Temporal::Beats beats = metric.quarters_at_superclock (start);
|
|
||||||
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("Gend %1\t %2\n", metric, ret.back()));
|
|
||||||
start += step;
|
|
||||||
bbt = metric.bbt_at (start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done, leave outer loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inner loop: add grid points until we hit limit, which is defined by either @param e or the next marker of some kind */
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
/* we already have the superclock and BBT time for the next point, either computed before the loop, or at the bottom of this one.
|
|
||||||
* So now complete the triplet of (superclock,quarters,bbt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Temporal::Beats beats = metric.quarters_at_superclock (start);
|
|
||||||
|
|
||||||
/* add point to grid */
|
|
||||||
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("G %1\t %2\n", metric, ret.back()));
|
|
||||||
|
|
||||||
/* Advance by the meter note value size */
|
|
||||||
|
|
||||||
superclock_t step;
|
superclock_t step;
|
||||||
|
|
||||||
if (bar_mod == 0) {
|
if (bar_mod == 0) {
|
||||||
|
|
||||||
|
/* Advance by the meter note value size */
|
||||||
|
|
||||||
step = metric.superclocks_per_grid_at (start);
|
step = metric.superclocks_per_grid_at (start);
|
||||||
start += step;
|
start += step;
|
||||||
bbt = metric.bbt_at (start);
|
bbt = metric.bbt_at (start);
|
||||||
|
@ -1924,105 +1850,129 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
/* Advance by the number of bars specified by bar_mod */
|
||||||
|
|
||||||
bbt.bars += bar_mod;
|
bbt.bars += bar_mod;
|
||||||
start = metric.superclock_at (bbt);
|
start = metric.superclock_at (bbt);
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("bar mod %1 moved to %2\n", bar_mod, bbt))
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("bar mod %1 moved to %2\n", bar_mod, bbt))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we might be finished ...*/
|
||||||
|
|
||||||
|
if (start >= end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* could have just passed the current metric */
|
while ((p != _points.end()) && (start >= p->sclock())) {
|
||||||
|
|
||||||
if (first_of_three && (start > first_of_three->sclock ())) {
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("pausing to deal with point => %1\n", *p));
|
||||||
start = first_of_three->sclock();
|
|
||||||
break;
|
/* have just passed or arrived at the next
|
||||||
|
* point. Consider adding a grid point for this point.
|
||||||
|
*/
|
||||||
|
|
||||||
|
start = p->sclock();
|
||||||
|
bbt = p->bbt();
|
||||||
|
beats = p->beats();
|
||||||
|
|
||||||
|
if ((bar_mod != 0) && bbt.is_bar() && (bbt.bars % bar_mod != 0)) {
|
||||||
|
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
||||||
|
} else {
|
||||||
|
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start >= limit) {
|
/* But there may be multiple points here, and we have
|
||||||
/* go back to outer loop to advance iterators and get a new metric */
|
* to check them all (Tempo/Meter/MusicTime ... which
|
||||||
break;
|
* is itself both a Tempo *and* Meter point) before
|
||||||
|
* proceeding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const superclock_t pos = p->sclock();
|
||||||
|
|
||||||
|
Points::iterator nxt = p;
|
||||||
|
++nxt;
|
||||||
|
|
||||||
|
TempoPoint* tpp;
|
||||||
|
MeterPoint* mpp;
|
||||||
|
|
||||||
|
/* use this point */
|
||||||
|
|
||||||
|
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||||
|
tp = tpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (true);
|
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||||
|
mp = mpp;
|
||||||
/* back in outer loop. Check to see if we passed a marker */
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("pass-marker-check fo3 %1 start %2 fo2->sc %3\n", first_of_three, start, (first_of_three ? first_of_three->sclock() : -1)));
|
|
||||||
|
|
||||||
if (first_of_three && (start >= first_of_three->sclock())) {
|
|
||||||
|
|
||||||
if (advance_tempo) {
|
|
||||||
if (nxt_t != _tempos.end()) {
|
|
||||||
t = nxt_t;
|
|
||||||
++nxt_t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (advance_meter) {
|
|
||||||
if (nxt_m != _meters.end()) {
|
|
||||||
m = nxt_m;
|
|
||||||
++nxt_m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (advance_bartime) {
|
|
||||||
b = nxt_b;
|
|
||||||
if (nxt_b != _bartimes.end()) {
|
|
||||||
++nxt_b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (advance_tempo || advance_meter || advance_bartime) {
|
/* use any subsequent ones at the same location */
|
||||||
|
|
||||||
/* we overstepped a marker
|
while ((nxt != _points.end()) && (nxt->sclock() == pos)) {
|
||||||
|
|
||||||
* if bar_mod is zero, then by definition any
|
/* Set up the new metric given the new point */
|
||||||
* such marker qualifies as a grid point.
|
|
||||||
*
|
|
||||||
* if bar_mod != zero, then check to see if the new
|
|
||||||
* BBT position matches the interval we've been asked
|
|
||||||
* for. If so, use it, otherwise just continue around
|
|
||||||
* the loop, using the new position and metric.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bbt = first_of_three->bbt ();
|
if ((tpp = dynamic_cast<TempoPoint*> (&(*nxt))) != 0) {
|
||||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("reset bbt to %1\n", bbt));
|
tp = tpp;
|
||||||
|
|
||||||
if (bar_mod != 0) {
|
|
||||||
|
|
||||||
/* check to see if it matches the interval */
|
|
||||||
|
|
||||||
if (!bbt.is_bar() || (bbt.bars % bar_mod != 0)) {
|
|
||||||
|
|
||||||
/* not usable */
|
|
||||||
|
|
||||||
bbt = bbt.round_up_to_bar ();
|
|
||||||
|
|
||||||
/* reset iterators for new position */
|
|
||||||
|
|
||||||
for (Tempos::iterator tt = t; tt != _tempos.end() && tt->bbt() < bbt; ++tt) { t = tt; }
|
|
||||||
for (Meters::iterator mm = m; mm != _meters.end() && mm->bbt() < bbt; ++mm) { m = mm; }
|
|
||||||
for (MusicTimes::iterator bb = b; bb != _bartimes.end() && bb->bbt() < bbt; ++bb) { b = bb; }
|
|
||||||
nxt_t = t; ++nxt_t;
|
|
||||||
nxt_m = m; ++nxt_m;
|
|
||||||
nxt_b = b; ++nxt_b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now build a new metric that uses the correct
|
if ((mpp = dynamic_cast<MeterPoint*> (&(*nxt))) != 0) {
|
||||||
* tempo/meter (computed above), but the
|
mp = mpp;
|
||||||
* position of the marker we've just arrived
|
}
|
||||||
* at. The idea is that time after this marker
|
|
||||||
* is defined by the tempo/meter in effect
|
|
||||||
* there, combined with its own time (in all 3
|
|
||||||
* time domains, superclock, quarters, bbt).
|
|
||||||
*/
|
|
||||||
|
|
||||||
TempoPoint tp (*t, *first_of_three);
|
++nxt;
|
||||||
MeterPoint mp (*m, *first_of_three);
|
|
||||||
|
|
||||||
metric = TempoMetric (tp, mp);
|
|
||||||
start = first_of_three->sclock();
|
|
||||||
|
|
||||||
/* ready to loop because metric, start and bbt are all set correctly, as they were when entering the outer loop */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build a new metric from the composite of all the
|
||||||
|
* points at this position.
|
||||||
|
*/
|
||||||
|
|
||||||
|
metric = TempoMetric (*tp, *mp);
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("G %1\t %2\n", metric, ret.back()));
|
||||||
|
|
||||||
|
p = nxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == _points.end()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reached the end or no more points to consider, so just
|
||||||
|
* finish by filling the grid to the end, if necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (start < end) {
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("reached end, no more map points, finish between %1 .. %2\n", start, end));
|
||||||
|
|
||||||
|
/* note: if start < end, then p == _points.end(). This means there are
|
||||||
|
* no more Points beyond the current value of start.
|
||||||
|
*
|
||||||
|
* Since there are no more Points beyond start, the current metric
|
||||||
|
* cannot involve a ramp, so the step size per grid element is
|
||||||
|
* constant. metric will also remain constant until we finish.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const superclock_t step = metric.superclocks_per_grid_at (start);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const Temporal::Beats beats = metric.quarters_at_superclock (start);
|
||||||
|
ret.push_back (TempoMapPoint (*this, metric, start, beats, bbt));
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("Gend %1\t %2\n", metric, ret.back()));
|
||||||
|
start += step;
|
||||||
|
bbt = metric.bbt_at (start);
|
||||||
|
|
||||||
|
} while (start < end);
|
||||||
|
|
||||||
|
/* all done */
|
||||||
|
} else {
|
||||||
|
if (p == _points.end()) {
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("ended loop with start %1 end %2, p @ END\n", start, end));
|
||||||
|
} else {
|
||||||
|
DEBUG_TRACE (DEBUG::Grid, string_compose ("ended loop with start %1 end %2, p=> %3\n", start, end, *p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user