From 06e9bf6ca40062e7487d03a94119dde3c8a3e892 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 16 Aug 2023 09:06:10 -0600 Subject: [PATCH] domain swaps for MIDI CC and other controls --- libs/ardour/ardour/automatable.h | 3 +-- libs/ardour/automatable.cc | 14 ++++++++++---- libs/ardour/midi_region.cc | 12 ++++++++++-- libs/evoral/ControlList.cc | 4 ++-- libs/evoral/ControlSet.cc | 24 ++++++++++++++++++++++++ libs/evoral/evoral/ControlSet.h | 7 ++++++- 6 files changed, 53 insertions(+), 11 deletions(-) diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index 0e40021b67..1c9e7eeeb4 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -34,7 +34,6 @@ #include "evoral/ControlSet.h" -#include "temporal/domain_swap.h" #include "temporal/domain_provider.h" #include "ardour/libardour_visibility.h" @@ -51,7 +50,7 @@ class AutomationControl; /* The inherited ControlSet is virtual because AutomatableSequence inherits * from this AND EvoralSequence, which is also a ControlSet */ -class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable, public Temporal::TimeDomainProvider, public Temporal::TimeDomainSwapper +class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable, public Temporal::TimeDomainProvider { public: Automatable(Session&, Temporal::TimeDomainProvider const &); diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index e04040b014..9ff38c31a4 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -30,6 +30,7 @@ #include #include "pbd/error.h" +#include "pbd/memento_command.h" #include "temporal/timeline.h" @@ -749,19 +750,24 @@ Automatable::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { for (auto & c : _controls) { std::shared_ptr cl = c.second->list(); - if (cl) { - cl->start_domain_bounce (cmd); + if (cl && cl->time_domain() != cmd.to) { + std::shared_ptr al (std::dynamic_pointer_cast (cl)); + _a_session.add_command (new MementoCommand (*(al.get()), &al->get_state(), nullptr)); } } + ControlSet::start_domain_bounce (cmd); } void Automatable::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) { + ControlSet::finish_domain_bounce (cmd); + for (auto & c : _controls) { std::shared_ptr cl = c.second->list(); - if (cl) { - cl->finish_domain_bounce (cmd); + if (cl && cl->time_domain() != cmd.to) { + std::shared_ptr al (std::dynamic_pointer_cast (cl)); + _a_session.add_command (new MementoCommand (*(al.get()), nullptr, &al->get_state())); } } } diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 57882752ea..cdfe8fe57b 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -619,9 +619,12 @@ MidiRegion::start_domain_bounce (Temporal::DomainBounceInfo& cmd) /* Deal with the region position & length */ Region::start_domain_bounce (cmd); - if (cmd.from == Temporal::BeatTime) { - model()->create_mapping_stash (source_position().beats()); + if (cmd.from != Temporal::BeatTime) { + return; } + + model()->start_domain_bounce (cmd); + model()->create_mapping_stash (source_position().beats()); } void @@ -629,7 +632,12 @@ MidiRegion::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) { Region::finish_domain_bounce (cmd); + if (cmd.from != Temporal::BeatTime) { + return; + } + model()->rebuild_from_mapping_stash (source_position().beats()); + model()->finish_domain_bounce (cmd); _model_changed_connection.disconnect (); model()->ContentsChanged (); diff --git a/libs/evoral/ControlList.cc b/libs/evoral/ControlList.cc index b01708adb4..6d913c99a7 100644 --- a/libs/evoral/ControlList.cc +++ b/libs/evoral/ControlList.cc @@ -2247,14 +2247,14 @@ ControlList::start_domain_bounce (Temporal::DomainBounceInfo& dbi) for (auto const & e : _events) { timepos_t t (e->when); t.set_time_domain (dbi.to); - dbi.positions.insert (std::make_pair (&e->when, e->when)); + dbi.positions.insert (std::make_pair (&e->when, t)); } } void ControlList::finish_domain_bounce (Temporal::DomainBounceInfo& dbi) { - if (time_domain() == dbi.from) { + if (time_domain() == dbi.to) { return; } diff --git a/libs/evoral/ControlSet.cc b/libs/evoral/ControlSet.cc index 7c01bfe467..405a756d66 100644 --- a/libs/evoral/ControlSet.cc +++ b/libs/evoral/ControlSet.cc @@ -104,6 +104,29 @@ ControlSet::clear_controls () } } +void +ControlSet::start_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + for (auto & c : _controls) { + std::shared_ptr cl = c.second->list(); + if (cl && cl->time_domain() != cmd.to) { + cl->start_domain_bounce (cmd); + } + } +} + +void +ControlSet::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + for (auto & c : _controls) { + std::shared_ptr cl = c.second->list(); + if (cl && cl->time_domain() != cmd.to) { + cl->finish_domain_bounce (cmd); + } + } +} + + } // namespace Evoral /* No good place for this so just put it here */ @@ -113,3 +136,4 @@ std::operator<< (std::ostream & str, Evoral::Parameter const & p) { return str << p.type() << '-' << p.id() << '-' << (int) p.channel(); } + diff --git a/libs/evoral/evoral/ControlSet.h b/libs/evoral/evoral/ControlSet.h index 870bdbf7e0..20614e5527 100644 --- a/libs/evoral/evoral/ControlSet.h +++ b/libs/evoral/evoral/ControlSet.h @@ -30,6 +30,7 @@ #include #include "pbd/signals.h" +#include "temporal/domain_swap.h" #include "temporal/types.h" #include "evoral/visibility.h" @@ -41,7 +42,8 @@ namespace Evoral { class Control; class ControlEvent; -class LIBEVORAL_API ControlSet : public boost::noncopyable { +class LIBEVORAL_API ControlSet : public boost::noncopyable, public Temporal::TimeDomainSwapper +{ public: ControlSet (); ControlSet (const ControlSet&); @@ -71,6 +73,9 @@ public: Glib::Threads::Mutex& control_lock() const { return _control_lock; } + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); + protected: virtual void control_list_marked_dirty () {} virtual void control_list_interpolation_changed (Parameter const&, ControlList::InterpolationStyle) {}