fix (some) editing based on tempo & meter marks

After beginning an edit operation with TempoMap::write_copy(), the tempoPoint and meterPoint objects
referenced by markers are incorrect, since they refer to the original map, not the copy we are working
on. Fix this with Editor::reassociate_metric_markers()

Some instances requiring this fix may still remain
This commit is contained in:
Paul Davis 2021-04-04 17:56:58 -06:00
parent 5838bcbe7c
commit 7938d8de4f
6 changed files with 90 additions and 23 deletions

View File

@ -1396,7 +1396,9 @@ Editor::set_session (Session *t)
restore_ruler_visibility ();
//tempo_map_changed (PropertyChange (0));
TempoMap::use()->apply_with_metrics (*this, &Editor::draw_metric_marks);
TempoMap::Metrics metrics;
TempoMap::use()->get_metrics (metrics);
draw_metric_marks (metrics);
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(static_cast<TimeAxisView*>(*i))->set_samples_per_pixel (samples_per_pixel);

View File

@ -1813,6 +1813,7 @@ private:
void compute_current_bbt_points (Temporal::TempoMapPoints& grid, samplepos_t left, samplepos_t right);
void reassociate_metric_markers (Temporal::TempoMap::SharedPtr const &);
void tempo_map_changed ();
void redisplay_grid (bool immediate_redraw);

View File

@ -1504,6 +1504,9 @@ Editor::toggle_tempo_type ()
begin_reversible_command (_("set tempo to constant"));
TempoMap::SharedPtr tmap (TempoMap::write_copy());
reassociate_metric_markers (tmap);
XMLNode &before = tmap->get_state();
tmap->set_ramped (tempo, !tempo.ramped());
@ -1530,6 +1533,9 @@ Editor::toggle_tempo_clamped ()
XMLNode &before = tmap->get_state();
Temporal::Tempo & tempo (tm->tempo());
reassociate_metric_markers (tmap);
tempo.set_clamped (!tempo.clamped());
XMLNode &after = tmap->get_state();
@ -1554,6 +1560,8 @@ Editor::ramp_to_next_tempo ()
TempoMap::SharedPtr tmap (TempoMap::write_copy());
XMLNode &before = tmap->get_state();
reassociate_metric_markers (tmap);
Temporal::TempoPoint & tempo (tm->tempo());
tmap->set_ramped (tempo, !tempo.ramped());
XMLNode &after = tmap->get_state();

View File

@ -90,6 +90,66 @@ struct CurveComparator {
}
};
void
Editor::reassociate_metric_markers (TempoMap::SharedPtr const & tmap)
{
TempoMap::Metrics metrics;
tmap->get_metrics (metrics);
TempoMarker* tm;
MeterMarker* mm;
BBTMarker* bm;
Temporal::TempoPoint* tp;
Temporal::MeterPoint* mp;
Temporal::MusicTimePoint* mtp;
for (Marks::iterator x = metric_marks.begin(); x != metric_marks.end(); ++x) {
if ((tm = dynamic_cast<TempoMarker*> (*x)) != 0) {
for (TempoMap::Metrics::iterator m = metrics.begin(); m != metrics.end(); ++m) {
if ((mtp = dynamic_cast<Temporal::MusicTimePoint*>(*m)) != 0) {
/* do nothing .. but we had to catch
this first because MusicTimePoint
IS-A TempoPoint
*/
} else if ((tp = dynamic_cast<Temporal::TempoPoint*>(*m)) != 0) {
if (tm->tempo() == *tp) {
tm->reset_tempo (*tp);
break;
}
}
}
} else if ((mm = dynamic_cast<MeterMarker*> (*x)) != 0) {
for (TempoMap::Metrics::iterator m = metrics.begin(); m != metrics.end(); ++m) {
if ((mtp = dynamic_cast<Temporal::MusicTimePoint*>(*m)) != 0) {
/* do nothing .. but we had to catch
this first because MusicTimePoint
IS-A TempoPoint
*/
} else if ((mp = dynamic_cast<Temporal::MeterPoint*>(*m)) != 0) {
if (mm->meter() == *mp) {
mm->reset_meter (*mp);
break;
}
}
}
} else if ((bm = dynamic_cast<BBTMarker*> (*x)) != 0) {
for (TempoMap::Metrics::iterator m = metrics.begin(); m != metrics.end(); ++m) {
if ((mtp = dynamic_cast<Temporal::MusicTimePoint*>(*m)) != 0) {
if (bm->point() == *mtp) {
bm->reset_point (*mtp);
break;
}
}
}
}
}
}
void
Editor::draw_metric_marks (TempoMap::Metrics const & metrics)
{
@ -195,18 +255,12 @@ Editor::draw_metric_marks (TempoMap::Metrics const & metrics)
void
Editor::tempo_map_changed ()
{
PropertyChange pc;
if (!_session) {
return;
}
TempoMap::use()->apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers
TempoMap::Metrics metrics;
TempoMap::use()->get_metrics (metrics);
draw_metric_marks (metrics);
compute_bbt_ruler_scale (_leftmost_sample, _leftmost_sample + current_page_samples());
update_tempo_based_rulers ();
maybe_draw_grid_lines ();
}
@ -451,6 +505,8 @@ Editor::edit_meter_section (Temporal::MeterPoint& section)
TempoMap::SharedPtr tmap (TempoMap::write_copy());
reassociate_metric_markers (tmap);
begin_reversible_command (_("replace meter mark"));
XMLNode &before = tmap->get_state();
@ -483,6 +539,7 @@ Editor::edit_tempo_section (TempoPoint& section)
const Tempo tempo (bpm, end_bpm, nt);
TempoMap::SharedPtr tmap (TempoMap::write_copy());
reassociate_metric_markers (tmap);
Temporal::BBT_Time when;
tempo_dialog.get_bbt_time (when);
@ -490,7 +547,6 @@ Editor::edit_tempo_section (TempoPoint& section)
begin_reversible_command (_("replace tempo mark"));
XMLNode &before = tmap->get_state();
tmap->set_tempo (tempo, when);
XMLNode &after = tmap->get_state();

View File

@ -636,7 +636,7 @@ ArdourMarker::set_right_label_limit (double p)
TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Item& parent, guint32 rgba, const string& text,
Temporal::TempoPoint& temp)
: ArdourMarker (editor, parent, rgba, text, Tempo, temp.time(), false)
, _tempo (temp)
, _tempo (&temp)
{
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_marker_event), group, this));
}
@ -668,7 +668,7 @@ TempoMarker::update_height_mark (const double ratio)
void
TempoMarker::reset_tempo (Temporal::TempoPoint & t)
{
_tempo = t;
_tempo = &t;
}
@ -676,7 +676,7 @@ TempoMarker::reset_tempo (Temporal::TempoPoint & t)
MeterMarker::MeterMarker (PublicEditor& editor, ArdourCanvas::Item& parent, guint32 rgba, const string& text, Temporal::MeterPoint& m)
: ArdourMarker (editor, parent, rgba, text, Meter, m.time(), false)
, _meter (m)
, _meter (&m)
{
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_meter_marker_event), group, this));
}
@ -688,14 +688,14 @@ MeterMarker::~MeterMarker ()
void
MeterMarker::reset_meter (Temporal::MeterPoint & m)
{
_meter = m;
_meter = &m;
}
/***********************************************************************/
BBTMarker::BBTMarker (PublicEditor& editor, ArdourCanvas::Item& parent, guint32 rgba, const string& text, Temporal::MusicTimePoint& p)
: ArdourMarker (editor, parent, rgba, text, BBTPosition, p.time(), false)
, _point (p)
, _point (&p)
{
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_bbt_marker_event), group, this));
}
@ -707,5 +707,5 @@ BBTMarker::~BBTMarker ()
void
BBTMarker::reset_point (Temporal::MusicTimePoint & p)
{
_point = p;
_point = &p;
}

View File

@ -164,11 +164,11 @@ class TempoMarker : public ArdourMarker
void reset_tempo (Temporal::TempoPoint & t);
Temporal::TempoPoint& tempo() const { return _tempo; }
Temporal::TempoPoint& tempo() const { return *_tempo; }
void update_height_mark (const double ratio);
private:
Temporal::TempoPoint& _tempo;
Temporal::TempoPoint* _tempo;
};
class MeterMarker : public ArdourMarker
@ -179,10 +179,10 @@ class MeterMarker : public ArdourMarker
void reset_meter (Temporal::MeterPoint & m);
Temporal::MeterPoint& meter() const { return _meter; }
Temporal::MeterPoint& meter() const { return *_meter; }
private:
Temporal::MeterPoint& _meter;
Temporal::MeterPoint* _meter;
};
class BBTMarker : public ArdourMarker
@ -193,10 +193,10 @@ class BBTMarker : public ArdourMarker
void reset_point (Temporal::MusicTimePoint &);
Temporal::MusicTimePoint& point() const { return _point; }
Temporal::MusicTimePoint& point() const { return *_point; }
private:
Temporal::MusicTimePoint& _point;
Temporal::MusicTimePoint* _point;
};
#endif /* __gtk_ardour_marker_h__ */