mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-19 20:06:09 +01:00
generalize repeated code into a template method, add lots of const-ness to facilitate this
This commit is contained in:
parent
c5ecd14622
commit
1f8290f154
4 changed files with 100 additions and 243 deletions
|
|
@ -1887,8 +1887,8 @@ LuaBindings::common (lua_State* L)
|
|||
.addStaticFunction ("use", &TempoMap::use)
|
||||
.addFunction ("set_tempo", (Temporal::TempoPoint& (Temporal::TempoMap::*)(Temporal::Tempo const &,timepos_t const &)) &TempoMap::set_tempo)
|
||||
.addFunction ("set_meter", (Temporal::MeterPoint& (Temporal::TempoMap::*)(Temporal::Meter const &,timepos_t const &)) &TempoMap::set_meter)
|
||||
.addFunction ("tempo_at", (Temporal::TempoPoint& (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::tempo_at)
|
||||
.addFunction ("meter_at", (Temporal::MeterPoint& (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::meter_at)
|
||||
.addFunction ("tempo_at", (Temporal::TempoPoint const & (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::tempo_at)
|
||||
.addFunction ("meter_at", (Temporal::MeterPoint const & (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::meter_at)
|
||||
.addFunction ("bbt_at", (Temporal::BBT_Time (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::bbt_at)
|
||||
.addFunction ("quarters_at", (Temporal::Beats (Temporal::TempoMap::*)(timepos_t const &) const) &TempoMap::quarters_at)
|
||||
.addFunction ("sample_at", (samplepos_t (Temporal::TempoMap::*)(timepos_t const &, samplecnt_t) const) &TempoMap::sample_at)
|
||||
|
|
|
|||
|
|
@ -7418,7 +7418,7 @@ Session::maybe_update_tempo_from_midiclock_tempo (float bpm)
|
|||
if (tmap->n_tempos() == 1) {
|
||||
Temporal::TempoMetric const & metric (tmap->metric_at (0));
|
||||
if (fabs (metric.tempo().note_types_per_minute() - bpm) > (0.01 * metric.tempo().note_types_per_minute())) {
|
||||
tmap->change_tempo (metric.tempo(), Tempo (bpm, 4.0, bpm));
|
||||
tmap->change_tempo (metric.get_editable_tempo(), Tempo (bpm, 4.0, bpm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1642,6 +1642,53 @@ TempoMap::dump (std::ostream& ostr) const
|
|||
ostr << "------------\n\n\n";
|
||||
}
|
||||
|
||||
template<typename T> TempoMap::Points::const_iterator
|
||||
TempoMap::_get_tempo_and_meter (TempoPoint const *& tp, MeterPoint const *& mp, T (Point::*method)() const, T arg, bool can_match) const
|
||||
{
|
||||
Points::const_iterator p;
|
||||
bool tempo_done = false;
|
||||
bool meter_done = false;
|
||||
|
||||
assert (!_tempos.empty());
|
||||
assert (!_meters.empty());
|
||||
assert (!_points.empty());
|
||||
|
||||
tp = 0;
|
||||
mp = 0;
|
||||
|
||||
for (tp = &_tempos.front(), mp = &_meters.front(), p = _points.begin(); p != _points.end(); ++p) {
|
||||
|
||||
TempoPoint const * tpp;
|
||||
MeterPoint const * mpp;
|
||||
|
||||
if (!tempo_done && (tpp = dynamic_cast<TempoPoint const *> (&(*p))) != 0) {
|
||||
if ((can_match && (((*p).*method)() > arg)) || (((*p).*method)() >= arg)) {
|
||||
tempo_done = true;
|
||||
} else {
|
||||
tp = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
if (!meter_done && (mpp = dynamic_cast<MeterPoint const *> (&(*p))) != 0) {
|
||||
if ((can_match && (((*p).*method)() > arg)) || (((*p).*method)() >= arg)) {
|
||||
meter_done = true;
|
||||
} else {
|
||||
mp = mpp;
|
||||
}
|
||||
}
|
||||
|
||||
if (meter_done && tempo_done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tp || !mp) {
|
||||
return _points.end();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, uint32_t bar_mod)
|
||||
{
|
||||
|
|
@ -1651,9 +1698,9 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
|||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose (">>> GRID START %1 .. %2 (barmod = %3)\n", start, end, bar_mod));
|
||||
|
||||
TempoPoint* tp = 0;
|
||||
MeterPoint* mp = 0;
|
||||
Points::iterator p;
|
||||
TempoPoint const * tp = 0;
|
||||
MeterPoint const * mp = 0;
|
||||
Points::const_iterator p;
|
||||
|
||||
/* initial values required, but will be reset before we begin */
|
||||
TempoMetric metric (_tempos.front(), _meters.front());
|
||||
|
|
@ -1665,34 +1712,10 @@ 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.
|
||||
*/
|
||||
|
||||
for (tp = &_tempos.front(), p = _points.begin(); p != _points.end() && p->sclock() < start; ++p) {
|
||||
|
||||
TempoPoint* tpp;
|
||||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("Looking at a point tempo %1\n", *p));
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("set tempo with that (check: %1 < %2)\n", p->sclock(), start));
|
||||
tp = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
for (mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->sclock() < start; ++p) {
|
||||
|
||||
MeterPoint* mpp;
|
||||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("Looking at a point for meter %1\n", *p));
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("set meter with that (check: %1 < %2)\n", p->sclock(), start));
|
||||
mp = mpp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* reset metric */
|
||||
p = get_tempo_and_meter (tp, mp, start, false);
|
||||
|
||||
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
|
||||
|
|
@ -1721,29 +1744,10 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
|||
|
||||
/* rounded up, determine new starting superclock position */
|
||||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("new bbt for start (rounded up) = %1\n", bbt));
|
||||
|
||||
for (tp = &_tempos.front(), p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
|
||||
TempoPoint* tpp;
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||
tp = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
for (mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
MeterPoint* mpp;
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||
mp = mpp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* reset metric */
|
||||
p = get_tempo_and_meter (tp, mp, bbt);
|
||||
|
||||
metric = TempoMetric (*tp, *mp);
|
||||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("metric in effect(2) at %1 = %2\n", start, metric));
|
||||
|
||||
/* recompute superclock position */
|
||||
|
|
@ -1786,27 +1790,9 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
|||
|
||||
bbt = bar;
|
||||
|
||||
for (tp = &_tempos.front(), p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
|
||||
TempoPoint* tpp;
|
||||
MeterPoint* mpp;
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||
tp = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
for (mp = &_meters.front(), p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
MeterPoint* mpp;
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||
mp = mpp;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset metric */
|
||||
|
||||
p = get_tempo_and_meter (tp, mp, bbt);
|
||||
metric = TempoMetric (*tp, *mp);
|
||||
|
||||
DEBUG_TRACE (DEBUG::Grid, string_compose ("metric in effect(3) at %1 = %2\n", start, metric));
|
||||
start = metric.superclock_at (bbt);
|
||||
|
||||
|
|
@ -1907,19 +1893,19 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
|||
|
||||
const superclock_t pos = p->sclock();
|
||||
|
||||
Points::iterator nxt = p;
|
||||
Points::const_iterator nxt = p;
|
||||
++nxt;
|
||||
|
||||
TempoPoint* tpp;
|
||||
MeterPoint* mpp;
|
||||
TempoPoint const * tpp;
|
||||
MeterPoint const * mpp;
|
||||
|
||||
/* use this point */
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint*> (&(*p))) != 0) {
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p))) != 0) {
|
||||
tp = tpp;
|
||||
}
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint*> (&(*p))) != 0) {
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p))) != 0) {
|
||||
mp = mpp;
|
||||
}
|
||||
|
||||
|
|
@ -1929,11 +1915,11 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
|
|||
|
||||
/* Set up the new metric given the new point */
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint*> (&(*nxt))) != 0) {
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*nxt))) != 0) {
|
||||
tp = tpp;
|
||||
}
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint*> (&(*nxt))) != 0) {
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*nxt))) != 0) {
|
||||
mp = mpp;
|
||||
}
|
||||
|
||||
|
|
@ -2770,172 +2756,34 @@ TempoMap::metric_at (timepos_t const & pos) const
|
|||
TempoMetric
|
||||
TempoMap::metric_at (superclock_t sc, bool can_match) const
|
||||
{
|
||||
assert (!_tempos.empty());
|
||||
assert (!_meters.empty());
|
||||
assert (!_points.empty());
|
||||
TempoPoint const * tp = 0;
|
||||
MeterPoint const * mp = 0;
|
||||
|
||||
TempoPoint const * tpp = 0;
|
||||
MeterPoint const * mpp = 0;
|
||||
(void) get_tempo_and_meter (tp, mp, sc, can_match);
|
||||
|
||||
TempoPoint const * prev_t = &_tempos.front();
|
||||
|
||||
/* Yes, linear search because the typical size of _points
|
||||
* is 2, and extreme sizes are on the order of 10-100
|
||||
*/
|
||||
|
||||
Points::const_iterator p;
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->sclock() < sc; ++p) {
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
MeterPoint const * prev_m = &_meters.front();
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->sclock() < sc; ++p) {
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_match || sc == 0) {
|
||||
/* may have found tempo and/or meter precisely at @param sc */
|
||||
|
||||
if (p != _points.end() && p->sclock() == sc) {
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* I hate doing this const_cast<>, but making this method non-const
|
||||
* propagates into everything that just calls metric_at(), and that's a
|
||||
* bit ridiculous. Yes, the TempoMetric returned here can be used to
|
||||
* change the map, and that's bad, but the non-const propagation is
|
||||
* worse.
|
||||
*/
|
||||
|
||||
return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
|
||||
return TempoMetric (*tp,* mp);
|
||||
}
|
||||
|
||||
TempoMetric
|
||||
TempoMap::metric_at (Beats const & b, bool can_match) const
|
||||
{
|
||||
assert (!_tempos.empty());
|
||||
assert (!_meters.empty());
|
||||
assert (!_points.empty());
|
||||
TempoPoint const * tp = 0;
|
||||
MeterPoint const * mp = 0;
|
||||
|
||||
TempoPoint const * tpp = 0;
|
||||
MeterPoint const * mpp = 0;
|
||||
(void) get_tempo_and_meter (tp, mp, b, can_match);
|
||||
|
||||
TempoPoint const * prev_t = &_tempos.front();
|
||||
|
||||
/* Yes, linear search because the typical size of _points
|
||||
* is 2, and extreme sizes are on the order of 10-100
|
||||
*/
|
||||
|
||||
Points::const_iterator p;
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->beats() < b; ++p) {
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
MeterPoint const * prev_m = &_meters.front();
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->beats() < b; ++p) {
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_match || b == Beats()) {
|
||||
/* may have found tempo and/or meter precisely at @param sc */
|
||||
|
||||
if (p != _points.end() && p->beats() == b) {
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* I hate doing this const_cast<>, but making this method non-const
|
||||
* propagates into everything that just calls metric_at(), and that's a
|
||||
* bit ridiculous. Yes, the TempoMetric returned here can be used to
|
||||
* change the map, and that's bad, but the non-const propagation is
|
||||
* worse.
|
||||
*/
|
||||
|
||||
return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
|
||||
return TempoMetric (*tp, *mp);
|
||||
}
|
||||
|
||||
TempoMetric
|
||||
TempoMap::metric_at (BBT_Time const & bbt, bool can_match) const
|
||||
{
|
||||
assert (!_tempos.empty());
|
||||
assert (!_meters.empty());
|
||||
assert (!_points.empty());
|
||||
TempoPoint const * tp = 0;
|
||||
MeterPoint const * mp = 0;
|
||||
|
||||
TempoPoint const * tpp = 0;
|
||||
MeterPoint const * mpp = 0;
|
||||
(void) get_tempo_and_meter (tp, mp, bbt);
|
||||
|
||||
TempoPoint const * prev_t = &_tempos.front();
|
||||
|
||||
/* Yes, linear search because the typical size of _points
|
||||
* is 2, and extreme sizes are on the order of 10-100
|
||||
*/
|
||||
|
||||
Points::const_iterator p;
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
}
|
||||
|
||||
MeterPoint const * prev_m = &_meters.front();
|
||||
|
||||
for (p = _points.begin(); p != _points.end() && p->bbt() < bbt; ++p) {
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_match || bbt == BBT_Time()) {
|
||||
/* may have found tempo and/or meter precisely at @param sc */
|
||||
|
||||
if (p != _points.end() && p->bbt() == bbt) {
|
||||
|
||||
if ((tpp = dynamic_cast<TempoPoint const *> (&(*p)))) {
|
||||
prev_t = tpp;
|
||||
}
|
||||
|
||||
if ((mpp = dynamic_cast<MeterPoint const *> (&(*p)))) {
|
||||
prev_m = mpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* I hate doing this const_cast<>, but making this method non-const
|
||||
* propagates into everything that just calls metric_at(), and that's a
|
||||
* bit ridiculous. Yes, the TempoMetric returned here can be used to
|
||||
* change the map, and that's bad, but the non-const propagation is
|
||||
* worse.
|
||||
*/
|
||||
|
||||
return TempoMetric (*const_cast<TempoPoint*>(prev_t), *const_cast<MeterPoint*> (prev_m));
|
||||
return TempoMetric (*tp, *mp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -448,11 +448,14 @@ class LIBTEMPORAL_API TempoPoint : public Tempo, public virtual Point
|
|||
*/
|
||||
class LIBTEMPORAL_API TempoMetric {
|
||||
public:
|
||||
TempoMetric (TempoPoint & t, MeterPoint & m) : _tempo (&t), _meter (&m) {}
|
||||
TempoMetric (TempoPoint const & t, MeterPoint const & m) : _tempo (&t), _meter (&m) {}
|
||||
~TempoMetric () {}
|
||||
|
||||
TempoPoint & tempo() const { return *_tempo; }
|
||||
MeterPoint & meter() const { return *_meter; }
|
||||
TempoPoint const & tempo() const { return *_tempo; }
|
||||
MeterPoint const & meter() const { return *_meter; }
|
||||
|
||||
TempoPoint & get_editable_tempo() const { return *const_cast<TempoPoint*> (_tempo); }
|
||||
MeterPoint & get_editable_meter() const { return *const_cast<MeterPoint*> (_meter); }
|
||||
|
||||
/* even more convenient wrappers for individual aspects of a
|
||||
* TempoMetric (i.e. just tempo or just meter information required
|
||||
|
|
@ -508,8 +511,8 @@ class LIBTEMPORAL_API TempoMetric {
|
|||
Beats quarters_at_superclock (superclock_t sc) const { return _tempo->quarters_at_superclock (sc); }
|
||||
|
||||
protected:
|
||||
TempoPoint* _tempo;
|
||||
MeterPoint* _meter;
|
||||
TempoPoint const * _tempo;
|
||||
MeterPoint const * _meter;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -740,15 +743,15 @@ class LIBTEMPORAL_API TempoMap : public PBD::StatefulDestructible
|
|||
|
||||
/* essentially convenience methods */
|
||||
|
||||
MeterPoint& meter_at (timepos_t const & p) const { return metric_at (p).meter(); }
|
||||
MeterPoint& meter_at (superclock_t sc) const { return metric_at (sc).meter(); }
|
||||
MeterPoint& meter_at (Beats const &b) const { return metric_at (b).meter(); }
|
||||
MeterPoint& meter_at (BBT_Time const & bbt) const { return metric_at (bbt).meter(); }
|
||||
MeterPoint const & meter_at (timepos_t const & p) const { return metric_at (p).meter(); }
|
||||
MeterPoint const & meter_at (superclock_t sc) const { return metric_at (sc).meter(); }
|
||||
MeterPoint const & meter_at (Beats const &b) const { return metric_at (b).meter(); }
|
||||
MeterPoint const & meter_at (BBT_Time const & bbt) const { return metric_at (bbt).meter(); }
|
||||
|
||||
TempoPoint& tempo_at (timepos_t const & p) const { return metric_at (p).tempo(); }
|
||||
TempoPoint& tempo_at (superclock_t sc) const { return metric_at (sc).tempo(); }
|
||||
TempoPoint& tempo_at (Beats const &b) const { return metric_at (b).tempo(); }
|
||||
TempoPoint& tempo_at (BBT_Time const & bbt) const { return metric_at (bbt).tempo(); }
|
||||
TempoPoint const & tempo_at (timepos_t const & p) const { return metric_at (p).tempo(); }
|
||||
TempoPoint const & tempo_at (superclock_t sc) const { return metric_at (sc).tempo(); }
|
||||
TempoPoint const & tempo_at (Beats const &b) const { return metric_at (b).tempo(); }
|
||||
TempoPoint const & tempo_at (BBT_Time const & bbt) const { return metric_at (bbt).tempo(); }
|
||||
|
||||
TempoPoint const * previous_tempo (TempoPoint const &) const;
|
||||
|
||||
|
|
@ -851,6 +854,12 @@ class LIBTEMPORAL_API TempoMap : public PBD::StatefulDestructible
|
|||
BBT_Time bbt_at (Beats const &) const;
|
||||
BBT_Time bbt_at (superclock_t sc) const;
|
||||
|
||||
template<typename T> Points::const_iterator _get_tempo_and_meter (TempoPoint const *& tp, MeterPoint const *& mp, T (Point::*method)() const, T arg, bool can_match) const;
|
||||
|
||||
Points::const_iterator get_tempo_and_meter (TempoPoint const *& t, MeterPoint const *& m, BBT_Time const & bbt, bool can_match = true) const { return _get_tempo_and_meter<BBT_Time const &> (t, m, &Point::bbt, bbt, can_match); }
|
||||
Points::const_iterator get_tempo_and_meter (TempoPoint const *& t, MeterPoint const *& m, superclock_t sc, bool can_match = true) const { return _get_tempo_and_meter<superclock_t> (t, m, &Point::sclock, sc, can_match); }
|
||||
Points::const_iterator get_tempo_and_meter (TempoPoint const *& t, MeterPoint const *& m, Beats const & b, bool can_match = true) const { return _get_tempo_and_meter<Beats const &> (t, m, &Point::beats, b, can_match); }
|
||||
|
||||
/* parsing legacy tempo maps */
|
||||
|
||||
struct LegacyTempoState
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue