diff options
-rw-r--r-- | gtk2_ardour/tempo_dialog.cc | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 10 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 160 |
3 files changed, 87 insertions, 85 deletions
diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc index eef19e22a5..0d982a4085 100644 --- a/gtk2_ardour/tempo_dialog.cc +++ b/gtk2_ardour/tempo_dialog.cc @@ -277,7 +277,7 @@ TempoDialog::entry_key_release (GdkEventKey*) get_bbt_time (bbt); if (_section && is_user_input_valid()) { - set_response_sensitive (RESPONSE_ACCEPT, _map->bbt_valid (_section, Tempo (get_bpm(), get_note_type()), bbt)); + set_response_sensitive (RESPONSE_ACCEPT, _map->can_solve_bbt (_section, Tempo (get_bpm(), get_note_type()), bbt)); } else { set_response_sensitive (RESPONSE_ACCEPT, is_user_input_valid()); } diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 5fb9275df8..10f01643bf 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -386,7 +386,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void gui_move_meter (MeterSection*, const Meter& mt, const framepos_t& frame); void gui_move_meter (MeterSection*, const Meter& mt, const double& beat); - bool bbt_valid (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt); + bool can_solve_bbt (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt); void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where); void replace_meter (const MeterSection&, const Meter&, const framepos_t& frame); @@ -437,10 +437,10 @@ private: framecnt_t frame_at_tick_locked (const Metrics& metrics, double tick) const; framepos_t frame_time_locked (Metrics& metrics, const Timecode::BBT_Time&); - void get_new_order (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame); - void get_new_order (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& beat); - void get_new_order (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame); - void get_new_order (Metrics& metrics, MeterSection* section, const Meter& mt, const double& beat); + bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame); + bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& beat); + void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame); + void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const double& beat); friend class ::BBTTest; friend class ::FrameposPlusBeatsTest; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 0ea2a43857..63441b0d08 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1084,19 +1084,39 @@ TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BB { Glib::Threads::RWLock::ReaderLock lm (lock); Metrics future_map; + framepos_t ret = 0; TempoSection* new_section = copy_metrics_and_point (future_map, section); double const beat = bbt_to_beats_locked (future_map, bbt); - get_new_order (future_map, new_section, bpm, beat); + if (solve_map (future_map, new_section, bpm, beat)) { + ret = new_section->frame(); + } else { + ret = frame_at_beat_locked (_metrics, beat); + } - return new_section->frame(); + Metrics::const_iterator d = future_map.begin(); + while (d != future_map.end()) { + delete (*d); + ++d; + } + return ret; } void TempoMap::gui_move_tempo (TempoSection* ts, const Tempo& bpm, const framepos_t& frame) { + Metrics future_map; { Glib::Threads::RWLock::WriterLock lm (lock); - get_new_order (_metrics, ts, bpm, frame); + TempoSection* new_section = copy_metrics_and_point (future_map, ts); + if (solve_map (future_map, new_section, bpm, frame)) { + solve_map (_metrics, ts, bpm, frame); + } + } + + Metrics::const_iterator d = future_map.begin(); + while (d != future_map.end()) { + delete (*d); + ++d; } MetricPositionChanged (); // Emit Signal @@ -1107,7 +1127,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t& { { Glib::Threads::RWLock::WriterLock lm (lock); - get_new_order (_metrics, ms, mt, frame); + solve_map (_metrics, ms, mt, frame); } MetricPositionChanged (); // Emit Signal @@ -1118,7 +1138,7 @@ TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat { { Glib::Threads::RWLock::WriterLock lm (lock); - get_new_order (_metrics, ms, mt, beat); + solve_map (_metrics, ms, mt, beat); } MetricPositionChanged (); // Emit Signal @@ -1162,7 +1182,7 @@ TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section) } bool -TempoMap::bbt_valid (TempoSection* ts, const Tempo& bpm, const BBT_Time& bbt) +TempoMap::can_solve_bbt (TempoSection* ts, const Tempo& bpm, const BBT_Time& bbt) { Metrics copy; TempoSection* new_section = 0; @@ -1174,26 +1194,14 @@ TempoMap::bbt_valid (TempoSection* ts, const Tempo& bpm, const BBT_Time& bbt) } double const beat = bbt_to_beats_locked (copy, bbt); - get_new_order (copy, new_section, bpm, beat); + ret = solve_map (copy, new_section, bpm, beat); - /* invalid ordering means an impossible arrangement */ - TempoSection* prev_ts = 0; - for (Metrics::const_iterator i = copy.begin(); i != copy.end(); ++i) { - TempoSection* t; - if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { - if (prev_ts) { - if (t->frame() < prev_ts->frame() || t->beat() < prev_ts->beat()) { - ret = false; - } - } - prev_ts = t; - } - } Metrics::const_iterator d = copy.begin(); while (d != copy.end()) { delete (*d); ++d; } + return ret; } @@ -1343,21 +1351,11 @@ TempoMap::recompute_tempos (Metrics& metrics) if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { if (prev_ts) { if (t->position_lock_style() == AudioTime) { - if (prev_ts->position_lock_style() == AudioTime) { - /* compute c from t */ - prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate)); - } else { - prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate)); } else { - if (prev_ts->position_lock_style() == AudioTime) { - prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); - } else { - /* compute c from t */ - prev_ts->set_c_func(t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate)); } @@ -1714,10 +1712,11 @@ TempoMap::frame_time_locked (Metrics& metrics, const BBT_Time& bbt) return ret; } -void -TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame) +bool +TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame) { TempoSection* prev_ts = 0; + bool ret = true; section->set_frame (frame); MetricSectionFrameSorter fcmp; @@ -1730,40 +1729,24 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& if (prev_ts) { if (t == section) { /* we've already set the frame - set the beat */ - if (prev_ts->position_lock_style() == MusicTime) { - prev_ts->set_c_func (prev_ts->compute_c_func_frame (bpm.beats_per_minute(), frame, _frame_rate)); - - } else { - prev_ts->set_c_func (section->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_frame (bpm.beats_per_minute(), frame, _frame_rate)); section->set_beat (prev_ts->beat_at_tempo (bpm.beats_per_minute(), frame, _frame_rate)); prev_ts = t; continue; } if (t->position_lock_style() == AudioTime) { - if (prev_ts->position_lock_style() == AudioTime) { - /* compute c from t */ - prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate)); - } else { - prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate)); - } else { - if (prev_ts->position_lock_style() == AudioTime) { - prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); - } else { - /* compute c from t */ - prev_ts->set_c_func(t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate)); - } } prev_ts = t; } } recompute_meters (imaginary); + imaginary.sort (fcmp); if (section->position_lock_style() == MusicTime) { @@ -1774,7 +1757,22 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& } else { recompute_map (imaginary); } -/* + + /* + prev_ts = 0; + for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) { + TempoSection* t; + if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + if (prev_ts) { + if (t->frame() < prev_ts->frame()) { + ret = false; + } + } + prev_ts = t; + } + } + + /* prev_ts = 0; std::cerr << "dumping frame order ------" << std::endl;; for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) { @@ -1793,13 +1791,16 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& } } std::cerr << "end dump ------" << std::endl; -*/ + */ + + return ret; } -void -TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& beat) +bool +TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& beat) { TempoSection* prev_ts = 0; + bool ret = true; section->set_beat (beat); MetricSectionSorter cmp; @@ -1812,31 +1813,17 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& if (prev_ts) { if (t == section) { /* we've already set the beat - set the frame */ - if (prev_ts->position_lock_style() == AudioTime) { - prev_ts->set_c_func (prev_ts->compute_c_func_beat (bpm.beats_per_minute(), beat, _frame_rate)); - } else { - prev_ts->set_c_func (t->compute_c_func_beat (prev_ts->beats_per_minute(), prev_ts->beat(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_beat (bpm.beats_per_minute(), beat, _frame_rate)); t->set_frame (prev_ts->frame_at_tempo (bpm.beats_per_minute(), beat, _frame_rate)); prev_ts = t; continue; } if (t->position_lock_style() == AudioTime) { - if (prev_ts->position_lock_style() == AudioTime) { - /* compute c from t */ - prev_ts->set_c_func (t->compute_c_func_frame (prev_ts->beats_per_minute(), prev_ts->frame(), _frame_rate)); - } else { - prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->beats_per_minute(), t->frame(), _frame_rate)); t->set_beat (prev_ts->beat_at_tempo (t->beats_per_minute(), t->frame(), _frame_rate)); } else { - if (prev_ts->position_lock_style() == AudioTime) { - prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); - } else { - /* compute c from t (fixed music time to fixed music time)*/ - prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); - } + prev_ts->set_c_func (prev_ts->compute_c_func_beat (t->beats_per_minute(), t->beat(), _frame_rate)); t->set_frame (prev_ts->frame_at_tempo (t->beats_per_minute(), t->beat(), _frame_rate)); } } @@ -1844,8 +1831,8 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& } } recompute_meters (imaginary); - imaginary.sort (cmp); + imaginary.sort (cmp); if (section->position_lock_style() == AudioTime) { /* we're setting the beat */ section->set_position_lock_style (MusicTime); @@ -1854,6 +1841,19 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& } else { recompute_map (imaginary); } + prev_ts = 0; + for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) { + TempoSection* t; + if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + if (prev_ts) { + if (t->beat() < prev_ts->beat()) { + ret = false; + } + } + prev_ts = t; + } + } + /* prev_ts = 0; std::cerr << "dumping beat order ------" << std::endl; @@ -1877,10 +1877,12 @@ TempoMap::get_new_order (Metrics& imaginary, TempoSection* section, const Tempo& std::cerr << "end dump ------"; prev_ts = 0; */ + + return ret; } void -TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const double& beat) +TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& beat) { MeterSection* prev_ms = 0; @@ -1910,7 +1912,7 @@ TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& } MetricSectionFrameSorter fcmp; - imaginary.sort (fcmp); + //imaginary.sort (fcmp); if (section->position_lock_style() == AudioTime) { /* we're setting the beat */ @@ -1924,7 +1926,7 @@ TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& } void -TempoMap::get_new_order(Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame) +TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame) { MeterSection* prev_ms = 0; |