diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index e11eaa439c..f28296d81e 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -161,12 +161,12 @@ class LIBARDOUR_API AudioRegion : public Region, public AudioReadable /* automation */ std::shared_ptr - control(const Evoral::Parameter& id, bool create=false) { + control(const Evoral::Parameter& id, bool create=false) { return _automatable.control(id, create); } virtual std::shared_ptr - control(const Evoral::Parameter& id) const { + control(const Evoral::Parameter& id) const { return _automatable.control(id); } diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index 55a4270c19..0e40021b67 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -34,6 +34,7 @@ #include "evoral/ControlSet.h" +#include "temporal/domain_swap.h" #include "temporal/domain_provider.h" #include "ardour/libardour_visibility.h" @@ -50,7 +51,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 +class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable, public Temporal::TimeDomainProvider, public Temporal::TimeDomainSwapper { public: Automatable(Session&, Temporal::TimeDomainProvider const &); @@ -119,6 +120,9 @@ public: PBD::Signal0 AutomationStateChanged; + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); + protected: Session& _a_session; diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 9ec902c175..a5f1190c2c 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -38,6 +38,8 @@ #include "pbd/stateful.h" #include "pbd/statefuldestructible.h" +#include "temporal/domain_provider.h" +#include "temporal/domain_swap.h" #include "temporal/types.h" #include "ardour/ardour.h" @@ -173,8 +175,12 @@ public: Temporal::TimeDomain position_time_domain() const { return _start.time_domain(); } - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); - void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + /* Similar to, but not identical to the Temporal::TimeDomainSwapper API */ + + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); + + void set_time_domain (Temporal::TimeDomain); class ChangeSuspender { public: @@ -209,7 +215,7 @@ private: Lock, Cue, Scene, - Domain + Domain, }; void emit_signal (Signal); @@ -233,7 +239,7 @@ private: }; /** A collection of session locations including unique dedicated locations (loop, punch, etc) */ -class LIBARDOUR_API Locations : public SessionHandleRef, public PBD::StatefulDestructible +class LIBARDOUR_API Locations : public SessionHandleRef, public PBD::StatefulDestructible, public Temporal::TimeDomainProvider, public Temporal::TimeDomainSwapper { public: typedef std::list LocationList; @@ -303,8 +309,11 @@ public: void find_all_between (timepos_t const & start, timepos_t const & end, LocationList&, Location::Flags); - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); - void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + void set_time_domain (Temporal::TimeDomain); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); + + void time_domain_changed (); PBD::Signal1 current_changed; diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index c6d9621b34..b61f49950a 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -26,7 +26,6 @@ #include #include "temporal/beats.h" -#include "temporal/domainswap.h" #include "temporal/range.h" #include "pbd/string_convert.h" @@ -55,7 +54,7 @@ class ThawList; template class MidiRingBuffer; -class LIBARDOUR_API MidiRegion : public Region, public Temporal::TimeDomainSwapper +class LIBARDOUR_API MidiRegion : public Region { public: ~MidiRegion(); @@ -117,8 +116,8 @@ class LIBARDOUR_API MidiRegion : public Region, public Temporal::TimeDomainSwapp timecnt_t const & read_length, MidiChannelFilter* filter) const; - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); - void swap_domain (Temporal::TimeDomain, Temporal::TimeDomain); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); protected: diff --git a/libs/ardour/ardour/pannable.h b/libs/ardour/ardour/pannable.h index 1179b95994..1c3253fbec 100644 --- a/libs/ardour/ardour/pannable.h +++ b/libs/ardour/ardour/pannable.h @@ -76,6 +76,9 @@ public: bool has_state() const { return _has_state; } + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); + protected: virtual XMLNode& state () const; diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index c56f014117..ed4ca9e0c9 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -301,7 +301,8 @@ public: void set_capture_insertion_in_progress (bool yn); void time_domain_changed (); - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); protected: friend class Session; diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index aa1416138b..00e575ce9a 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -29,6 +29,7 @@ #include +#include "temporal/domain_swap.h" #include "temporal/timeline.h" #include "temporal/range.h" @@ -96,6 +97,7 @@ class LIBARDOUR_API Region , public std::enable_shared_from_this , public Trimmable , public Movable + , public Temporal::TimeDomainSwapper { public: typedef std::vector > SourceList; @@ -115,8 +117,8 @@ public: const DataType& data_type () const { return _type; } Temporal::TimeDomain time_domain() const; - virtual void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); - virtual void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); /** How the region parameters play together: * @@ -386,7 +388,7 @@ public: /* automation */ virtual std::shared_ptr - control (const Evoral::Parameter& id, bool create=false) = 0; + control (const Evoral::Parameter& id, bool create=false) = 0; virtual std::shared_ptr control (const Evoral::Parameter& id) const = 0; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index c7450f8f67..aad8930af4 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -41,6 +41,7 @@ #include "pbd/controllable.h" #include "pbd/destructible.h" +#include "temporal/domain_swap.h" #include "temporal/types.h" #include "ardour/ardour.h" @@ -612,7 +613,6 @@ public: virtual void use_captured_sources (SourceList& srcs, CaptureInfos const &) {} - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); protected: friend class Session; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 21eae1975e..8eaf7672e4 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1387,7 +1387,8 @@ public: bool bang_trigger_at(int32_t route_index, int32_t row_index); bool unbang_trigger_at(int32_t route_index, int32_t row_index); - PBD::Command* globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); protected: friend class AudioEngine; diff --git a/libs/ardour/ardour/session_playlists.h b/libs/ardour/ardour/session_playlists.h index 242c78c2c0..b68435436a 100644 --- a/libs/ardour/ardour/session_playlists.h +++ b/libs/ardour/ardour/session_playlists.h @@ -70,7 +70,8 @@ public: std::vector > get_unused () const; uint32_t n_playlists() const; - void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to); + void start_domain_bounce (Temporal::DomainBounceInfo&); + void finish_domain_bounce (Temporal::DomainBounceInfo&); private: friend class Session; diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 3fe3b0129d..952b44503b 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -743,3 +743,13 @@ Automatable::find_prev_ac_event (std::shared_ptr c, timepos_t ++i; } } + +void +Automatable::start_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ +} + +void +Automatable::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ +} diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 8b2017ac9e..b7a1ec4591 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -92,22 +92,8 @@ Location::Location (Session& s, timepos_t const & start, timepos_t const & end, set_position_time_domain (_session.time_domain()); } -void -Location::set_position_time_domain (TimeDomain domain) -{ - if (_start.time_domain() == domain) { - return; - } - - _start.set_time_domain (domain); - _end.set_time_domain (domain); - - emit_signal (Domain); /* EMIT SIGNAL */ -} - Location::Location (const Location& other) : SessionHandleRef (other._session) - , StatefulDestructible() , _name (other._name) , _start (other._start) , _end (other._end) @@ -253,6 +239,26 @@ Location::actually_emit_signal (Signal s) } } + +void +Location::set_position_time_domain (TimeDomain domain) +{ + if (_start.time_domain() == domain) { + return; + } + + _start.set_time_domain (domain); + _end.set_time_domain (domain); + + // emit_signal (Domain); /* EMIT SIGNAL */ +} + +void +Location::set_time_domain (TimeDomain domain) +{ + set_position_time_domain (domain); +} + /** Set location name */ void Location::set_name (const std::string& str) @@ -777,32 +783,53 @@ Location::set_scene_change (std::shared_ptr sc) } void -Location::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Location::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { - assert (domain_swap); - - if (_start.time_domain() == from) { - - _start.set_time_domain (to); - _end.set_time_domain (to); - - domain_swap->add (_start); - domain_swap->add (_end); + if (_start.time_domain() == cmd.to) { + /* has the right domain to begin with */ + return; } + + timepos_t s (_start); + timepos_t e (_end); + + s.set_time_domain (cmd.to); + e.set_time_domain (cmd.to); + + cmd.positions.insert (std::make_pair (&_start, s)); + cmd.positions.insert (std::make_pair (&_end, e)); } void -Location::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Location::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) { - if (_start.time_domain() == from) { - set_position_time_domain (to); + if (_start.time_domain() == cmd.to) { + /* had the right domain to begin with */ + return; } + + TimeDomainPosChanges::iterator tpc; + timepos_t s; + timepos_t e; + + tpc = cmd.positions.find (&_start); + assert (tpc != cmd.positions.end()); + s = tpc->second; + s.set_time_domain (cmd.from); + + tpc = cmd.positions.find (&_end); + assert (tpc != cmd.positions.end()); + e = tpc->second; + e.set_time_domain (cmd.from); + + set (s, e); } /*---------------------------------------------------------------------- */ Locations::Locations (Session& s) : SessionHandleRef (s) + , Temporal::TimeDomainProvider (s, false) /* session is our parent */ { current_location = 0; } @@ -1890,21 +1917,28 @@ Locations::clear_cue_markers (samplepos_t start, samplepos_t end) } void -Locations::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Locations::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { Glib::Threads::RWLock::WriterLock lm (_lock); - for (auto & l : locations) { - l->globally_change_time_domain (from, to); - } + for (auto & l : locations) { + l->start_domain_bounce (cmd); + } } void -Locations::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Locations::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + for (auto & l : locations) { + l->finish_domain_bounce (cmd); + } +} + +void +Locations::time_domain_changed () { Glib::Threads::RWLock::WriterLock lm (_lock); for (auto & l : locations) { - l->change_time_domain (from, to); + l->set_time_domain (time_domain()); } - } diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 7e993e7d97..5424f140af 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -1793,18 +1793,17 @@ MidiModel::create_mapping_stash (Temporal::Beats const & src_pos_offset) Event& off (n->off_event()); audio_time = tmap->superclock_at (src_pos_offset + off.time()); tempo_mapping_stash.insert (std::make_pair (&off, audio_time)); - } for (auto const & s : sysexes()) { superclock_t audio_time = tmap->superclock_at (src_pos_offset + s->time()); - tempo_mapping_stash.insert (std::make_pair ((void*)s.get(), audio_time)); + tempo_mapping_stash.insert (std::make_pair (s.get(), audio_time)); } for (uint8_t chan = 0; chan < 16; ++chan) { for (auto const & p : pitches(chan)) { superclock_t audio_time = tmap->superclock_at (src_pos_offset + p->time()); - tempo_mapping_stash.insert (std::make_pair ((void*) &p, audio_time)); + tempo_mapping_stash.insert (std::make_pair (p.get(), audio_time)); } } @@ -1827,6 +1826,7 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset) } TempoMap::SharedPtr tmap (TempoMap::use()); + NoteDiffCommand* note_cmd = new_note_diff_command (_("conform to tempo map")); for (auto & n : notes()) { @@ -1836,17 +1836,21 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset) TempoMappingStash::iterator tms (tempo_mapping_stash.find (&on)); assert (tms != tempo_mapping_stash.end()); Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset); - on.set_time (beat_time); + + note_cmd->change (n, NoteDiffCommand::StartTime, beat_time); tms = tempo_mapping_stash.find (&off); assert (tms != tempo_mapping_stash.end()); beat_time = tmap->quarters_at_superclock (tms->second) - src_pos_offset; off.set_time (beat_time); + note_cmd->change (n, NoteDiffCommand::Length, beat_time); } + apply_diff_command_as_subcommand (_midi_source.session(), note_cmd); + for (auto & s : sysexes()) { - TempoMappingStash::iterator tms (tempo_mapping_stash.find ((void*) &s)); + TempoMappingStash::iterator tms (tempo_mapping_stash.find (s.get())); assert (tms != tempo_mapping_stash.end()); Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset); s->set_time (beat_time); @@ -1854,7 +1858,7 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset) for (uint8_t chan = 0; chan < 16; ++chan) { for (auto & p : pitches(chan)) { - TempoMappingStash::iterator tms (tempo_mapping_stash.find ((void*) &p)); + TempoMappingStash::iterator tms (tempo_mapping_stash.find (p.get())); assert (tms != tempo_mapping_stash.end()); Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset); p->set_time (beat_time); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 8c1d4de5ca..57882752ea 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -614,23 +614,24 @@ MidiRegion::merge (std::shared_ptr other_region) } void -MidiRegion::swap_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +MidiRegion::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { - if (from == Temporal::BeatTime) { - model()->create_mapping_stash (source_position().beats()); - } else { - model()->rebuild_from_mapping_stash (source_position().beats()); + /* Deal with the region position & length */ - _model_changed_connection.disconnect (); - model()->ContentsChanged (); - model()->ContentsChanged.connect_same_thread (_model_changed_connection, boost::bind (&MidiRegion::model_contents_changed, this)); + Region::start_domain_bounce (cmd); + if (cmd.from == Temporal::BeatTime) { + model()->create_mapping_stash (source_position().beats()); } } void -MidiRegion::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +MidiRegion::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) { - Region::globally_change_time_domain (from, to); - swap_domain (from, to); - Temporal::domain_swap->add (*this); + Region::finish_domain_bounce (cmd); + + model()->rebuild_from_mapping_stash (source_position().beats()); + + _model_changed_connection.disconnect (); + model()->ContentsChanged (); + model()->ContentsChanged.connect_same_thread (_model_changed_connection, boost::bind (&MidiRegion::model_contents_changed, this)); } diff --git a/libs/ardour/pannable.cc b/libs/ardour/pannable.cc index badacaa4aa..e35a33dd74 100644 --- a/libs/ardour/pannable.cc +++ b/libs/ardour/pannable.cc @@ -266,3 +266,14 @@ Pannable::set_state (const XMLNode& root, int version) return 0; } + +void +Pannable::start_domain_bounce (Temporal::DomainBounceInfo&) +{ +} + +void +Pannable::finish_domain_bounce (Temporal::DomainBounceInfo&) +{ +} + diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 81a8b6efa3..42a3bd89c3 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -3530,17 +3530,38 @@ Playlist::rdiff_and_add_command (Session* session) } void -Playlist::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Playlist::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { RegionReadLock rlock (this); for (auto & region : regions) { - region->globally_change_time_domain (from, to); + region->start_domain_bounce (cmd); } } + +void +Playlist::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + ThawList thawlist; + + clear_changes (); + + { + RegionWriteLock rlock (this); + for (auto & region : regions) { + thawlist.add (region); + region->finish_domain_bounce (cmd); + } + } + + thawlist.release (); + rdiff_and_add_command (&_session); +} + void Playlist::time_domain_changed () { +#if 0 using namespace Temporal; TimeDomainProvider::time_domain_changed (); @@ -3549,8 +3570,8 @@ Playlist::time_domain_changed () Temporal::TimeDomain from = (to == AudioTime ? BeatTime : AudioTime); for (auto & region : regions) { - region->change_time_domain (from, to); + region->swap_time_domain (from, to); } - +#endif } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 3dd0b01685..1372a670cf 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -2270,27 +2270,39 @@ Region::time_domain() const } void -Region::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Region::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { - assert (Temporal::domain_swap); + if (locked()) { + return; + } /* recall that the _length member is a timecnt_t, and so holds both * position *and* length. */ - if (_length.val().time_domain() == from) { - timecnt_t& l (_length.non_const_val()); - l.set_time_domain (to); - Temporal::domain_swap->add (l); + if (_length.val().time_domain() != cmd.from) { + return; } + + timecnt_t& l (_length.non_const_val()); + + timecnt_t saved (l); + saved.set_time_domain (cmd.to); + + cmd.counts.insert (std::make_pair (&l, saved)); } void -Region::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +Region::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) { - std::cerr << name() << " change td to " << to << std::endl; - if (_length.val().time_domain() == from) { - timecnt_t& l (_length.non_const_val()); - l.set_time_domain (to); - } + clear_changes (); + + Temporal::TimeDomainCntChanges::iterator tc = cmd.counts.find (&_length.non_const_val()); + assert (tc != cmd.counts.end()); + + /* switch domains back (but with modified TempoMap, presumably */ + tc->second.set_time_domain (cmd.from); + _length = tc->second; + + send_change (Properties::length); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 2c3f83c88c..912f03aa1d 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -6349,8 +6349,3 @@ Route::tempo_map_changed () _triggerbox->tempo_map_changed (); } } - -void -Route::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) -{ -} diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 776dbd912e..09718dee42 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -7787,15 +7787,3 @@ Session::foreach_route (void (Route::*method)()) } } -void -Session::time_domain_changed () -{ - using namespace Temporal; - - TimeDomainProvider::time_domain_changed (); - - Temporal::TimeDomain to = time_domain(); - Temporal::TimeDomain from = (to == AudioTime ? BeatTime : AudioTime); - - _locations->change_time_domain (from, to); -} diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc index a1cd2427f8..afd1b0196c 100644 --- a/libs/ardour/session_playlists.cc +++ b/libs/ardour/session_playlists.cc @@ -689,11 +689,31 @@ SessionPlaylists::foreach (boost::function) } void -SessionPlaylists::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +SessionPlaylists::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { Glib::Threads::Mutex::Lock lm (lock); for (auto & pl : playlists) { - pl->globally_change_time_domain (from, to); + pl->start_domain_bounce (cmd); + } +} + +void +SessionPlaylists::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + /* We cannot hold the playlist lock while finishing a domain bounce + */ + + std::vector > copy; + + { + Glib::Threads::Mutex::Lock lm (lock); + for (auto & pl : playlists) { + copy.push_back (pl); + } + } + + for (auto & pl : copy) { + pl->finish_domain_bounce (cmd); } } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 6035d08845..cfacc6a2a2 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -3346,6 +3346,7 @@ Session::add_stateful_diff_command (std::shared_ptr s void Session::begin_reversible_command (const string& name) { + std::cerr << "begin REV-C [" << name << "]\n"; begin_reversible_command (g_quark_from_string (name.c_str ())); } @@ -3395,6 +3396,7 @@ Session::abort_reversible_command () if (_current_trans != 0) { DEBUG_UNDO_HISTORY ( string_compose ("Abort Reversible Command: %1", _current_trans->name ())); + std::cerr << "abort REV-C [" << _current_trans->name() << "]\n"; _current_trans->clear(); delete _current_trans; _current_trans = 0; @@ -3421,6 +3423,7 @@ Session::commit_reversible_command (Command *cmd) return; } + std::cerr << "commit REV-C [" << _current_trans->name() << "]\n"; struct timeval now; if (cmd) { @@ -3460,6 +3463,8 @@ Session::commit_reversible_command (Command *cmd) gettimeofday (&now, 0); _current_trans->set_timestamp (now); + std::cerr << "Add command with " << _current_trans->size() << std::endl; + _history.add (_current_trans); _current_trans = 0; } diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index d81890a979..62125f0e9d 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -299,21 +299,42 @@ Session::any_duration_to_samples (samplepos_t position, AnyTime const & duration return duration.samples; } -PBD::Command* -Session::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) +void +Session::start_domain_bounce (Temporal::DomainBounceInfo& cmd) { - PBD::Command* undo_command = new Temporal::TimeDomainCommand (from, to); - { std::shared_ptr rl (routes.reader()); for (auto const& r : *rl) { - r->globally_change_time_domain (from, to); + r->start_domain_bounce (cmd); } } - _playlists->globally_change_time_domain (from, to); - _locations->globally_change_time_domain (from, to); - - return undo_command; + _playlists->start_domain_bounce(cmd); + _locations->start_domain_bounce (cmd); } + +void +Session::finish_domain_bounce (Temporal::DomainBounceInfo& cmd) +{ + { + std::shared_ptr rl (routes.reader()); + + for (auto const& r : *rl) { + r->finish_domain_bounce (cmd); + } + } + + _playlists->finish_domain_bounce (cmd); + _locations->finish_domain_bounce (cmd); +} + +void +Session::time_domain_changed () +{ + TimeDomainProvider::time_domain_changed (); + + // _playlists->set_time_domain (time_domain()); + // _locations->set_time_domain (time_domain()); +} + diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h index 890d0a8a95..4736b31040 100644 --- a/libs/pbd/pbd/undo.h +++ b/libs/pbd/pbd/undo.h @@ -60,6 +60,8 @@ public: void add_command (PBD::Command* const); void remove_command (PBD::Command* const); + std::list::size_type size() const { return actions.size(); } + void operator() (); void undo (); void redo (); diff --git a/libs/temporal/domainswap.cc b/libs/temporal/domain_swap.cc similarity index 56% rename from libs/temporal/domainswap.cc rename to libs/temporal/domain_swap.cc index 5558062480..49d8eea6ba 100644 --- a/libs/temporal/domainswap.cc +++ b/libs/temporal/domain_swap.cc @@ -16,39 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "temporal/domainswap.h" +#include "temporal/domain_swap.h" using namespace Temporal; -void -TimeDomainCommand::add (TimeDomainSwapper& tds) -{ - tds.DropReferences.connect_same_thread (tds_connections, boost::bind (&TimeDomainCommand::going_away, this, &tds)); - swappers.insert (&tds); -} - -void -TimeDomainCommand::going_away (TimeDomainSwapper* tds) -{ - Swappers::iterator i = swappers.find (tds); - - if (i != swappers.end()) { - swappers.erase (i); - } -} - -void -TimeDomainCommand::operator() () -{ - for (auto & swapper : swappers) { - swapper->swap_domain (from, to); - } -} - -void -TimeDomainCommand::undo () -{ - for (auto & swapper : swappers) { - swapper->swap_domain (to, from); - } -} diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index d08500a55b..d89552d665 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -4864,49 +4864,6 @@ TempoCommand::operator() () TempoMap::update (map); } -DomainSwapInformation* Temporal::domain_swap (0); - -DomainSwapInformation* -DomainSwapInformation::start(TimeDomain prev) -{ - TEMPO_MAP_ASSERT (!domain_swap); - domain_swap = new DomainSwapInformation (prev); - return domain_swap; -} - -DomainSwapInformation::~DomainSwapInformation () -{ - TEMPO_MAP_ASSERT (this == domain_swap); - undo (); - domain_swap = 0; -} - -void -DomainSwapInformation::clear () -{ - counts.clear (); - positions.clear (); -} - -void -DomainSwapInformation::undo () -{ - std::cerr << "DSI::undo on " << counts.size() << " lengths and " << positions.size() << " positions\n"; - for (auto & c : counts) { - c->set_time_domain (previous); - } - - for (auto & p : positions) { - p->set_time_domain (previous); - } - - for (auto & tt : time_things) { - tt->swap_domain (previous == AudioTime ? BeatTime : AudioTime, previous); - } - - clear (); -} - TempoMapCutBuffer::TempoMapCutBuffer (timecnt_t const & dur) : _start_tempo (nullptr) , _end_tempo (nullptr) diff --git a/libs/temporal/temporal/domainswap.h b/libs/temporal/temporal/domain_swap.h similarity index 52% rename from libs/temporal/temporal/domainswap.h rename to libs/temporal/temporal/domain_swap.h index 5fd6d9c034..1630a19174 100644 --- a/libs/temporal/temporal/domainswap.h +++ b/libs/temporal/temporal/domain_swap.h @@ -30,56 +30,38 @@ namespace Temporal { +typedef std::map TimeDomainPosChanges; +typedef std::map TimeDomainCntChanges; + +struct LIBTEMPORAL_API DomainBounceInfo; + struct LIBTEMPORAL_API TimeDomainSwapper : public virtual PBD::Destructible { - virtual ~TimeDomainSwapper() {} - virtual void swap_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) = 0; -}; - - -struct LIBTEMPORAL_API TimeDomainCommand : public PBD::Command { public: - TimeDomainCommand (TimeDomain f, TimeDomain t) : from (f), to (t) {} - void add (TimeDomainSwapper&); - - void operator() (); - void undo (); - - private: - TimeDomain from; - TimeDomain to; - - typedef std::set Swappers; - Swappers swappers; - PBD::ScopedConnectionList tds_connections; - - void going_away (TimeDomainSwapper*); - + virtual ~TimeDomainSwapper() {} + virtual void start_domain_bounce (DomainBounceInfo&) = 0; + virtual void finish_domain_bounce (DomainBounceInfo&) = 0; }; -class LIBTEMPORAL_API DomainSwapInformation { - public: - static DomainSwapInformation* start (TimeDomain prev); +/* A DomainBounceInfo functions in two roles: + * + * 1. as part of an UndoTransaction reflecting actions taken by a user that + * modified time domains of one or more objects. + * + * 2. as a standalone object used during temporary domain swaps that records + * (perhaps opaquely) what was changed and provides a way to revert it. + */ - ~DomainSwapInformation (); +struct LIBTEMPORAL_API DomainBounceInfo +{ + DomainBounceInfo (TimeDomain f, TimeDomain t) : from (f), to (t) {} - void add (timecnt_t& t) { counts.push_back (&t); } - void add (timepos_t& p) { positions.push_back (&p); } - void add (TimeDomainSwapper& tt) { time_things.push_back (&tt); } - void clear (); + const TimeDomain from; + const TimeDomain to; - private: - DomainSwapInformation (TimeDomain prev) : previous (prev) {} - - std::vector counts; - std::vector positions; - std::vector time_things; - TimeDomain previous; - - void undo (); + TimeDomainPosChanges positions; + TimeDomainCntChanges counts; }; -extern LIBTEMPORAL_API DomainSwapInformation* domain_swap; - } #endif /* __tmeporal_domain_swap_h__ */ diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h index e24e70a4e2..0b2df9c1dd 100644 --- a/libs/temporal/temporal/tempo.h +++ b/libs/temporal/temporal/tempo.h @@ -42,7 +42,7 @@ #include "temporal/beats.h" #include "temporal/bbt_argument.h" #include "temporal/bbt_time.h" -#include "temporal/domainswap.h" +#include "temporal/domain_swap.h" #include "temporal/superclock.h" #include "temporal/timeline.h" #include "temporal/types.h" diff --git a/libs/temporal/wscript b/libs/temporal/wscript index bbdbc620c1..9fe008f52f 100644 --- a/libs/temporal/wscript +++ b/libs/temporal/wscript @@ -28,7 +28,7 @@ temporal_sources = [ 'debug.cc', 'bbt_time.cc', 'beats.cc', - 'domainswap.cc', + 'domain_swap.cc', 'enums.cc', 'range.cc', 'superclock.cc',