mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
continuing miscellaneous work on broken-out tempo code
This commit is contained in:
parent
73d0a849b8
commit
059fda9d4b
2 changed files with 180 additions and 92 deletions
243
nutemp/t.cc
243
nutemp/t.cc
|
|
@ -431,7 +431,7 @@ TempoMap::rebuild_locked (superclock_t limit)
|
||||||
++nxt;
|
++nxt;
|
||||||
|
|
||||||
if (tmp->ramped() && (nxt != _points.end())) {
|
if (tmp->ramped() && (nxt != _points.end())) {
|
||||||
tmp->metric().compute_c_quarters (_sample_rate, nxt->metric().superclocks_per_quarter_note (), nxt->quarters() - tmp->quarters());
|
tmp->compute_c_quarters (_sample_rate, nxt->metric().superclocks_per_quarter_note (), nxt->quarters() - tmp->quarters());
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = nxt;
|
tmp = nxt;
|
||||||
|
|
@ -558,6 +558,98 @@ TempoMap::rebuild_locked (superclock_t limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TempoMap::set_tempo_and_meter (Tempo const & tempo, Meter const & meter, superclock_t sc, bool ramp, bool flexible)
|
||||||
|
{
|
||||||
|
/* CALLER MUST HOLD LOCK */
|
||||||
|
|
||||||
|
assert (!_points.empty());
|
||||||
|
|
||||||
|
/* special case: first map entry is later than the new point */
|
||||||
|
|
||||||
|
if (_points.front().sclock() > sc) {
|
||||||
|
/* first point is later than sc. There's no iterator to reference a point at or before sc */
|
||||||
|
|
||||||
|
/* determine beats and BBT time for this new tempo point. Note that tempo changes (points) must be deemed to be on beat,
|
||||||
|
even if the user moves them later. Even after moving, the TempoMapPoint that was beat N is still beat N, and is not
|
||||||
|
fractional.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Evoral::Beats b = _points.front().quarters_at (sc).round_to_beat();
|
||||||
|
Timecode::BBT_Time bbt = _points.front().bbt_at (b).round_to_beat ();
|
||||||
|
|
||||||
|
_points.insert (_points.begin(), TempoMapPoint (TempoMapPoint::ExplicitTempo, tempo, meter, sc, b, bbt, AudioTime, ramp));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special case #3: only one map entry, at the same time as the new point.
|
||||||
|
This is the common case when editing tempo/meter in a session with a single tempo/meter
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_points.size() == 1 && _points.front().sclock() == sc) {
|
||||||
|
/* change metrics */
|
||||||
|
*((Tempo*) &_points.front().metric()) = tempo;
|
||||||
|
*((Meter*) &_points.front().metric()) = meter;
|
||||||
|
_points.front().make_explicit (TempoMapPoint::Flag (TempoMapPoint::ExplicitTempo|TempoMapPoint::ExplicitMeter));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember: iterator_at() returns an iterator that references the TempoMapPoint at or BEFORE sc */
|
||||||
|
|
||||||
|
TempoMapPoints::iterator i = iterator_at (sc);
|
||||||
|
TempoMapPoints::iterator nxt = i;
|
||||||
|
++nxt;
|
||||||
|
|
||||||
|
if (i->sclock() == sc) {
|
||||||
|
/* change metrics */
|
||||||
|
*((Tempo*) &i->metric()) = tempo;
|
||||||
|
*((Meter*) &i->metric()) = meter;
|
||||||
|
i->make_explicit (TempoMapPoint::Flag (TempoMapPoint::ExplicitTempo|TempoMapPoint::ExplicitMeter));
|
||||||
|
/* done */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!flexible && (sc - i->sclock() < i->metric().superclocks_per_note_type())) {
|
||||||
|
cerr << "new tempo too close to previous ...\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempoMapPoints::iterator e (i);
|
||||||
|
while (!e->is_explicit() && e != _points.begin()) {
|
||||||
|
--e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->metric().ramped()) {
|
||||||
|
/* need to adjust ramp constants for preceding explict point, since the new point will be positioned right after it
|
||||||
|
and thus defines the new ramp distance.
|
||||||
|
*/
|
||||||
|
e->compute_c_superclock (_sample_rate, tempo.superclocks_per_quarter_note (), sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine beats and BBT time for this new tempo point. Note that tempo changes (points) must be deemed to be on beat,
|
||||||
|
even if the user moves them later. Even after moving, the TempoMapPoint that was beat N is still beat N, and is not
|
||||||
|
fractional.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Evoral::Beats qn = i->quarters_at (sc).round_to_beat();
|
||||||
|
|
||||||
|
/* rule: all Tempo changes must be on-beat. So determine the nearest later beat to "sc"
|
||||||
|
*/
|
||||||
|
|
||||||
|
Timecode::BBT_Time bbt = i->bbt_at (qn).round_up_to_beat ();
|
||||||
|
|
||||||
|
/* Modify the iterator to reference the point AFTER this new one, because STL insert is always "insert-before"
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (i != _points.end()) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "Insert at " << i->sclock() / superclock_ticks_per_second << endl;
|
||||||
|
_points.insert (i, TempoMapPoint (TempoMapPoint::ExplicitTempo, tempo, meter, sc, qn, bbt, AudioTime, ramp));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TempoMap::set_tempo (Tempo const & t, superclock_t sc, bool ramp)
|
TempoMap::set_tempo (Tempo const & t, superclock_t sc, bool ramp)
|
||||||
{
|
{
|
||||||
|
|
@ -614,11 +706,16 @@ TempoMap::set_tempo (Tempo const & t, superclock_t sc, bool ramp)
|
||||||
|
|
||||||
Meter const & meter (i->metric());
|
Meter const & meter (i->metric());
|
||||||
|
|
||||||
if (i->metric().ramped()) {
|
TempoMapPoints::iterator e (i);
|
||||||
|
while (!e->is_explicit() && e != _points.begin()) {
|
||||||
|
--e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->metric().ramped()) {
|
||||||
/* need to adjust ramp constants for preceding explict point, since the new point will be positioned right after it
|
/* need to adjust ramp constants for preceding explict point, since the new point will be positioned right after it
|
||||||
and thus defines the new ramp distance.
|
and thus defines the new ramp distance.
|
||||||
*/
|
*/
|
||||||
i->metric().compute_c_superclock (_sample_rate, t.superclocks_per_quarter_note (), sc);
|
e->compute_c_superclock (_sample_rate, t.superclocks_per_quarter_note (), sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine beats and BBT time for this new tempo point. Note that tempo changes (points) must be deemed to be on beat,
|
/* determine beats and BBT time for this new tempo point. Note that tempo changes (points) must be deemed to be on beat,
|
||||||
|
|
@ -1042,7 +1139,7 @@ TempoMap::dump (std::ostream& ostr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TempoMap::dump (std::ostream& ostr)
|
TempoMap::dump_locked (std::ostream& ostr)
|
||||||
{
|
{
|
||||||
ostr << "\n\n------------\n";
|
ostr << "\n\n------------\n";
|
||||||
for (TempoMapPoints::iterator i = _points.begin(); i != _points.end(); ++i) {
|
for (TempoMapPoints::iterator i = _points.begin(); i != _points.end(); ++i) {
|
||||||
|
|
@ -1053,7 +1150,7 @@ TempoMap::dump (std::ostream& ostr)
|
||||||
void
|
void
|
||||||
TempoMap::remove_explicit_point (superclock_t sc)
|
TempoMap::remove_explicit_point (superclock_t sc)
|
||||||
{
|
{
|
||||||
//Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||||
TempoMapPoints::iterator p = iterator_at (sc);
|
TempoMapPoints::iterator p = iterator_at (sc);
|
||||||
|
|
||||||
if (p->sclock() == sc) {
|
if (p->sclock() == sc) {
|
||||||
|
|
@ -1061,64 +1158,74 @@ TempoMap::remove_explicit_point (superclock_t sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
TempoMap::move_explicit (superclock_t current, superclock_t destination)
|
TempoMap::move_to (superclock_t current, superclock_t destination, bool push)
|
||||||
{
|
{
|
||||||
//Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||||
TempoMapPoints::iterator p = iterator_at (current);
|
TempoMapPoints::iterator p = iterator_at (current);
|
||||||
|
|
||||||
if (p->sclock() != current) {
|
if (p->sclock() != current) {
|
||||||
return;
|
cerr << "No point @ " << current << endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_explicit_to (p, destination);
|
const Meter meter (p->metric());
|
||||||
}
|
const Tempo tempo (p->metric());
|
||||||
|
const bool ramp = p->ramped();
|
||||||
void
|
|
||||||
TempoMap::move_explicit_to (TempoMapPoints::iterator p, superclock_t destination)
|
|
||||||
{
|
|
||||||
/* CALLER MUST HOLD LOCK */
|
|
||||||
|
|
||||||
TempoMapPoint point (*p);
|
|
||||||
point.set_sclock (destination);
|
|
||||||
|
|
||||||
TempoMapPoints::iterator prev;
|
|
||||||
|
|
||||||
prev = p;
|
|
||||||
if (p != _points.begin()) {
|
|
||||||
--prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove existing */
|
|
||||||
|
|
||||||
_points.erase (p);
|
_points.erase (p);
|
||||||
prev->set_dirty (true);
|
|
||||||
|
|
||||||
/* find insertion point */
|
return set_tempo_and_meter (tempo, meter, destination, ramp, true);
|
||||||
|
|
||||||
p = iterator_at (destination);
|
|
||||||
|
|
||||||
/* STL insert semantics are always "insert-before", whereas ::iterator_at() returns iterator-at-or-before */
|
|
||||||
++p;
|
|
||||||
|
|
||||||
_points.insert (p, point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TempoMap::move_implicit (superclock_t current, superclock_t destination)
|
TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end)
|
||||||
{
|
{
|
||||||
//Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::ReaderLock lm (_lock);
|
||||||
TempoMapPoints::iterator p = iterator_at (current);
|
TempoMapPoints::iterator p = iterator_at (start);
|
||||||
|
|
||||||
if (p->sclock() != current) {
|
while (p != _points.end() && p->sclock() < start) {
|
||||||
return;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->is_implicit()) {
|
while (p != _points.end() && p->sclock() < end) {
|
||||||
p->make_explicit (TempoMapPoint::Flag (TempoMapPoint::ExplicitMeter|TempoMapPoint::ExplicitTempo));
|
ret.push_back (*p);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& str, Meter const & m)
|
||||||
|
{
|
||||||
|
return str << m.divisions_per_bar() << '/' << m.note_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& str, Tempo const & t)
|
||||||
|
{
|
||||||
|
return str << t.note_types_per_minute() << " 1/" << t.note_type() << " notes per minute (" << t.superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& str, TempoMapPoint const & tmp)
|
||||||
|
{
|
||||||
|
str << '@' << std::setw (12) << tmp.sclock() << ' ' << tmp.sclock() / (double) superclock_ticks_per_second
|
||||||
|
<< (tmp.is_explicit() ? " EXP" : " imp")
|
||||||
|
<< " qn " << tmp.quarters ()
|
||||||
|
<< " bbt " << tmp.bbt()
|
||||||
|
<< " lock to " << tmp.lock_style()
|
||||||
|
;
|
||||||
|
|
||||||
|
if (tmp.is_explicit()) {
|
||||||
|
str << " tempo " << *((Tempo*) &tmp.metric())
|
||||||
|
<< " meter " << *((Meter*) &tmp.metric())
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_explicit_to (p, destination);
|
if (tmp.is_explicit() && tmp.ramped()) {
|
||||||
|
str << " ramp c/sc = " << tmp.metric().c_per_superclock() << " c/qn " << tmp.metric().c_per_quarter();
|
||||||
|
}
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******/
|
/*******/
|
||||||
|
|
@ -1212,39 +1319,17 @@ main ()
|
||||||
tmap.rebuild (SECONDS_TO_SUPERCLOCK (120));
|
tmap.rebuild (SECONDS_TO_SUPERCLOCK (120));
|
||||||
tmap.dump (std::cout);
|
tmap.dump (std::cout);
|
||||||
|
|
||||||
|
if (tmap.move_to (SECONDS_TO_SUPERCLOCK(23), SECONDS_TO_SUPERCLOCK (72))) {
|
||||||
|
tmap.rebuild (SECONDS_TO_SUPERCLOCK (120));
|
||||||
|
tmap.dump (std::cout);
|
||||||
|
}
|
||||||
|
|
||||||
|
TempoMapPoints grid;
|
||||||
|
tmap.get_grid (grid, SECONDS_TO_SUPERCLOCK (12), SECONDS_TO_SUPERCLOCK (44));
|
||||||
|
cout << "grid contains " << grid.size() << endl;
|
||||||
|
for (TempoMapPoints::iterator p = grid.begin(); p != grid.end(); ++p) {
|
||||||
|
cout << *p << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& str, Meter const & m)
|
|
||||||
{
|
|
||||||
return str << m.divisions_per_bar() << '/' << m.note_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& str, Tempo const & t)
|
|
||||||
{
|
|
||||||
return str << t.note_types_per_minute() << " 1/" << t.note_type() << " notes per minute (" << t.superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& str, TempoMapPoint const & tmp)
|
|
||||||
{
|
|
||||||
str << '@' << std::setw (12) << tmp.sclock() << ' ' << tmp.sclock() / (double) superclock_ticks_per_second
|
|
||||||
<< (tmp.is_explicit() ? " EXP" : " imp")
|
|
||||||
<< " qn " << tmp.quarters ()
|
|
||||||
<< " bbt " << tmp.bbt()
|
|
||||||
<< " lock to " << tmp.lock_style()
|
|
||||||
;
|
|
||||||
|
|
||||||
if (tmp.is_explicit()) {
|
|
||||||
str << " tempo " << *((Tempo*) &tmp.metric())
|
|
||||||
<< " meter " << *((Meter*) &tmp.metric())
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmp.is_explicit() && tmp.ramped()) {
|
|
||||||
str << " ramp c/sc = " << tmp.metric().c_per_superclock() << " c/qn " << tmp.metric().c_per_quarter();
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
29
nutemp/t.h
29
nutemp/t.h
|
|
@ -217,10 +217,11 @@ class LIBARDOUR_API TempoMapPoint
|
||||||
Timecode::BBT_Time const & bbt() const { return _bbt; }
|
Timecode::BBT_Time const & bbt() const { return _bbt; }
|
||||||
bool ramped() const { return metric().ramped(); }
|
bool ramped() const { return metric().ramped(); }
|
||||||
TempoMetric const & metric() const { return is_explicit() ? _explicit.metric : _reference->metric(); }
|
TempoMetric const & metric() const { return is_explicit() ? _explicit.metric : _reference->metric(); }
|
||||||
/* Implicit points are not allowed to return non-const references to their reference metric */
|
|
||||||
TempoMetric & metric() { if (is_explicit()) { return _explicit.metric; } throw BadTempoMetricLookup(); }
|
|
||||||
PositionLockStyle lock_style() const { return is_explicit() ? _explicit.lock_style : _reference->lock_style(); }
|
PositionLockStyle lock_style() const { return is_explicit() ? _explicit.lock_style : _reference->lock_style(); }
|
||||||
|
|
||||||
|
void compute_c_superclock (framecnt_t sr, superclock_t end_superclocks_per_note_type, superclock_t duration) { if (is_explicit()) { _explicit.metric.compute_c_superclock (sr, end_superclocks_per_note_type, duration); } }
|
||||||
|
void compute_c_quarters (framecnt_t sr, superclock_t end_superclocks_per_note_type, Evoral::Beats const & duration) { if (is_explicit()) { _explicit.metric.compute_c_quarters (sr, end_superclocks_per_note_type, duration); } }
|
||||||
|
|
||||||
/* None of these properties can be set for an Implicit point, because
|
/* None of these properties can be set for an Implicit point, because
|
||||||
* they are determined by the TempoMapPoint pointed to by _reference.
|
* they are determined by the TempoMapPoint pointed to by _reference.
|
||||||
*/
|
*/
|
||||||
|
|
@ -301,15 +302,13 @@ class LIBARDOUR_API TempoMap
|
||||||
|
|
||||||
void remove_explicit_point (superclock_t);
|
void remove_explicit_point (superclock_t);
|
||||||
|
|
||||||
void move_implicit (superclock_t current, superclock_t destination);
|
bool move_to (superclock_t current, superclock_t destination, bool push = false);
|
||||||
void move_explicit (superclock_t current, superclock_t destination);
|
|
||||||
|
bool set_tempo_and_meter (Tempo const &, Meter const &, superclock_t, bool ramp, bool flexible);
|
||||||
|
|
||||||
//bool set_tempo_at (Tempo const &, Evoral::Beats const &, PositionLockStyle psl, bool ramp = false);
|
|
||||||
bool set_tempo (Tempo const &, Timecode::BBT_Time const &, bool ramp = false);
|
bool set_tempo (Tempo const &, Timecode::BBT_Time const &, bool ramp = false);
|
||||||
bool set_tempo (Tempo const &, superclock_t, bool ramp = false);
|
bool set_tempo (Tempo const &, superclock_t, bool ramp = false);
|
||||||
|
|
||||||
//bool set_meter_at (Meter const &, Evoral::Beats const &);
|
|
||||||
|
|
||||||
bool set_meter (Meter const &, Timecode::BBT_Time const &);
|
bool set_meter (Meter const &, Timecode::BBT_Time const &);
|
||||||
bool set_meter (Meter const &, superclock_t);
|
bool set_meter (Meter const &, superclock_t);
|
||||||
|
|
||||||
|
|
@ -327,6 +326,16 @@ class LIBARDOUR_API TempoMap
|
||||||
superclock_t superclock_at (Evoral::Beats const &) const;
|
superclock_t superclock_at (Evoral::Beats const &) const;
|
||||||
superclock_t superclock_at (Timecode::BBT_Time const &) const;
|
superclock_t superclock_at (Timecode::BBT_Time const &) const;
|
||||||
|
|
||||||
|
TempoMapPoint const & const_point_at (superclock_t sc) const { return *const_iterator_at (sc); }
|
||||||
|
TempoMapPoint const & const_point_at (Evoral::Beats const & b) const { return *const_iterator_at (b); }
|
||||||
|
TempoMapPoint const & const_point_at (Timecode::BBT_Time const & bbt) const { return *const_iterator_at (bbt); }
|
||||||
|
|
||||||
|
TempoMapPoint const & const_point_after (superclock_t sc) const;
|
||||||
|
TempoMapPoint const & const_point_after (Evoral::Beats const & b) const;
|
||||||
|
TempoMapPoint const & const_point_after (Timecode::BBT_Time const & bbt) const;
|
||||||
|
|
||||||
|
void get_grid (TempoMapPoints& points, superclock_t start, superclock_t end);
|
||||||
|
|
||||||
struct EmptyTempoMapException : public std::exception {
|
struct EmptyTempoMapException : public std::exception {
|
||||||
virtual const char* what() const throw() { return "TempoMap is empty"; }
|
virtual const char* what() const throw() { return "TempoMap is empty"; }
|
||||||
};
|
};
|
||||||
|
|
@ -371,10 +380,6 @@ class LIBARDOUR_API TempoMap
|
||||||
TempoMapPoint & point_at (Evoral::Beats const & b) { return *iterator_at (b); }
|
TempoMapPoint & point_at (Evoral::Beats const & b) { return *iterator_at (b); }
|
||||||
TempoMapPoint & point_at (Timecode::BBT_Time const & bbt) { return *iterator_at (bbt); }
|
TempoMapPoint & point_at (Timecode::BBT_Time const & bbt) { return *iterator_at (bbt); }
|
||||||
|
|
||||||
TempoMapPoint const & const_point_at (superclock_t sc) const { return *const_iterator_at (sc); }
|
|
||||||
TempoMapPoint const & const_point_at (Evoral::Beats const & b) const { return *const_iterator_at (b); }
|
|
||||||
TempoMapPoint const & const_point_at (Timecode::BBT_Time const & bbt) const { return *const_iterator_at (bbt); }
|
|
||||||
|
|
||||||
Meter const & meter_at_locked (superclock_t sc) const { return const_point_at (sc).metric(); }
|
Meter const & meter_at_locked (superclock_t sc) const { return const_point_at (sc).metric(); }
|
||||||
Meter const & meter_at_locked (Evoral::Beats const & b) const { return const_point_at (b).metric(); }
|
Meter const & meter_at_locked (Evoral::Beats const & b) const { return const_point_at (b).metric(); }
|
||||||
Meter const & meter_at_locked (Timecode::BBT_Time const & bbt) const { return const_point_at (bbt).metric(); }
|
Meter const & meter_at_locked (Timecode::BBT_Time const & bbt) const { return const_point_at (bbt).metric(); }
|
||||||
|
|
@ -388,8 +393,6 @@ class LIBARDOUR_API TempoMap
|
||||||
superclock_t superclock_at_locked (Evoral::Beats const &) const;
|
superclock_t superclock_at_locked (Evoral::Beats const &) const;
|
||||||
superclock_t superclock_at_locked (Timecode::BBT_Time const &) const;
|
superclock_t superclock_at_locked (Timecode::BBT_Time const &) const;
|
||||||
|
|
||||||
void move_explicit_to (TempoMapPoints::iterator, superclock_t destination);
|
|
||||||
|
|
||||||
void rebuild_locked (superclock_t limit);
|
void rebuild_locked (superclock_t limit);
|
||||||
void dump_locked (std::ostream&);
|
void dump_locked (std::ostream&);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue