From 7138a0baa0964e07457d01fe0aa3aef99d4eaced Mon Sep 17 00:00:00 2001 From: nick_m Date: Fri, 6 Jan 2017 02:20:45 +1100 Subject: [PATCH] prevent meter-locked tempi from being moved directly when replacing. - the audio-locked meter owns it. --- libs/ardour/ardour/tempo.h | 4 ++- libs/ardour/tempo.cc | 53 +++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index bd940f991a..f51f617a01 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -352,6 +352,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible double frames_per_quarter_note_at (const framepos_t&, const framecnt_t& sr) const; const TempoSection& tempo_section_at_frame (framepos_t frame) const; + TempoSection& tempo_section_at_frame (framepos_t frame); const MeterSection& meter_section_at_frame (framepos_t frame) const; const MeterSection& meter_section_at_beat (double beat) const; @@ -380,7 +381,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void remove_tempo (const TempoSection&, bool send_signal); void remove_meter (const MeterSection&, bool send_signal); - void replace_tempo (const TempoSection&, const Tempo&, const double& pulse, const framepos_t& frame + void replace_tempo (TempoSection&, const Tempo&, const double& pulse, const framepos_t& frame , TempoSection::Type type, PositionLockStyle pls); void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls); @@ -533,6 +534,7 @@ private: double quarter_notes_between_frames_locked (const Metrics& metrics, const framecnt_t start, const framecnt_t end) const; const TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute) const; + TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute); const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const; const MeterSection& meter_section_at_minute_locked (const Metrics& metrics, double minute) const; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index cf269232d9..a23743820c 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1075,7 +1075,7 @@ TempoMap::add_tempo (const Tempo& tempo, const double& pulse, const framepos_t& } void -TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const double& pulse, const framepos_t& frame, TempoSection::Type type, PositionLockStyle pls) +TempoMap::replace_tempo (TempoSection& ts, const Tempo& tempo, const double& pulse, const framepos_t& frame, TempoSection::Type type, PositionLockStyle pls) { if (tempo.note_types_per_minute() <= 0.0) { return; @@ -1086,9 +1086,18 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const doubl { Glib::Threads::RWLock::WriterLock lm (lock); TempoSection& first (first_tempo()); - if (ts.frame() != first.frame()) { - remove_tempo_locked (ts); - add_tempo_locked (tempo, pulse, minute_at_frame (frame), type, pls, true, locked_to_meter); + if (!ts.initial()) { + if (ts.locked_to_meter()) { + ts.set_type (type); + { + /* cannot move a meter-locked tempo section */ + *static_cast(&ts) = tempo; + recompute_map (_metrics); + } + } else { + remove_tempo_locked (ts); + add_tempo_locked (tempo, pulse, minute_at_frame (frame), type, pls, true, locked_to_meter); + } } else { first.set_type (type); first.set_pulse (0.0); @@ -3990,6 +3999,14 @@ TempoMap::tempo_section_at_frame (framepos_t frame) const return tempo_section_at_minute_locked (_metrics, minute_at_frame (frame)); } +TempoSection& +TempoMap::tempo_section_at_frame (framepos_t frame) +{ + Glib::Threads::RWLock::ReaderLock lm (lock); + + return tempo_section_at_minute_locked (_metrics, minute_at_frame (frame)); +} + const TempoSection& TempoMap::tempo_section_at_minute_locked (const Metrics& metrics, double minute) const { @@ -4019,7 +4036,35 @@ TempoMap::tempo_section_at_minute_locked (const Metrics& metrics, double minute) return *prev; } +TempoSection& +TempoMap::tempo_section_at_minute_locked (const Metrics& metrics, double minute) +{ + TempoSection* prev = 0; + TempoSection* t; + + for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { + + if ((*i)->is_tempo()) { + t = static_cast (*i); + if (!t->active()) { + continue; + } + if (prev && t->minute() > minute) { + break; + } + + prev = t; + } + } + + if (prev == 0) { + fatal << endmsg; + abort(); /*NOTREACHED*/ + } + + return *prev; +} const TempoSection& TempoMap::tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const {