diff options
author | Carl Hetherington <carl@carlh.net> | 2008-12-16 23:21:01 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2008-12-16 23:21:01 +0000 |
commit | 2ebb1af2997b8e8f162635b11e8acc5c5d0fe563 (patch) | |
tree | a88ebc1e46dbe43cc760626eddd57d0feac81216 /libs/evoral | |
parent | 43b14aa6098e266f07e1d7dfe4a8a65edda36b0a (diff) |
Implement #2425: option for automation to follow region moves.
git-svn-id: svn://localhost/ardour2/branches/3.0@4326 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/evoral')
-rw-r--r-- | libs/evoral/evoral/ControlList.hpp | 3 | ||||
-rw-r--r-- | libs/evoral/evoral/types.hpp | 11 | ||||
-rw-r--r-- | libs/evoral/src/ControlList.cpp | 96 |
3 files changed, 74 insertions, 36 deletions
diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index 36799300fe..48050f9e93 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -120,7 +120,7 @@ public: void erase_range (double start, double end); void erase (iterator); void erase (iterator, iterator); - void move_range (iterator start, iterator end, double, double); + void move_ranges (RangeMoveList const &); void modify (iterator, double, double); boost::shared_ptr<ControlList> cut (double, double); @@ -241,6 +241,7 @@ protected: bool rt_safe_earliest_event_linear_unlocked (double start, double end, double& x, double& y, bool inclusive) const; boost::shared_ptr<ControlList> cut_copy_clear (double, double, int op); + bool erase_range_internal (double start, double end, EventList &); virtual void maybe_signal_changed (); diff --git a/libs/evoral/evoral/types.hpp b/libs/evoral/evoral/types.hpp index fc1001c7d8..4bca6f1288 100644 --- a/libs/evoral/evoral/types.hpp +++ b/libs/evoral/evoral/types.hpp @@ -20,6 +20,7 @@ #define EVORAL_TYPES_HPP #include <stdint.h> +#include <list> namespace Evoral { @@ -41,6 +42,16 @@ typedef double EventLength; /** Type of an event (opaque, mapped by application) */ typedef uint32_t EventType; +/** Type to describe the movement of a time range */ +struct RangeMove { + RangeMove (EventTime f, FrameTime l, EventTime t) : from (f), length (l), to (t) {} + EventTime from; ///< start of the range + FrameTime length; ///< length of the range + EventTime to; ///< new start of the range +}; + +typedef std::list<RangeMove> RangeMoveList; + } // namespace Evoral #endif // EVORAL_TYPES_HPP diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index e1cea8e191..033e375a8a 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -390,16 +390,10 @@ ControlList::erase_range (double start, double endt) { Glib::Mutex::Lock lm (_lock); - ControlEvent cp (start, 0.0f); - iterator s; - iterator e; + erased = erase_range_internal (start, endt, _events); - if ((s = lower_bound (_events.begin(), _events.end(), &cp, time_comparator)) != _events.end()) { - cp.when = endt; - e = upper_bound (_events.begin(), _events.end(), &cp, time_comparator); - _events.erase (s, e); + if (erased) { reposition_for_rt_add (0); - erased = true; mark_dirty (); } @@ -410,36 +404,22 @@ ControlList::erase_range (double start, double endt) } } -void -ControlList::move_range (iterator start, iterator end, double xdelta, double ydelta) +bool +ControlList::erase_range_internal (double start, double endt, EventList & events) { - /* note: we assume higher level logic is in place to avoid this - reordering the time-order of control events in the list. ie. all - points after end are later than (end)->when. - */ - - { - Glib::Mutex::Lock lm (_lock); - - while (start != end) { - (*start)->when += xdelta; - (*start)->value += ydelta; - if (isnan ((*start)->value)) { - abort (); - } - ++start; - } - - if (!_frozen) { - _events.sort (event_time_less_than); - } else { - _sort_pending = true; - } - - mark_dirty (); + bool erased = false; + ControlEvent cp (start, 0.0f); + iterator s; + iterator e; + + if ((s = lower_bound (events.begin(), events.end(), &cp, time_comparator)) != events.end()) { + cp.when = endt; + e = upper_bound (events.begin(), events.end(), &cp, time_comparator); + events.erase (s, e); + erased = true; } - maybe_signal_changed (); + return erased; } void @@ -1315,5 +1295,51 @@ ControlList::paste (ControlList& alist, double pos, float times) return true; } +/** Move automation around according to a list of region movements */ +void +ControlList::move_ranges (RangeMoveList const & movements) +{ + { + Glib::Mutex::Lock lm (_lock); + + /* a copy of the events list before we started moving stuff around */ + EventList old_events = _events; + + /* clear the source and destination ranges in the new list */ + for (RangeMoveList::const_iterator i = movements.begin (); i != movements.end (); ++i) { + + erase_range_internal (i->from, i->from + i->length, _events); + erase_range_internal (i->to, i->to + i->length, _events); + + } + + /* copy the events into the new list */ + for (RangeMoveList::const_iterator i = movements.begin (); i != movements.end (); ++i) { + iterator j = old_events.begin (); + EventTime const limit = i->from + i->length; + EventTime const dx = i->to - i->from; + while (j != old_events.end () && (*j)->when <= limit) { + if ((*j)->when >= i->from) { + ControlEvent* ev = new ControlEvent (**j); + ev->when += dx; + _events.push_back (ev); + } + ++j; + } + } + + if (!_frozen) { + _events.sort (event_time_less_than); + } else { + _sort_pending = true; + } + + reposition_for_rt_add (0); + mark_dirty (); + } + + maybe_signal_changed (); +} + } // namespace Evoral |