diff options
author | nick_m <mainsbridge@gmail.com> | 2016-10-16 02:33:49 +1100 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2016-10-16 02:33:49 +1100 |
commit | 3a0a628a75fdbc9da1c0ad2a21f46286a5184503 (patch) | |
tree | aa5baf48f846314a54820473d1a7b375655e901d /libs | |
parent | 9698f16aee5f91d158551d333fe0fb1b23d22859 (diff) |
Rework duration clock and TempoMap::insert_time to include meter at offset.
- should fix 7072
- also fixes scroll behavior over multiple tempi.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/tempo.cc | 172 |
1 files changed, 54 insertions, 118 deletions
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 27ba9f6223..1d6f4eccf2 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -3192,11 +3192,52 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir) { Glib::Threads::RWLock::ReaderLock lm (lock); - const double tick_at_time = max (0.0, beat_at_frame_locked (_metrics, pos)) * BBT_Time::ticks_per_beat; - const double bbt_ticks = bbt.ticks + (bbt.beats * BBT_Time::ticks_per_beat); - const double total_beats = (tick_at_time + bbt_ticks) / BBT_Time::ticks_per_beat; + BBT_Time pos_bbt = bbt_at_frame_locked (_metrics, pos); + const framecnt_t offset = frame_at_bbt_locked (_metrics, pos_bbt); + const double divisions = meter_section_at_frame_locked (_metrics, pos).divisions_per_bar(); - return frame_at_beat_locked (_metrics, total_beats); + if (dir > 0) { + pos_bbt.bars += bbt.bars; + + pos_bbt.ticks += bbt.ticks; + if ((double) pos_bbt.ticks > BBT_Time::ticks_per_beat) { + pos_bbt.beats += 1; + pos_bbt.ticks -= BBT_Time::ticks_per_beat; + } + + pos_bbt.beats += bbt.beats; + if ((double) pos_bbt.beats > divisions) { + pos_bbt.bars += 1; + pos_bbt.beats -= divisions; + } + + return frame_at_bbt_locked (_metrics, pos_bbt) - offset; + } else { + pos_bbt.bars -= bbt.bars; + + if (pos_bbt.ticks < bbt.ticks) { + if (pos_bbt.beats == 1) { + pos_bbt.bars--; + pos_bbt.beats = divisions; + } else { + pos_bbt.beats--; + } + pos_bbt.ticks = BBT_Time::ticks_per_beat - (bbt.ticks - pos_bbt.ticks); + } else { + pos_bbt.ticks -= bbt.ticks; + } + + if (pos_bbt.beats <= bbt.beats) { + pos_bbt.bars--; + pos_bbt.beats = divisions - (bbt.beats - pos_bbt.beats); + } else { + pos_bbt.beats -= bbt.beats; + } + + return offset - frame_at_bbt_locked (_metrics, pos_bbt); + } + + return 0; } framepos_t @@ -3890,129 +3931,24 @@ TempoMap::n_meters() const void TempoMap::insert_time (framepos_t where, framecnt_t amount) { - { - Glib::Threads::RWLock::WriterLock lm (lock); - for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) { - if ((*i)->frame() >= where && (*i)->movable ()) { - (*i)->set_frame ((*i)->frame() + amount); - } - } - - /* now reset the BBT time of all metrics, based on their new - * audio time. This is the only place where we do this reverse - * timestamp. - */ - - Metrics::iterator i; - const MeterSection* meter; - const TempoSection* tempo; - MeterSection *m; - TempoSection *t; - - meter = &first_meter (); - tempo = &first_tempo (); - - BBT_Time start; - BBT_Time end; - - // cerr << "\n###################### TIMESTAMP via AUDIO ##############\n" << endl; - - bool first = true; - MetricSection* prev = 0; + for (Metrics::reverse_iterator i = _metrics.rbegin(); i != _metrics.rend(); ++i) { + if ((*i)->frame() >= where && (*i)->movable ()) { + MeterSection* ms; + TempoSection* ts; - for (i = _metrics.begin(); i != _metrics.end(); ++i) { - - BBT_Time bbt; - //TempoMetric metric (*meter, *tempo); - MeterSection* ms = const_cast<MeterSection*>(meter); - TempoSection* ts = const_cast<TempoSection*>(tempo); - if (prev) { - if (ts){ - if ((t = dynamic_cast<TempoSection*>(prev)) != 0) { - if (!t->active()) { - continue; - } - ts->set_pulse (t->pulse()); - } - if ((m = dynamic_cast<MeterSection*>(prev)) != 0) { - ts->set_pulse (m->pulse()); - } - ts->set_frame (prev->frame()); - - } - if (ms) { - if ((m = dynamic_cast<MeterSection*>(prev)) != 0) { - pair<double, BBT_Time> start = make_pair (m->beat(), m->bbt()); - ms->set_beat (start); - ms->set_pulse (m->pulse()); - } - if ((t = dynamic_cast<TempoSection*>(prev)) != 0) { - if (!t->active()) { - continue; - } - const double beat = beat_at_pulse_locked (_metrics, t->pulse()); - pair<double, BBT_Time> start = make_pair (beat, bbt_at_beat_locked (_metrics, beat)); - ms->set_beat (start); - ms->set_pulse (t->pulse()); - } - ms->set_frame (prev->frame()); - } - - } else { - // metric will be at frames=0 bbt=1|1|0 by default - // which is correct for our purpose + if ((ms = dynamic_cast <MeterSection*>(*i)) != 0) { + gui_move_meter (ms, (*i)->frame() + amount); } - // cerr << bbt << endl; - - if ((t = dynamic_cast<TempoSection*>(*i)) != 0) { - if (!t->active()) { - continue; - } - t->set_pulse (pulse_at_frame_locked (_metrics, m->frame())); - tempo = t; - // cerr << "NEW TEMPO, frame = " << (*i)->frame() << " beat = " << (*i)->pulse() <<endl; - } else if ((m = dynamic_cast<MeterSection*>(*i)) != 0) { - bbt = bbt_at_frame_locked (_metrics, m->frame()); - - // cerr << "timestamp @ " << (*i)->frame() << " with " << bbt.bars << "|" << bbt.beats << "|" << bbt.ticks << " => "; - - if (first) { - first = false; - } else { - - if (bbt.ticks > BBT_Time::ticks_per_beat/2) { - /* round up to next beat */ - bbt.beats += 1; - } - - bbt.ticks = 0; - - if (bbt.beats != 1) { - /* round up to next bar */ - bbt.bars += 1; - bbt.beats = 1; - } - } - pair<double, BBT_Time> start = make_pair (max (0.0, beat_at_frame_locked (_metrics, m->frame())), bbt); - m->set_beat (start); - m->set_pulse (pulse_at_frame_locked (_metrics, m->frame())); - meter = m; - // cerr << "NEW METER, frame = " << (*i)->frame() << " beat = " << (*i)->pulse() <<endl; - } else { - fatal << _("programming error: unhandled MetricSection type") << endmsg; - abort(); /*NOTREACHED*/ + if ((ts = dynamic_cast <TempoSection*>(*i)) != 0) { + gui_move_tempo (ts, (*i)->frame() + amount, 0); } - - prev = (*i); } - - recompute_map (_metrics); } - PropertyChanged (PropertyChange ()); } + bool TempoMap::remove_time (framepos_t where, framecnt_t amount) { |