-void
-TempoMap::gui_dilate_tempo (MeterSection* ms, const framepos_t& frame)
-{
- Metrics future_map;
- TempoSection* ts = 0;
-
- if (frame <= first_meter().frame()) {
- return;
- }
-
- if (ms->position_lock_style() == AudioTime) {
- /* disabled for now due to faked tempo locked to meter pulse */
- return;
- }
-
- {
- Glib::Threads::RWLock::WriterLock lm (lock);
- ts = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, ms->frame() - 1));
- if (!ts) {
- return;
- }
- TempoSection* prev_t = copy_metrics_and_point (_metrics, future_map, ts);
- TempoSection* prev_to_prev_t = 0;
- const frameoffset_t fr_off = frame - ms->frame();
- double new_bpm = 0.0;
-
- if (prev_t && prev_t->pulse() > 0.0) {
- prev_to_prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (future_map, prev_t->frame() - 1));
- }
-
- /* the change in frames is the result of changing the slope of at most 2 previous tempo sections.
- constant to constant is straightforward, as the tempo prev to prev_t has constant slope.
- */
- double contribution = 0.0;
- frameoffset_t frame_contribution = 0;
- frameoffset_t prev_t_frame_contribution = fr_off;
-
- if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
- /* prev to prev_t's position will remain constant in terms of frame and pulse. lets use frames. */
- contribution = (prev_t->frame() - prev_to_prev_t->frame()) / (double) (ms->frame() - prev_to_prev_t->frame());
- frame_contribution = contribution * (double) fr_off;
- prev_t_frame_contribution = fr_off - frame_contribution;
- }
-
- if (prev_t->type() == TempoSection::Constant || prev_t->c_func() == 0.0) {
-
- if (prev_t->position_lock_style() == MusicTime) {
- if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
- / (double) (ms->frame() + prev_t_frame_contribution - prev_t->frame()));
-
- } else {
- /* prev to prev is irrelevant */
- const double meter_pulse = prev_t->pulse_at_frame (ms->frame(), _frame_rate);
- const double frame_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
-
- if (frame_pulse != prev_t->pulse()) {
- new_bpm = prev_t->beats_per_minute() * ((meter_pulse - prev_t->pulse()) / (frame_pulse - prev_t->pulse()));
- } else {
- new_bpm = prev_t->beats_per_minute();
- }
- }
- } else {
- /* AudioTime */
- if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
- / (double) (ms->frame() + prev_t_frame_contribution - prev_t->frame()));
- } else {
- /* prev_to_prev_t is irrelevant */
-
- if (frame != prev_t->frame()) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame()) / (double) (frame - prev_t->frame()));
- } else {
- new_bpm = prev_t->beats_per_minute();
- }
- }
- }
- } else if (prev_t->c_func() < 0.0) {
- if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
- new_bpm = prev_t->tempo_at_frame (prev_t->frame() + frame_contribution, _frame_rate) * (double) prev_t->note_type();
- } else {
- /* prev_to_prev_t is irrelevant */
- new_bpm = prev_t->tempo_at_frame (prev_t->frame() + fr_off, _frame_rate) * (double) prev_t->note_type();
- }
-
- } else if (prev_t->c_func() > 0.0) {
- if (prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
- new_bpm = prev_t->tempo_at_frame (prev_t->frame() - frame_contribution, _frame_rate) * (double) prev_t->note_type();
- } else {
- /* prev_to_prev_t is irrelevant */
- new_bpm = prev_t->tempo_at_frame (prev_t->frame() - fr_off, _frame_rate) * (double) prev_t->note_type();
- }
- }
-
- /* limits - a bit clunky, but meh */
- const double diff = (prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type()) - prev_t->beats_per_minute();
- if (diff > -1.0 && diff < 1.0) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
- / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
- }
-
- prev_t->set_beats_per_minute (new_bpm);
- recompute_tempos (future_map);
- recompute_meters (future_map);
-
- if (check_solved (future_map, true)) {
-
- prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, ms->frame() - 1));
- prev_t->set_beats_per_minute (new_bpm);
- recompute_tempos (_metrics);
-
- if (ms->position_lock_style() == AudioTime) {
- ms->set_frame (frame);
- }
-
- recompute_meters (_metrics);
- }
- }
-
- Metrics::const_iterator d = future_map.begin();
- while (d != future_map.end()) {
- delete (*d);
- ++d;
- }
-
- MetricPositionChanged (); // Emit Signal
-}
-