MetricPositionChanged (); // Emit Signal
}
-void
-TempoMap::gui_move_tempo_pulse (TempoSection* ts, const double& pulse)
-{
- Metrics future_map;
- {
- Glib::Threads::RWLock::WriterLock lm (lock);
- TempoSection* tempo_copy = copy_metrics_and_point (_metrics, future_map, ts);
- if (solve_map (future_map, tempo_copy, pulse)) {
- solve_map (_metrics, ts, pulse);
- recompute_meters (_metrics);
- }
- }
-
- Metrics::const_iterator d = future_map.begin();
- while (d != future_map.end()) {
- delete (*d);
- ++d;
- }
-
- MetricPositionChanged (); // Emit Signal
-}
-
void
TempoMap::gui_move_meter (MeterSection* ms, const framepos_t& frame)
{
new_bpm = prev_t->tempo_at_frame (prev_t->frame() + fr_off, _frame_rate) * (double) prev_t->note_type();
}
- const double diff = (prev_t->tempo_at_frame (frame, _frame_rate) * prev_t->note_type()) - prev_t->beats_per_minute();
- if (diff > -0.1 && diff < 0.1) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
- / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
- }
-
} 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();
/* 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 > -0.1 && diff < 0.1) {
- new_bpm = prev_t->beats_per_minute() * ((ms->frame() - prev_t->frame())
- / (double) ((ms->frame() + prev_t_frame_contribution) - prev_t->frame()));
- }
+ /* 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);
}
void
-TempoMap::gui_dilate_tempo (const framepos_t& frame, const framepos_t& end_frame)
-{
- Metrics future_map;
- TempoSection* ts = 0;
+TempoMap::gui_dilate_tempo (TempoSection* ts, const framepos_t& frame, const framepos_t& end_frame, const double& pulse)
+{
+ /*
+ Ts (future prev_t) Tnext
+ | |
+ | [drag^] |
+ |----------|----------
+ e_f pulse(frame)
+ */
+ Metrics future_map;
{
Glib::Threads::RWLock::WriterLock lm (lock);
- ts = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, 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 = end_frame - frame;
prev_to_prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (future_map, prev_t->frame() - 1));
}
+ TempoSection* next_t = 0;
+ for (Metrics::iterator i = future_map.begin(); i != future_map.end(); ++i) {
+ TempoSection* t = 0;
+ if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+ if (t->frame() > ts->frame()) {
+ next_t = t;
+ break;
+ }
+ }
+ }
+
/* 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;
+ double start_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
- 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_to_prev_t->beats_per_minute() / (prev_to_prev_t->beats_per_minute() + prev_t->beats_per_minute());
+ if (next_t && prev_to_prev_t && prev_to_prev_t->type() == TempoSection::Ramp) {
+ contribution = (prev_t->frame() - prev_to_prev_t->frame()) / (double) (next_t->frame() - prev_to_prev_t->frame());
}
- frameoffset_t frame_contribution = contribution * (double) fr_off;
- frameoffset_t prev_t_frame_contribution = fr_off - frame_contribution;
-
- const double start_tempo = prev_t->tempo_at_frame (frame, _frame_rate);
- const double end_tempo = prev_t->tempo_at_frame (frame + prev_t_frame_contribution, _frame_rate);
- const double start_pulse = prev_t->pulse_at_frame (frame, _frame_rate);
- const double end_pulse = prev_t->pulse_at_frame (end_frame, _frame_rate);
- const double dpulse = (start_pulse) / (end_pulse);
- double new_bpm = prev_t->tempo_at_frame (prev_t->frame() - prev_t_frame_contribution, _frame_rate) * (double) prev_t->note_type();
+ frameoffset_t prev_t_frame_contribution = fr_off - (contribution * (double) fr_off);
+ double end_pulse = prev_t->pulse_at_frame (end_frame, _frame_rate);
+ double new_bpm;
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() * ((frame - prev_t->frame())
- / (double) ((frame + prev_t_frame_contribution) - prev_t->frame()));
+
+ new_bpm = prev_t->beats_per_minute() * ((frame - prev_to_prev_t->frame())
+ / (double) ((frame + prev_t_frame_contribution) - prev_to_prev_t->frame()));
} else {
/* prev to prev is irrelevant */
}
}
}
- } else if (prev_t->c_func() < 0.0) {
+ } else {
- const double end_minute = (((frame + prev_t_frame_contribution) - prev_t->frame()) / (double) _frame_rate) / 60.0;
- const double future_c = log (end_tempo / (new_bpm / (double) prev_t->note_type())) / end_minute;
+ double frame_ratio;
+ double pulse_ratio;
+ const framepos_t pulse_pos = prev_t->frame_at_pulse (pulse, _frame_rate);
- const double dtempo = (start_tempo) / (end_tempo);
- const double dframe = (frame) / (double) ((frame + prev_t_frame_contribution));
+ if (prev_to_prev_t) {
- /* limits - a bit clunky, but meh */
- if (future_c > -10.1 && future_c < 10.1) {
- new_bpm = prev_t->beats_per_minute() * (dpulse / dtempo);
+ frame_ratio = (((pulse_pos - fr_off) - prev_to_prev_t->frame()) / (double) ((pulse_pos) - prev_to_prev_t->frame()));
+ pulse_ratio = ((start_pulse - prev_to_prev_t->pulse()) / (end_pulse - prev_to_prev_t->pulse()));
} else {
- new_bpm = prev_t->beats_per_minute() * (dframe / dtempo);
- }
- } else if (prev_t->c_func() > 0.0) {
-
- const double end_minute = (((frame + prev_t_frame_contribution) - prev_t->frame()) / (double) _frame_rate) / 60.0;
- const double future_c = log (end_tempo / (new_bpm / (double) prev_t->note_type())) / end_minute;
-
- const double dtempo = (end_tempo) / (start_tempo);
- const double dframe = (frame) / (double) ((frame + prev_t_frame_contribution));
-
- /* limits - a bit clunky, but meh */
- if (future_c > -10.1 && future_c < 10.1) {
- new_bpm = prev_t->beats_per_minute() * (dpulse / dtempo);
- } else {
- new_bpm = prev_t->beats_per_minute() * (dframe / dtempo);
+ frame_ratio = (((pulse_pos - fr_off) - prev_t->frame()) / (double) ((pulse_pos) - prev_t->frame()));
+ pulse_ratio = (start_pulse / end_pulse);
}
+ new_bpm = prev_t->beats_per_minute() * (pulse_ratio * frame_ratio);
}
prev_t->set_beats_per_minute (new_bpm);
recompute_meters (future_map);
if (check_solved (future_map, true)) {
-
- prev_t = const_cast<TempoSection*>(&tempo_section_at_locked (_metrics, frame - 1));
- prev_t->set_beats_per_minute (new_bpm);
+ ts->set_beats_per_minute (new_bpm);
recompute_tempos (_metrics);
recompute_meters (_metrics);
}