From 20e1b6b28700105fab86e7d73fe70e8563628a4a Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 30 Jun 2023 15:50:25 -0600 Subject: [PATCH] temporal: add API to clear tempos in various ways --- libs/temporal/tempo.cc | 112 ++++++++++++++++++++++++++++++++- libs/temporal/temporal/tempo.h | 3 + 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index ae0279e904..c139948256 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -1111,6 +1111,114 @@ TempoMap::add_meter (MeterPoint* mp) return ret; } +bool +TempoMap::clear_tempos_before (timepos_t const & t, bool stop_at_music_time) +{ + if (_tempos.size() < 2) { + return false; + } + + bool removed = false; + superclock_t sc = t.superclocks(); + Tempos::iterator tp = _tempos.end(); + --tp; + MusicTimePoint* mtp (nullptr); + + while (tp != _tempos.begin()) { + + if (tp->sclock() > sc) { + --tp; + mtp = nullptr; + continue; + } + + if ((mtp = dynamic_cast (&*tp)) && stop_at_music_time) { + break; + } + + Tempos::iterator nxt = tp; + --nxt; + + if (mtp) { + Meters::iterator mpi = _meters.s_iterator_to (*(static_cast (&*mtp))); + _meters.erase (mpi); + MusicTimes::iterator mtpi = _bartimes.s_iterator_to (*mtp); + _bartimes.erase (mtpi); + } + + Points::iterator pi = _points.s_iterator_to (*(static_cast (&*tp))); + + if (pi != _points.end()) { + _points.erase (pi); + } + + _tempos.erase (tp); + removed = true; + tp = nxt; + mtp = nullptr; + } + + if (removed) { + reset_starting_at (sc); + } + + return removed; +} + +bool +TempoMap::clear_tempos_after (timepos_t const & t, bool stop_at_music_time) +{ + if (_tempos.size() < 2) { + return false; + } + + bool removed = false; + superclock_t sc = t.superclocks(); + Tempos::iterator tp = _tempos.begin(); + MusicTimePoint* mtp (nullptr); + ++tp; + + while (tp != _tempos.end()) { + + if (tp->sclock() < sc) { + ++tp; + mtp = nullptr; + continue; + } + + if ((mtp = dynamic_cast (&*tp)) && stop_at_music_time) { + break; + } + + Tempos::iterator nxt = tp; + ++nxt; + + if (mtp) { + Meters::iterator mpi = _meters.s_iterator_to (*(static_cast (&*mtp))); + _meters.erase (mpi); + MusicTimes::iterator mtpi = _bartimes.s_iterator_to (*mtp); + _bartimes.erase (mtpi); + } + + Points::iterator pi = _points.s_iterator_to (*(static_cast (&*tp))); + + if (pi != _points.end()) { + _points.erase (pi); + } + + _tempos.erase (tp); + removed = true; + tp = nxt; + mtp = nullptr; + } + + if (removed) { + reset_starting_at (sc); + } + + return removed; +} + void TempoMap::change_tempo (TempoPoint & p, Tempo const & t) { @@ -2378,7 +2486,7 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t rstart, superclock_t end, * arbitrarily placed with respect to the earlier elements of the tempo * map. * - * So we can just start at the later of the two of them, + * So we can just start at the later of the two of them, */ superclock_t start; @@ -4911,5 +5019,3 @@ TempoMapCutBuffer::clear () _bartimes.clear (); _points.clear (); } - - diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h index 182e5ec72a..d60211060b 100644 --- a/libs/temporal/temporal/tempo.h +++ b/libs/temporal/temporal/tempo.h @@ -773,6 +773,9 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible LIBTEMPORAL_API void stretch_tempo (TempoPoint& ts, double new_npm); LIBTEMPORAL_API void stretch_tempo_end (TempoPoint* ts, samplepos_t sample, samplepos_t end_sample); + LIBTEMPORAL_API bool clear_tempos_before (timepos_t const &, bool stop_at_music_time); + LIBTEMPORAL_API bool clear_tempos_after (timepos_t const &, bool stop_at_music_time); + /* END OF MODIFYING METHODS */ /* rather than giving direct access to the intrusive list members,