From a5055a22276ef0cfa17311ade7df0ff871606d22 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 27 Aug 2023 22:51:24 -0600 Subject: [PATCH] various changes related to tempo map copy/cut/paste section Tempo map is currently still excluded from the editor operation --- libs/ardour/session.cc | 41 ++++++++++++++++++------ libs/temporal/tempo.cc | 72 +++++++++++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 09718dee42..9904362c59 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -7304,23 +7304,46 @@ Session::cut_copy_section (timepos_t const& start, timepos_t const& end, timepos XMLNode &after = _locations->get_state(); add_command (new MementoCommand (*_locations, &before, &after)); } +#if 0 -#if 0 // TODO - enable once tempo-map cut/copy/paste works TempoMap::WritableSharedPtr wmap = TempoMap::write_copy (); TempoMapCutBuffer* tmcb; - if (copy) { - tmcb = wmap->copy (start, end); - } else { - tmcb = wmap->cut (start, end, true); + XMLNode& tm_before (wmap->get_state()); + + switch (op) { + case CopyPasteSection: + if ((tmcb = wmap->copy (start, end))) { + tmcb->dump (std::cerr); + wmap->paste (*tmcb, to, true); + } + break; + case CutPasteSection: + if ((tmcb = wmap->cut (start, end, true))) { + tmcb->dump (std::cerr); + wmap->paste (*tmcb, to, false); + } + break; + default: + tmcb = nullptr; + break; + } + + if (tmcb) { + TempoMap::update (wmap); + delete tmcb; + delete &tm_before; + + XMLNode& tm_after (wmap->get_state()); + std::cerr << "Saving tmap state as part of rev cmd\n"; + add_command (new MementoCommand (*wmap.get(), &tm_before, &tm_after)); } - wmap->paste (*tmcb, to, !copy); - TempoMap::update (wmap); - delete tmcb; #endif if (!abort_empty_reversible_command ()) { - commit_reversible_command (); + return; } + + commit_reversible_command (); } void diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index 4c9bd8382f..749fcbec72 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -866,6 +866,10 @@ TempoMap::copy ( timepos_t const & start, timepos_t const & end) TempoMapCutBuffer* TempoMap::cut_copy (timepos_t const & start, timepos_t const & end, bool copy, bool ripple) { + if (n_tempos() == 1 && n_meters() == 1) { + return nullptr; + } + TempoMetric sm (metric_at (start)); TempoMetric em (metric_at (end)); timecnt_t dur = start.distance (end); @@ -977,12 +981,22 @@ TempoMap::cut_copy (timepos_t const & start, timepos_t const & end, bool copy, b void TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool ripple) { + if (cb.empty()) { + std::cerr << "nothing to paste\n"; + return; + } + + std::cerr << "tm paste, ripple " << ripple << std::endl; if (ripple) { shift (position, cb.duration()); } bool replaced_ignored; + const timepos_t end_position = position + cb.duration(); + Tempo end_tempo = tempo_at (end_position); + Meter end_meter = meter_at (end_position); + /* iterate over _points since they are already in sclock order, and we * won't need to post-sort the way we would if we handled tempos, * meters, bartimes separately. @@ -990,19 +1004,26 @@ TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool BBT_Time pos_bbt = bbt_at (position); Beats pos_beats = quarters_at (position); - + bool ignored; Tempo const * st = cb.start_tempo(); - if (st) { - TempoPoint *ntp = new TempoPoint (*this, *st, position.superclocks(), pos_beats, pos_bbt); - core_add_tempo (ntp, replaced_ignored); - core_add_point (ntp); - } - Meter const * mt = cb.start_meter(); - if (mt) { - MeterPoint *ntp = new MeterPoint (*this, *mt, position.superclocks(), pos_beats, pos_bbt); - core_add_meter (ntp, replaced_ignored); - core_add_point (ntp); + + if (!st && !mt) { + MusicTimePoint* mtp = new MusicTimePoint (*this, position.superclocks(), pos_beats, pos_bbt, tempo_at (position), meter_at (position), _("paste start")); + core_add_bartime (mtp, ignored); + core_add_point (mtp); + } else { + if (st) { + TempoPoint *ntp = new TempoPoint (*this, *st, position.superclocks(), pos_beats, pos_bbt); + core_add_tempo (ntp, replaced_ignored); + core_add_point (ntp); + } + + if (mt) { + MeterPoint *ntp = new MeterPoint (*this, *mt, position.superclocks(), pos_beats, pos_bbt); + core_add_meter (ntp, replaced_ignored); + core_add_point (ntp); + } } for (auto const & p : cb.points()) { @@ -1030,23 +1051,28 @@ TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool } } - const timepos_t end_position = position + cb.duration(); pos_bbt = bbt_at (end_position); pos_beats = quarters_at (end_position); st = cb.end_tempo(); - if (st) { - TempoPoint *ntp = new TempoPoint (*this, *st, end_position.superclocks(), pos_beats, pos_bbt); - core_add_tempo (ntp, replaced_ignored); - core_add_point (ntp); - } mt = cb.end_meter(); - if (mt) { - MeterPoint *ntp = new MeterPoint (*this, *mt, end_position.superclocks(), pos_beats, pos_bbt); - core_add_meter (ntp, replaced_ignored); - core_add_point (ntp); - } + if (!st && !mt) { + MusicTimePoint* mtp = new MusicTimePoint (*this, end_position.superclocks(), pos_beats, pos_bbt, end_tempo, end_meter, _("paste end")); + core_add_bartime (mtp, ignored); + core_add_point (mtp); + } else { + if (st) { + TempoPoint *ntp = new TempoPoint (*this, *st, end_position.superclocks(), pos_beats, pos_bbt); + core_add_tempo (ntp, replaced_ignored); + core_add_point (ntp); + } + if (mt) { + MeterPoint *ntp = new MeterPoint (*this, *mt, end_position.superclocks(), pos_beats, pos_bbt); + core_add_meter (ntp, replaced_ignored); + core_add_point (ntp); + } + } } void @@ -1073,6 +1099,8 @@ TempoMap::shift (timepos_t const & at, BBT_Offset const & offset) { /* for now we require BBT-based shifts to be in units of whole bars */ + std::cerr << "Ripple tempo map by " << offset << std::endl; + if (std::abs (offset.bars) < 1) { return; }