libtemporal: make TempoMap::metric_at() variants use all Points, to account for music time points as well as explicit tempo/meter points

This commit is contained in:
Paul Davis 2021-02-09 09:48:25 -07:00
parent 432fbe984a
commit cffc25a11c

View file

@ -2688,28 +2688,43 @@ TempoMap::metric_at (timepos_t const & pos) const
TempoMetric TempoMetric
TempoMap::metric_at (superclock_t sc, bool can_match) const TempoMap::metric_at (superclock_t sc, bool can_match) const
{ {
Tempos::const_iterator t, prev_t;
Meters::const_iterator m, prev_m;
assert (!_tempos.empty()); assert (!_tempos.empty());
assert (!_meters.empty()); assert (!_meters.empty());
assert (!_points.empty());
/* Yes, linear search because the typical size of _tempos and _meters TempoPoint const * tpp = 0;
* is 1, and extreme sizes are on the order of 10 MeterPoint const * mpp = 0;
TempoPoint const * prev_t = &_tempos.front();
MeterPoint const * prev_m = &_meters.front();
/* Yes, linear search because the typical size of _points
* is 2, and extreme sizes are on the order of 10-100
*/ */
for (t = _tempos.begin(), prev_t = t; t != _tempos.end() && t->sclock() < sc; ++t) { prev_t = t; } Points::const_iterator p;
for (m = _meters.begin(), prev_m = m; m != _meters.end() && m->sclock() < sc; ++m) { prev_m = m; }
for (p = _points.begin(); p != _points.end() && p->sclock() < sc; ++p) {
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
}
if (can_match || sc == 0) { if (can_match || sc == 0) {
/* may have found tempo and/or meter precisely at @param sc */ /* may have found tempo and/or meter precisely at @param sc */
if (t != _tempos.end() && t->sclock() == sc) { if (p != _points.end() && p->sclock() == sc) {
prev_t = t;
}
if (m != _meters.end() && m->sclock() == sc) { if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_m = m; prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
} }
} }
@ -2720,33 +2735,49 @@ TempoMap::metric_at (superclock_t sc, bool can_match) const
* worse. * worse.
*/ */
return TempoMetric (*const_cast<TempoPoint*>(&*prev_t), *const_cast<MeterPoint*> (&*prev_m)); return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
} }
TempoMetric TempoMetric
TempoMap::metric_at (Beats const & b, bool can_match) const TempoMap::metric_at (Beats const & b, bool can_match) const
{ {
Tempos::const_iterator t, prev_t;
Meters::const_iterator m, prev_m;
assert (!_tempos.empty()); assert (!_tempos.empty());
assert (!_meters.empty()); assert (!_meters.empty());
assert (!_points.empty());
/* Yes, linear search because the typical size of _tempos and _meters TempoPoint const * tpp = 0;
* is 1, and extreme sizes are on the order of 10 MeterPoint const * mpp = 0;
TempoPoint const * prev_t = &_tempos.front();
MeterPoint const * prev_m = &_meters.front();
/* Yes, linear search because the typical size of _points
* is 2, and extreme sizes are on the order of 10-100
*/ */
for (t = _tempos.begin(), prev_t = t; t != _tempos.end() && t->beats() < b; ++t) { prev_t = t; } Points::const_iterator p;
for (m = _meters.begin(), prev_m = m; m != _meters.end() && m->beats() < b; ++m) { prev_m = m; }
for (p = _points.begin(); p != _points.end() && p->beats() < b; ++p) {
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
}
if (can_match || b == Beats()) { if (can_match || b == Beats()) {
/* may have found tempo and/or meter precisely at @param b */ /* may have found tempo and/or meter precisely at @param sc */
if (t != _tempos.end() && t->beats() == b) {
prev_t = t;
}
if (m != _meters.end() && m->beats() == b) { if (p != _points.end() && p->beats() == b) {
prev_m = m;
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
} }
} }
@ -2757,34 +2788,49 @@ TempoMap::metric_at (Beats const & b, bool can_match) const
* worse. * worse.
*/ */
return TempoMetric (*const_cast<TempoPoint*>(&*prev_t), *const_cast<MeterPoint*> (&*prev_m)); return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
} }
TempoMetric TempoMetric
TempoMap::metric_at (BBT_Time const & bbt, bool can_match) const TempoMap::metric_at (BBT_Time const & bbt, bool can_match) const
{ {
Tempos::const_iterator t, prev_t;
Meters::const_iterator m, prev_m;
assert (!_tempos.empty()); assert (!_tempos.empty());
assert (!_meters.empty()); assert (!_meters.empty());
assert (!_points.empty());
/* Yes, linear search because the typical size of _tempos and _meters TempoPoint const * tpp = 0;
* is 1, and extreme sizes are on the order of 10 MeterPoint const * mpp = 0;
TempoPoint const * prev_t = &_tempos.front();
MeterPoint const * prev_m = &_meters.front();
/* Yes, linear search because the typical size of _points
* is 2, and extreme sizes are on the order of 10-100
*/ */
for (t = _tempos.begin(), prev_t = t; t != _tempos.end() && t->bbt() < bbt; ++t) { prev_t = t; } Points::const_iterator p;
for (m = _meters.begin(), prev_m = m; m != _meters.end() && m->bbt() < bbt; ++m) { prev_m = m; }
for (p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
}
if (can_match || bbt == BBT_Time()) { if (can_match || bbt == BBT_Time()) {
/* may have found tempo and/or meter precisely at @param bbt */ /* may have found tempo and/or meter precisely at @param sc */
if (t != _tempos.end() && t->bbt() == bbt) { if (p != _points.end() && p->bbt() == bbt) {
prev_t = t;
}
if (m != _meters.end() && m->bbt() == bbt) { if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
prev_m = m; prev_t = tpp;
}
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
prev_m = mpp;
}
} }
} }
@ -2795,7 +2841,7 @@ TempoMap::metric_at (BBT_Time const & bbt, bool can_match) const
* worse. * worse.
*/ */
return TempoMetric (*const_cast<TempoPoint*>(&*prev_t), *const_cast<MeterPoint*> (&*prev_m)); return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
} }
bool bool