diff options
-rw-r--r-- | gtk2_ardour/editor_tempodisplay.cc | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 2 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 80 |
3 files changed, 69 insertions, 16 deletions
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 95fb178421..a971e98abe 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -378,8 +378,7 @@ Editor::edit_tempo_section (TempoSection* section) if (tempo_dialog.get_lock_style() == MusicTime) { _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), beat, tempo_dialog.get_tempo_type()); } else { - _session->tempo_map().replace_c_func_from_tempo_and_beat (bpm, beat); - framepos_t const f = _session->tempo_map().frame_at_beat (beat); + framepos_t const f = _session->tempo_map().compute_replacement_tempo_section (section, bpm, beat); _session->tempo_map().replace_tempo (*section, Tempo (bpm, nt), f, tempo_dialog.get_tempo_type()); } XMLNode &after = _session->tempo_map().get_state(); diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 6ce59ffbea..d1ee1090bc 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -371,7 +371,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_c_func_from_tempo_and_beat (const double& tempo, const double& beat); + framepos_t compute_replacement_tempo_section (TempoSection* section, const double& tempo, const double& beat); void replace_tempo (const TempoSection&, const Tempo&, const double& where, TempoSection::Type type); void replace_tempo (const TempoSection&, const Tempo&, const framepos_t& where, TempoSection::Type type); diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index da22da4bd2..15d88b01c9 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -824,33 +824,87 @@ TempoMap::do_insert (MetricSection* section) } } -/* -This is for a gui who needs to know the frame of a beat if a proposed tempo section were to be placed there. -You probably shouldn't use this unless you know what you're doing, -as it doesn't recompute the tempo map and will make a ramp invalid intil that next happens. -It is assumed that the next frame calculation is the last time you need this c_func before the next do_insert() and/or recompute_map(). +/** +* This is for a gui that needs to know the frame of a beat if a tempo section were to be moved or altered. +* It actually alters tha ramps up to the beat parameter, so calling this commits you to replacing the section immediately. +* It will not emit a signal or recompute the map, as you probably want to replace the tempo or do somethig else before that happens. +* @param section - the section you want to alter +* @param bpm - the new tempo +* @param beat - the beat where the altered tempo will fall +* @return returns - the position in frames where the new tempo section will lie */ -void -TempoMap::replace_c_func_from_tempo_and_beat (const double& bpm, const double& beat) +framepos_t +TempoMap::compute_replacement_tempo_section (TempoSection* section, const double& bpm, const double& beat) { - Glib::Threads::RWLock::WriterLock lm (lock); TempoSection* prev_ts = 0; TempoSection* t; + framepos_t ret = 0; + MetricSectionSorter cmp; + + Glib::Threads::RWLock::WriterLock lm (lock); for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) { if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { if (prev_ts) { - prev_ts->set_c_func_from_tempo_and_beat (bpm, beat, _frame_rate); + if (section->beat() == t->beat()) { + continue; + } + if (beat < t->beat()){ + prev_ts->set_c_func_from_tempo_and_beat (bpm, beat, _frame_rate); + section->set_beat (beat); + section->set_frame (prev_ts->frame_at_beat (beat, _frame_rate)); + break; + } + + if (t->position_lock_style() == MusicTime) { + prev_ts->set_c_func_from_tempo_and_beat (t->beats_per_minute(), t->beat(), _frame_rate); + t->set_frame (prev_ts->frame_at_beat (t->beat(), _frame_rate)); + } else { + prev_ts->set_c_func (prev_ts->compute_c_func (t->beats_per_minute(), t->frame(), _frame_rate)); + t->set_beat (prev_ts->beat_at_frame (t->frame(), _frame_rate)); + } + } + prev_ts = t; + } + } + /* now we do the whole thing again because audio-locked sections will have caused a re-order */ + prev_ts = 0; + metrics.sort (cmp); - if (beat < t->beat()) { - return; + for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) { + if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { + if (prev_ts) { + if (section->beat() == t->beat()) { + continue; + } + if (beat < t->beat()){ + prev_ts->set_c_func_from_tempo_and_beat (bpm, beat, _frame_rate); + ret = prev_ts->frame_at_beat (beat, _frame_rate); + section->set_frame (ret); + prev_ts = section; + break; + } + if (t->position_lock_style() == MusicTime) { + prev_ts->set_c_func_from_tempo_and_beat (t->beats_per_minute(), t->beat(), _frame_rate); + t->set_frame (prev_ts->frame_at_beat (t->beat(), _frame_rate)); + } else { + prev_ts->set_c_func (prev_ts->compute_c_func (t->beats_per_minute(), t->frame(), _frame_rate)); + t->set_beat (prev_ts->beat_at_frame (t->frame(), _frame_rate)); } } prev_ts = t; } } - /* there is always at least one tempo section */ - prev_ts->set_c_func_from_tempo_and_beat (bpm, beat, _frame_rate); + + if (!ret) { + prev_ts->set_c_func_from_tempo_and_beat (bpm, beat, _frame_rate); + section->set_beat (beat); + section->set_frame (prev_ts->frame_at_beat (beat, _frame_rate)); + + ret = prev_ts->frame_at_beat (beat, _frame_rate); + } + + return ret; } void |