X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftempo.cc;h=0c328c0b1edbc5ac254b7b00541e9707de89eae2;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=417c82ea267e42ec73d6b327f2b1591b40c067ad;hpb=7a6f8abc1d524367a843dd2acf6824c62e77940f;p=ardour.git diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 417c82ea26..0c328c0b1e 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -33,7 +33,7 @@ #include "ardour/lmath.h" #include "ardour/tempo.h" -#include "i18n.h" +#include "pbd/i18n.h" #include using namespace std; @@ -772,13 +772,13 @@ TempoMap::remove_meter (const MeterSection& tempo, bool complete_operation) bool TempoMap::remove_meter_locked (const MeterSection& meter) { - Metrics::iterator i; - for (i = _metrics.begin(); i != _metrics.end(); ++i) { - TempoSection* t = 0; - if ((t = dynamic_cast (*i)) != 0) { - if (meter.frame() == (*i)->frame()) { - if (t->locked_to_meter()) { + if (meter.position_lock_style() == AudioTime) { + /* remove meter-locked tempo */ + for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) { + TempoSection* t = 0; + if ((t = dynamic_cast (*i)) != 0) { + if (t->locked_to_meter() && meter.frame() == (*i)->frame()) { delete (*i); _metrics.erase (i); break; @@ -787,7 +787,7 @@ TempoMap::remove_meter_locked (const MeterSection& meter) } } - for (i = _metrics.begin(); i != _metrics.end(); ++i) { + for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) { if (dynamic_cast (*i) != 0) { if (meter.frame() == (*i)->frame()) { if ((*i)->movable()) { @@ -981,6 +981,7 @@ TempoMap::add_tempo_locked (const Tempo& tempo, double pulse, framepos_t frame TempoSection* t = new TempoSection (pulse, frame, tempo.beats_per_minute(), tempo.note_type(), type, pls); t->set_locked_to_meter (locked_to_meter); bool solved = false; + do_insert (t); if (recompute) { @@ -993,8 +994,8 @@ TempoMap::add_tempo_locked (const Tempo& tempo, double pulse, framepos_t frame } if (!solved && recompute) { - remove_tempo_locked (*t); - return 0; + warning << "Adding tempo may have left the tempo map unsolved." << endmsg; + recompute_map (_metrics); } return t; @@ -1087,8 +1088,11 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, const BBT_Time& whe } if (!solved && recompute) { - remove_meter_locked (*new_meter); - return 0; + /* if this has failed to solve, there is little we can do other than to ensure that + the new map is recalculated. + */ + warning << "Adding meter may have left the tempo map unsolved." << endmsg; + recompute_map (_metrics); } return new_meter; @@ -1246,7 +1250,7 @@ TempoMap::first_tempo () return *t; } void -TempoMap::recompute_tempos (Metrics& metrics) +TempoMap::recompute_tempi (Metrics& metrics) { TempoSection* prev_t = 0; @@ -1386,7 +1390,7 @@ TempoMap::recompute_map (Metrics& metrics, framepos_t end) return; } - recompute_tempos (metrics); + recompute_tempi (metrics); recompute_meters (metrics); } @@ -2111,10 +2115,17 @@ TempoMap::check_solved (const Metrics& metrics) const m = static_cast (*i); if (prev_m && m->position_lock_style() == AudioTime) { const TempoSection* t = &tempo_section_at_frame_locked (metrics, m->frame() - 1); - const double nascent_m_pulse = ((m->beat() - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse(); - const framepos_t nascent_m_frame = t->frame_at_pulse (nascent_m_pulse, _frame_rate); - - if (t && (nascent_m_frame > m->frame() || nascent_m_frame < 0)) { + const framepos_t nascent_m_frame = t->frame_at_pulse (m->pulse(), _frame_rate); + /* Here we check that a preceding section of music doesn't overlap a subsequent one. + It is complicated by the fact that audio locked meters represent a discontinuity in the pulse + (they place an exact pulse at a particular time expressed only in frames). + This has the effect of shifting the calculated frame at the meter pulse (wrt the previous section of music) + away from its actual frame (which is now the frame location of the exact pulse). + This can result in the calculated frame (from the previous musical section) + differing from the exact frame by one sample. + Allow for that. + */ + if (t && (nascent_m_frame > m->frame() + 1 || nascent_m_frame < 0)) { return false; } } @@ -2214,7 +2225,7 @@ TempoMap::solve_map_frame (Metrics& imaginary, TempoSection* section, const fram } #if (0) - recompute_tempos (imaginary); + recompute_tempi (imaginary); if (check_solved (imaginary)) { return true; @@ -2226,7 +2237,7 @@ TempoMap::solve_map_frame (Metrics& imaginary, TempoSection* section, const fram MetricSectionFrameSorter fcmp; imaginary.sort (fcmp); - recompute_tempos (imaginary); + recompute_tempi (imaginary); if (check_solved (imaginary)) { return true; @@ -2280,7 +2291,7 @@ TempoMap::solve_map_pulse (Metrics& imaginary, TempoSection* section, const doub } #if (0) - recompute_tempos (imaginary); + recompute_tempi (imaginary); if (check_solved (imaginary)) { return true; @@ -2292,7 +2303,7 @@ TempoMap::solve_map_pulse (Metrics& imaginary, TempoSection* section, const doub MetricSectionSorter cmp; imaginary.sort (cmp); - recompute_tempos (imaginary); + recompute_tempi (imaginary); /* Reordering * XX need a restriction here, but only for this case, * as audio locked tempos don't interact in the same way. @@ -2762,7 +2773,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const framepos_t& frame) if (solve_map_frame (future_map, copy, frame)) { solve_map_frame (_metrics, ms, frame); - recompute_tempos (_metrics); + recompute_tempi (_metrics); } } } else { @@ -2775,7 +2786,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const framepos_t& frame) if (solve_map_bbt (future_map, copy, bbt)) { solve_map_bbt (_metrics, ms, bbt); - recompute_tempos (_metrics); + recompute_tempi (_metrics); } } } @@ -2798,7 +2809,7 @@ TempoMap::gui_change_tempo (TempoSection* ts, const Tempo& bpm) Glib::Threads::RWLock::WriterLock lm (lock); TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts); tempo_copy->set_beats_per_minute (bpm.beats_per_minute()); - recompute_tempos (future_map); + recompute_tempi (future_map); if (check_solved (future_map)) { ts->set_beats_per_minute (bpm.beats_per_minute()); @@ -2947,12 +2958,12 @@ TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const fra } new_bpm = min (new_bpm, (double) 1000.0); prev_t->set_beats_per_minute (new_bpm); - recompute_tempos (future_map); + recompute_tempi (future_map); recompute_meters (future_map); if (check_solved (future_map)) { ts->set_beats_per_minute (new_bpm); - recompute_tempos (_metrics); + recompute_tempi (_metrics); recompute_meters (_metrics); } } @@ -2967,7 +2978,7 @@ TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const fra } double -TempoMap::exact_beat_at_frame (const framepos_t& frame, const int32_t& sub_num) +TempoMap::exact_beat_at_frame (const framepos_t& frame, const int32_t sub_num) { Glib::Threads::RWLock::ReaderLock lm (lock); @@ -2975,7 +2986,7 @@ TempoMap::exact_beat_at_frame (const framepos_t& frame, const int32_t& sub_num) } double -TempoMap::exact_beat_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t& sub_num) +TempoMap::exact_beat_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t sub_num) { double beat = beat_at_frame_locked (metrics, frame); if (sub_num > 1) {