diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d8618ffca4..cd663444ec 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3148,10 +3148,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move) if (first_move) { - // create a dummy marker for visual representation of moving the - // section, because whether its a copy or not, we're going to - // leave or lose the original marker (leave if its a copy; lose if its - // not, because we'll remove it from the map). + // create a dummy marker to catch events, then hide it. char name[64]; snprintf (name, sizeof(name), "%g/%g", _marker->meter().divisions_per_bar(), _marker->meter().note_divisor ()); @@ -3166,14 +3163,34 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move) /* use the new marker for the grab */ swap_grab (&_marker->the_item(), 0, GDK_CURRENT_TIME); + _marker->hide(); + + TempoMap& map (_editor->session()->tempo_map()); + /* get current state */ + before_state = &map.get_state(); if (!_copy) { _editor->begin_reversible_command (_("move meter mark")); - TempoMap& map (_editor->session()->tempo_map()); - /* get current state */ - before_state = &map.get_state(); + } else { + _editor->begin_reversible_command (_("copy meter mark")); + + Timecode::BBT_Time bbt; + map.bbt_time (_marker->position(), bbt); + map.round_bbt (bbt, -1); + if (_real_section->frame() < adjusted_current_frame (event, false)) { + ++bbt.bars; + } else { + --bbt.bars; + } + const double beat = map.bbt_to_beats (bbt); + + if (_real_section->position_lock_style() == AudioTime) { + _real_section = map.add_meter (Meter (_marker->meter().divisions_per_bar(), _marker->meter().note_divisor()) + , _marker->position(), beat, bbt); + } else { + _real_section = map.add_meter (Meter (_marker->meter().divisions_per_bar(), _marker->meter().note_divisor()), beat, bbt); + } } - _marker->hide(); } framepos_t const pf = adjusted_current_frame (event, false); @@ -3184,6 +3201,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move) } else { _editor->session()->tempo_map().gui_move_meter (_real_section, pf); } + _marker->set_position (pf); show_verbose_cursor_time (pf); } @@ -3200,20 +3218,11 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred) TempoMap& map (_editor->session()->tempo_map()); if (_copy == true) { - _editor->begin_reversible_command (_("copy meter mark")); - XMLNode &before = map.get_state(); - - if (_real_section->position_lock_style() == AudioTime) { - map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->frame(), _real_section->beat(), _real_section->bbt()); - } else { - map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->beat(), _real_section->bbt()); - } XMLNode &after = map.get_state(); - _editor->session()->add_command(new MementoCommand(map, &before, &after)); + _editor->session()->add_command(new MementoCommand(map, before_state, &after)); _editor->commit_reversible_command (); } else { - /* we removed it before, so add it back now */ if (_real_section->position_lock_style() == AudioTime) { map.replace_meter (*_real_section, Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->frame()); } else { @@ -3283,13 +3292,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move) } if (first_move) { - // create a dummy marker for visual representation of moving the - // section, because whether its a copy or not, we're going to - // leave or lose the original marker (leave if its a copy; lose if its - // not, because we'll remove it from the map). - - // create a dummy marker for visual representation of moving the copy. - // The actual copying is not done before we reach the finish callback. + // mvc drag - create a dummy marker to catch events, hide it. char name[64]; snprintf (name, sizeof (name), "%.2f", _marker->tempo().beats_per_minute()); @@ -3390,7 +3393,6 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred) return; } - //motion (event, false); TempoMap& map (_editor->session()->tempo_map()); diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 5ab4056c5e..98c6e82c16 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -376,8 +376,8 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible void add_tempo (const Tempo&, const double& pulse, TempoSection::Type type); void add_tempo (const Tempo&, const framepos_t& frame, TempoSection::Type type); - void add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where); - void add_meter (const Meter&, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where); + MeterSection* add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where); + MeterSection* add_meter (const Meter&, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where); void remove_tempo (const TempoSection&, bool send_signal); void remove_meter (const MeterSection&, bool send_signal); @@ -492,8 +492,8 @@ private: void add_tempo_locked (const Tempo&, double pulse, bool recompute, TempoSection::Type type); void add_tempo_locked (const Tempo&, framepos_t frame, bool recompute, TempoSection::Type type); - void add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute); - void add_meter_locked (const Meter&, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute); + MeterSection* add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute); + MeterSection* add_meter_locked (const Meter&, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute); bool remove_tempo_locked (const TempoSection&); bool remove_meter_locked (const MeterSection&); diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 9c40b25919..4915c42e8a 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -779,7 +779,7 @@ TempoMap::do_insert (MetricSection* section) bool const ipm = insert_meter->position_lock_style() == MusicTime; - if ((ipm && meter->pulse() == insert_meter->pulse()) || (!ipm && meter->frame() == insert_meter->frame())) { + if ((ipm && meter->beat() == insert_meter->beat()) || (!ipm && meter->frame() == insert_meter->frame())) { if (!meter->movable()) { @@ -793,7 +793,6 @@ TempoMap::do_insert (MetricSection* section) need_add = false; } else { _metrics.erase (i); - } break; @@ -817,7 +816,7 @@ TempoMap::do_insert (MetricSection* section) if (meter) { bool const ipm = insert_meter->position_lock_style() == MusicTime; - if ((ipm && meter->pulse() > insert_meter->pulse()) || (!ipm && meter->frame() > insert_meter->frame())) { + if ((ipm && meter->beat() > insert_meter->beat()) || (!ipm && meter->frame() > insert_meter->frame())) { break; } } @@ -948,8 +947,8 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T /* cannot move the first meter section */ *static_cast(&first) = meter; first.set_position_lock_style (pl); - recompute_map (_metrics); } + recompute_map (_metrics); } PropertyChanged (PropertyChange ()); @@ -980,20 +979,20 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame first_t.set_frame (first.frame()); first_t.set_pulse (0.0); first_t.set_position_lock_style (AudioTime); - - recompute_map (_metrics); } + recompute_map (_metrics); } PropertyChanged (PropertyChange ()); } -void +MeterSection* TempoMap::add_meter (const Meter& meter, const double& beat, const BBT_Time& where) { + MeterSection* m = 0; { Glib::Threads::RWLock::WriterLock lm (lock); - add_meter_locked (meter, beat, where, true); + m = add_meter_locked (meter, beat, where, true); } @@ -1004,14 +1003,17 @@ TempoMap::add_meter (const Meter& meter, const double& beat, const BBT_Time& whe #endif PropertyChanged (PropertyChange ()); + dump (_metrics, std::cerr); + return m; } -void +MeterSection* TempoMap::add_meter (const Meter& meter, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where) { + MeterSection* m = 0; { Glib::Threads::RWLock::WriterLock lm (lock); - add_meter_locked (meter, frame, beat, where, true); + m = add_meter_locked (meter, frame, beat, where, true); } @@ -1022,9 +1024,11 @@ TempoMap::add_meter (const Meter& meter, const framepos_t& frame, const double& #endif PropertyChanged (PropertyChange ()); + + return m; } -void +MeterSection* TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, bool recompute) { /* a new meter always starts a new bar on the first beat. so @@ -1040,8 +1044,7 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo } /* new meters *always* start on a beat. */ where.ticks = 0; - double pulse = pulse_at_beat_locked (_metrics, beat); - + const double pulse = pulse_at_beat_locked (_metrics, beat); MeterSection* new_meter = new MeterSection (pulse, beat, where, meter.divisions_per_bar(), meter.note_divisor()); do_insert (new_meter); @@ -1049,9 +1052,10 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo solve_map (_metrics, new_meter, pulse); } + return new_meter; } -void +MeterSection* TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute) { @@ -1066,6 +1070,7 @@ TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, double beat, T solve_map (_metrics, new_meter, frame); } + return new_meter; } void @@ -1261,11 +1266,11 @@ TempoMap::recompute_meters (Metrics& metrics) double pulse = 0.0; pair b_bbt; if (meter->movable()) { - const double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat(); + const double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()); const double ceil_beats = beats - fmod (beats, prev_m->divisions_per_bar()); - b_bbt = make_pair (ceil_beats, BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); - const double true_pulse = prev_m->pulse() + (ceil_beats - prev_m->beat()) / prev_m->note_divisor(); - const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor()); + b_bbt = make_pair (ceil_beats + prev_m->beat(), BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); + const double true_pulse = prev_m->pulse() + (ceil_beats / prev_m->note_divisor()); + const double pulse_off = true_pulse - (beats / prev_m->note_divisor()); pulse = true_pulse - pulse_off; } else { b_bbt = make_pair (0.0, BBT_Time (1, 1, 0)); @@ -1465,7 +1470,6 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co /* HOLD THE READER LOCK */ const TempoSection* prev_t = 0; - double accumulated_pulses = 0.0; for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { TempoSection* t; @@ -1478,12 +1482,11 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co return prev_t->frame_at_pulse (pulse, _frame_rate); } - accumulated_pulses = t->pulse(); prev_t = t; } } /* must be treated as constant, irrespective of _type */ - double const pulses_in_section = pulse - accumulated_pulses; + double const pulses_in_section = pulse - prev_t->pulse(); double const dtime = pulses_in_section * prev_t->frames_per_pulse (_frame_rate); framecnt_t const ret = (framecnt_t) floor (dtime) + prev_t->frame(); @@ -2007,11 +2010,11 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const framepos_t double pulse = 0.0; pair b_bbt; if (m->movable()) { - const double beats = ((pulse_at_frame_locked (imaginary, frame) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat(); + const double beats = ((pulse_at_frame_locked (imaginary, frame) - prev_m->pulse()) * prev_m->note_divisor()); const double ceil_beats = beats - fmod (beats, prev_m->divisions_per_bar()); - b_bbt = make_pair (ceil_beats, BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); - const double true_pulse = prev_m->pulse() + ((ceil_beats - prev_m->beat()) / prev_m->note_divisor()); - const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor()); + b_bbt = make_pair (ceil_beats + prev_m->beat(), BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); + const double true_pulse = prev_m->pulse() + (ceil_beats / prev_m->note_divisor()); + const double pulse_off = true_pulse - (beats / prev_m->note_divisor()); pulse = true_pulse - pulse_off; } else { b_bbt = make_pair (0.0, BBT_Time (1, 1, 0)); @@ -2030,11 +2033,11 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const framepos_t double pulse = 0.0; pair b_bbt; if (m->movable()) { - const double beats = ((pulse_at_frame_locked (imaginary, m->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat(); + const double beats = ((pulse_at_frame_locked (imaginary, m->frame()) - prev_m->pulse()) * prev_m->note_divisor()); const double ceil_beats = beats - fmod (beats , prev_m->divisions_per_bar()); - b_bbt = make_pair (ceil_beats, BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); - const double true_pulse = prev_m->pulse() + (ceil_beats - prev_m->beat()) / prev_m->note_divisor(); - const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor()); + b_bbt = make_pair (ceil_beats + prev_m->beat(), BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); + const double true_pulse = prev_m->pulse() + (ceil_beats / prev_m->note_divisor()); + const double pulse_off = true_pulse - (beats / prev_m->note_divisor()); pulse = true_pulse - pulse_off; } else { b_bbt = make_pair (0.0, BBT_Time (1, 1, 0)); @@ -2071,34 +2074,33 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const double& pu if ((m = dynamic_cast (*i)) != 0) { if (m == section){ section->set_frame (frame_at_pulse_locked (imaginary, pulse)); - const double beats = ((pulse - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat(); + const double beats = ((pulse - prev_m->pulse()) * prev_m->note_divisor()); const int32_t bars = (beats + 1) / prev_m->divisions_per_bar(); - pair b_bbt = make_pair (beats, BBT_Time (bars + 1, 1, 0)); + pair b_bbt = make_pair (beats + prev_m->beat(), BBT_Time (bars + prev_m->bbt().bars, 1, 0)); section->set_beat (b_bbt); prev_m = section; continue; } if (prev_m) { + double pulse = 0.0; if (m->position_lock_style() == MusicTime) { - const double pulse = prev_m->pulse() + (m->beat() - prev_m->beat()) / prev_m->note_divisor(); + pulse = prev_m->pulse() + (m->beat() - prev_m->beat()) / prev_m->note_divisor(); m->set_frame (frame_at_pulse_locked (imaginary, pulse)); - m->set_pulse (pulse); } else { - double pulse = 0.0; pair b_bbt; if (m->movable()) { - const double beats = ((pulse_at_frame_locked (imaginary, m->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat(); + const double beats = ((pulse_at_frame_locked (imaginary, m->frame()) - prev_m->pulse()) * prev_m->note_divisor()); const double ceil_beats = beats - fmod (beats, prev_m->divisions_per_bar()); - b_bbt = make_pair (ceil_beats, BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); - const double true_pulse = prev_m->pulse() + (m->beat() - prev_m->beat()) / prev_m->note_divisor(); - const double pulse_off = true_pulse - ((ceil_beats - prev_m->beat()) / prev_m->note_divisor()); + b_bbt = make_pair (ceil_beats + prev_m->beat(), BBT_Time ((ceil_beats / prev_m->divisions_per_bar()) + prev_m->bbt().bars, 1, 0)); + const double true_pulse = prev_m->pulse() + (ceil_beats / prev_m->note_divisor()); + const double pulse_off = true_pulse - (beats / prev_m->note_divisor()); pulse = true_pulse - pulse_off; } else { b_bbt = make_pair (0.0, BBT_Time (1, 1, 0)); } m->set_beat (b_bbt); - m->set_pulse (pulse); } + m->set_pulse (pulse); } prev_m = m; }