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 | |
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
-rw-r--r-- | gtk2_ardour/automation_line.cc | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/automation_event.h | 3 | ||||
-rw-r--r-- | libs/ardour/automation_event.cc | 197 |
3 files changed, 71 insertions, 132 deletions
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 94273626c3..47e5333c52 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -1199,6 +1199,7 @@ AutomationLine::hide_selection () void AutomationLine::list_changed () { + cerr << "AL " << &alist << " changed\n"; queue_reset (); } @@ -1208,6 +1209,8 @@ AutomationLine::reset_callback (const AutomationList& events) ALPoints tmp_points; uint32_t npoints = events.size(); + cerr << "Redraw with " << npoints << endl; + if (npoints == 0) { for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) { delete *i; diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h index 470445d65e..c782c1b642 100644 --- a/libs/ardour/ardour/automation_event.h +++ b/libs/ardour/ardour/automation_event.h @@ -101,6 +101,7 @@ class AutomationList : public PBD::StatefulDestructible void add (double when, double value); /* this should be private but old-school automation loading needs it in IO/Redirect */ void fast_simple_add (double when, double value); + void merge_nascent (); void reset_range (double start, double end); void erase_range (double start, double end); @@ -203,6 +204,7 @@ class AutomationList : public PBD::StatefulDestructible protected: AutomationEventList events; + AutomationEventList nascent_events; mutable Glib::Mutex lock; int8_t _frozen; bool changed_when_thawed; @@ -224,6 +226,7 @@ class AutomationList : public PBD::StatefulDestructible double max_yval; double default_value; bool sort_pending; + ControlEvent _touch_saved_point; iterator rt_insertion_point; double rt_pos; 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 (); } |