temporal: remove TempoMap::insert_time() and use shift() instead
The former was incorrectly implemented, and the latter has already been tested more in real life. We should likely remove ::remove_time also and use shift() there too, but that requires testing negative shifts more broadly.
This commit is contained in:
parent
a33514e270
commit
da175cc2e8
@ -8585,9 +8585,8 @@ Editor::insert_time (timepos_t const & pos, timecnt_t const & samples, InsertTim
|
||||
in_command = true;
|
||||
}
|
||||
TempoMap::WritableSharedPtr tmap (TempoMap::write_copy());
|
||||
|
||||
XMLNode& before (tmap->get_state());
|
||||
tmap->insert_time (pos, samples);
|
||||
tmap->shift (pos, samples);
|
||||
XMLNode& after (tmap->get_state());
|
||||
_session->add_command (new Temporal::TempoCommand (_("insert time"), &before, &after));
|
||||
|
||||
|
@ -1113,6 +1113,11 @@ TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool
|
||||
void
|
||||
TempoMap::shift (timepos_t const & at, timecnt_t const & by)
|
||||
{
|
||||
if (at == std::numeric_limits<timepos_t>::min()) {
|
||||
/* can't insert time at the front of the map: those entries are fixed */
|
||||
return;
|
||||
}
|
||||
|
||||
timecnt_t abs_by (by.abs());
|
||||
superclock_t distance = abs_by.superclocks ();
|
||||
superclock_t at_superclocks = abs_by.superclocks ();
|
||||
@ -3558,138 +3563,6 @@ TempoMap::n_tempos () const
|
||||
return _tempos.size();
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::insert_time (timepos_t const & pos, timecnt_t const & duration)
|
||||
{
|
||||
TEMPO_MAP_ASSERT (!_tempos.empty());
|
||||
TEMPO_MAP_ASSERT (!_meters.empty());
|
||||
|
||||
if (pos == std::numeric_limits<timepos_t>::min()) {
|
||||
/* can't insert time at the front of the map: those entries are fixed */
|
||||
return;
|
||||
}
|
||||
|
||||
Tempos::iterator t (_tempos.begin());
|
||||
Meters::iterator m (_meters.begin());
|
||||
MusicTimes::iterator b (_bartimes.begin());
|
||||
|
||||
TempoPoint current_tempo = *t;
|
||||
MeterPoint current_meter = *m;
|
||||
MusicTimePoint current_time_point (*this, 0, Beats(), BBT_Time(), current_tempo, current_meter);
|
||||
|
||||
if (_bartimes.size() > 0) {
|
||||
current_time_point = *b;
|
||||
}
|
||||
|
||||
superclock_t sc;
|
||||
Beats beats;
|
||||
BBT_Time bbt;
|
||||
|
||||
/* set these to true so that we set current_* on our first pass
|
||||
* through the while loop(s)
|
||||
*/
|
||||
|
||||
bool moved_tempo = true;
|
||||
bool moved_meter = true;
|
||||
bool moved_bartime = true;
|
||||
|
||||
switch (duration.time_domain()) {
|
||||
case AudioTime:
|
||||
sc = pos.superclocks();
|
||||
|
||||
/* handle a common case quickly */
|
||||
|
||||
if ((_tempos.size() < 2 || sc > _tempos.back().sclock()) &&
|
||||
(_meters.size() < 2 || sc > _meters.back().sclock()) &&
|
||||
(_bartimes.size() < 2 || (_bartimes.empty() || sc > _bartimes.back().sclock()))) {
|
||||
|
||||
/* only one tempo, plus one meter and zero or
|
||||
one bartimes, or insertion point is after last
|
||||
item. nothing to do here.
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* advance fundamental iterators to correct position */
|
||||
|
||||
while (t != _tempos.end() && t->sclock() < sc) ++t;
|
||||
while (m != _meters.end() && m->sclock() < sc) ++m;
|
||||
while (b != _bartimes.end() && b->sclock() < sc) ++b;
|
||||
|
||||
while (t != _tempos.end() && m != _meters.end() && b != _bartimes.end()) {
|
||||
|
||||
if (moved_tempo && t != _tempos.end()) {
|
||||
current_tempo = *t;
|
||||
moved_tempo = false;
|
||||
}
|
||||
if (moved_meter && m != _meters.end()) {
|
||||
current_meter = *m;
|
||||
moved_meter = false;
|
||||
}
|
||||
if (moved_bartime && b != _bartimes.end()) {
|
||||
current_time_point = *b;
|
||||
moved_bartime = false;
|
||||
}
|
||||
|
||||
/* for each of t, m and b:
|
||||
|
||||
if the point is earlier than the other two,
|
||||
recompute the superclock, beat and bbt
|
||||
positions, and reset the point.
|
||||
*/
|
||||
|
||||
if (t->sclock() < m->sclock() && t->sclock() < b->sclock()) {
|
||||
|
||||
sc = t->sclock() + duration.superclocks();
|
||||
beats = current_tempo.quarters_at_superclock (sc);
|
||||
/* round tempo to beats */
|
||||
beats = beats.round_to_beat ();
|
||||
sc = current_tempo.superclock_at (beats);
|
||||
bbt = current_meter.bbt_at (beats);
|
||||
|
||||
t->set (sc, beats, bbt);
|
||||
++t;
|
||||
moved_tempo = true;
|
||||
}
|
||||
|
||||
if (m->sclock() < t->sclock() && m->sclock() < b->sclock()) {
|
||||
|
||||
sc = m->sclock() + duration.superclocks();
|
||||
beats = current_tempo.quarters_at_superclock (sc);
|
||||
/* round meter to bars */
|
||||
bbt = current_meter.bbt_at (beats);
|
||||
beats = current_meter.quarters_at (current_meter.round_to_bar(bbt));
|
||||
/* recompute */
|
||||
sc = current_tempo.superclock_at (beats);
|
||||
|
||||
m->set (sc, beats, bbt);
|
||||
++m;
|
||||
moved_meter = true;
|
||||
}
|
||||
|
||||
if (b->sclock() < t->sclock() && b->sclock() < m->sclock()) {
|
||||
|
||||
sc = b->sclock() + duration.superclocks();
|
||||
beats = current_tempo.quarters_at_superclock (sc);
|
||||
/* round bartime to beats */
|
||||
beats = beats.round_to_beat();
|
||||
sc = current_tempo.superclock_at (beats);
|
||||
bbt = current_meter.bbt_at (beats);
|
||||
|
||||
m->set (sc, beats, bbt);
|
||||
++m;
|
||||
moved_meter = true;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case BeatTime:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMap::remove_time (timepos_t const & pos, timecnt_t const & duration)
|
||||
{
|
||||
|
@ -781,7 +781,6 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
|
||||
LIBTEMPORAL_API bool set_ramped (TempoPoint&, bool);
|
||||
LIBTEMPORAL_API bool set_continuing (TempoPoint&, bool);
|
||||
|
||||
LIBTEMPORAL_API void insert_time (timepos_t const & pos, timecnt_t const & duration);
|
||||
LIBTEMPORAL_API bool remove_time (timepos_t const & pos, timecnt_t const & duration);
|
||||
|
||||
LIBTEMPORAL_API void change_tempo (TempoPoint&, Tempo const&);
|
||||
|
Loading…
Reference in New Issue
Block a user