diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-04-21 14:58:12 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-04-21 14:58:12 +0000 |
commit | 15cf746b80e01cf463f402340943e81b5c8db698 (patch) | |
tree | 36041abe357d6b49045e369721984539b353c222 /libs/ardour/automation_event.cc | |
parent | 4894ec8c413c0447ed3fd60ea2fcf3975ee96ceb (diff) |
start of The Fix for automation touch+write
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6943 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/automation_event.cc')
-rw-r--r-- | libs/ardour/automation_event.cc | 197 |
1 files changed, 65 insertions, 132 deletions
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc index 4799411b6c..cd381565f1 100644 --- a/libs/ardour/automation_event.cc +++ b/libs/ardour/automation_event.cc @@ -54,6 +54,7 @@ static void dumpit (const AutomationList& al, string prefix = "") #endif AutomationList::AutomationList (double defval) + : _touch_saved_point (-1.0, -1.0) { _frozen = 0; changed_when_thawed = false; @@ -66,7 +67,6 @@ AutomationList::AutomationList (double defval) max_xval = 0; // means "no limit" default_value = defval; _dirty = false; - rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); sort_pending = false; @@ -75,6 +75,7 @@ AutomationList::AutomationList (double defval) } AutomationList::AutomationList (const AutomationList& other) + : _touch_saved_point (-1.0, -1.0) { _frozen = 0; changed_when_thawed = false; @@ -87,7 +88,6 @@ AutomationList::AutomationList (const AutomationList& other) _touching = other._touching; _new_touch = false; _dirty = false; - rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); sort_pending = false; @@ -104,6 +104,7 @@ AutomationList::AutomationList (const AutomationList& other) } AutomationList::AutomationList (const AutomationList& other, double start, double end) + : _touch_saved_point (-1.0, -1.0) { _frozen = 0; changed_when_thawed = false; @@ -115,7 +116,6 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl _state = other._state; _touching = other._touching; _dirty = false; - rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); sort_pending = false; @@ -138,6 +138,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl } AutomationList::AutomationList (const XMLNode& node) + : _touch_saved_point (-1.0, -1.0) { _frozen = 0; changed_when_thawed = false; @@ -148,7 +149,6 @@ AutomationList::AutomationList (const XMLNode& node) _dirty = false; _state = Auto_Off; _style = Auto_Absolute; - rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); sort_pending = false; @@ -165,6 +165,10 @@ AutomationList::~AutomationList() for (AutomationEventList::iterator x = events.begin(); x != events.end(); ++x) { delete (*x); } + + for (AutomationEventList::iterator x = nascent_events.begin(); x != nascent_events.end(); ++x) { + delete (*x); + } } bool @@ -189,7 +193,6 @@ AutomationList::operator= (const AutomationList& other) max_xval = other.max_xval; default_value = other.default_value; - rt_insertion_point = events.end(); lookup_cache.range.first = events.end(); mark_dirty (); @@ -207,6 +210,7 @@ AutomationList::maybe_signal_changed () if (_frozen) { changed_when_thawed = true; } else { + cerr << " SC, events holds " << events.size() << endl; StateChanged (); } } @@ -234,6 +238,7 @@ AutomationList::start_touch () { _touching = true; _new_touch = true; + _touch_saved_point.when = -1.0; } void @@ -241,37 +246,6 @@ AutomationList::stop_touch (bool mark, double when) { _touching = false; _new_touch = false; - - if (mark) { - /* get the value of the next point after "when", and replicate - it directly after when, unless of course its already there. - */ - - double val; - AutomationList::const_iterator i; - - for (i = const_begin(); i != const_end(); ++i) { - if ((*i)->when >= when) { - break; - } - } - - if (i == const_end()) { - val = default_value; - } else { - val = (*i)->value; - } - - /* if the existing point is at "when", add a new one right after it, - otherwise add it directly where the touch ended. - */ - - if ((*i)->when == when) { - when++; - } - - add (when, val); - } } void @@ -317,98 +291,75 @@ void AutomationList::_x_scale (double factor) void AutomationList::reposition_for_rt_add (double when) { - rt_insertion_point = events.end(); + merge_nascent (); } -#define last_rt_insertion_point rt_insertion_point - void AutomationList::rt_add (double when, double value) { /* this is for automation recording */ if ((_state & Auto_Touch) && !_touching) { - return; - } - - // cerr << "RT: alist @ " << this << " add " << value << " @ " << when << endl; - - { - Glib::Mutex::Lock lm (lock); - - iterator where; - TimeComparator cmp; - ControlEvent cp (when, 0.0); - bool done = false; - - if ((last_rt_insertion_point != events.end()) && ((*last_rt_insertion_point)->when < when) ) { - - /* we have a previous insertion point, so we should delete - everything between it and the position where we are going - to insert this point. - */ - - iterator after = last_rt_insertion_point; + return; + } - if (++after != events.end()) { - iterator far = after; + assert (when > nascent_events.back()->when); + nascent_events.push_back (point_factory (when, value)); +} - while (far != events.end()) { - if ((*far)->when > when) { - break; - } - ++far; - } +void +AutomationList::merge_nascent () +{ + { + Glib::Mutex::Lock lm (lock); - if(_new_touch) { - where = far; - last_rt_insertion_point = where; - - if((*where)->when == when) { - (*where)->value = value; - done = true; - } - } else { - where = events.erase (after, far); + if (nascent_events.empty()) { + return; + } + + cerr << "Merging " << nascent_events.size() << " nascent events\n"; + + iterator i; + bool inserted = false; + double lower = nascent_events.front()->when; + double upper = nascent_events.back()->when; + + double clamp_time = upper+1; + double clamp_value = unlocked_eval (upper+1); + + cerr << "nascent range = " << lower << " .. " << upper << " will add clamp at " + << clamp_time << " = " << clamp_value << endl; + + for (i = events.begin(); i != events.end(); ) { + + /* remove all events within the range defined by nascent events, + and insert the contents of nascent events. + */ + + if ((*i)->when >= lower) { + + if (!inserted) { + events.insert (i, nascent_events.begin(), nascent_events.end()); + cerr << "did insert, events how has " << events.size() << endl; + events.insert (i, point_factory (clamp_time, clamp_value)); + inserted = true; } - } else { - - where = after; - - } - - iterator previous = last_rt_insertion_point; - --previous; - - if (last_rt_insertion_point != events.begin() && (*last_rt_insertion_point)->value == value && (*previous)->value == value) { - (*last_rt_insertion_point)->when = when; - done = true; - - } - - } else { - - where = lower_bound (events.begin(), events.end(), &cp, cmp); + if ((*i)->when > upper) { + break; + } - if (where != events.end()) { - if ((*where)->when == when) { - (*where)->value = value; - done = true; - } - } - } - - if (!done) { - last_rt_insertion_point = events.insert (where, point_factory (when, value)); - // cerr << "\tINSERTED\n"; - } - - _new_touch = false; - mark_dirty (); - } + i = events.erase (i); + } else { + cerr << "skip event at " << (*i)->when << endl; + ++i; + } + } + + nascent_events.clear (); + } - maybe_signal_changed (); + maybe_signal_changed (); } void @@ -418,8 +369,6 @@ AutomationList::fast_simple_add (double when, double value) events.insert (events.end(), point_factory (when, value)); } -#undef last_rt_insertion_point - void AutomationList::add (double when, double value) { @@ -448,10 +397,7 @@ AutomationList::add (double when, double value) } if (insert) { - events.insert (insertion_point, point_factory (when, value)); - reposition_for_rt_add (0); - } mark_dirty (); @@ -466,7 +412,6 @@ AutomationList::erase (AutomationList::iterator i) { Glib::Mutex::Lock lm (lock); events.erase (i); - reposition_for_rt_add (0); mark_dirty (); } maybe_signal_changed (); @@ -478,7 +423,6 @@ AutomationList::erase (AutomationList::iterator start, AutomationList::iterator { Glib::Mutex::Lock lm (lock); events.erase (start, end); - reposition_for_rt_add (0); mark_dirty (); } maybe_signal_changed (); @@ -532,7 +476,6 @@ AutomationList::erase_range (double start, double endt) cp.when = endt; e = upper_bound (events.begin(), events.end(), &cp, cmp); events.erase (s, e); - reposition_for_rt_add (0); erased = true; mark_dirty (); } @@ -688,6 +631,7 @@ AutomationList::thaw () } if (changed_when_thawed) { + cerr << " thaw SC, events holds " << events.size() << endl; StateChanged(); /* EMIT SIGNAL */ } } @@ -799,7 +743,6 @@ AutomationList::truncate_end (double last_coordinate) events.back()->value = last_val; } - reposition_for_rt_add (0); mark_dirty(); } @@ -905,8 +848,6 @@ AutomationList::truncate_start (double overall_length) events.push_front (point_factory (0, first_legal_value)); } - reposition_for_rt_add (0); - mark_dirty(); } @@ -1062,8 +1003,6 @@ AutomationList::cut (iterator start, iterator end) nal->events.push_back (point_factory (**x)); events.erase (x); - reposition_for_rt_add (0); - x = tmp; } @@ -1125,10 +1064,6 @@ AutomationList::cut_copy_clear (double start, double end, int op) nal->events.push_back (point_factory (end - start, unlocked_eval (end))); } - if (changed) { - reposition_for_rt_add (0); - } - mark_dirty (); } @@ -1219,7 +1154,6 @@ AutomationList::paste (AutomationList& alist, double pos, float times) } } - reposition_for_rt_add (0); mark_dirty (); } @@ -1344,7 +1278,6 @@ AutomationList::deserialize_events (const XMLNode& node) error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg; } else { mark_dirty (); - reposition_for_rt_add (0); maybe_signal_changed (); } |