summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-04-21 14:58:12 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-04-21 14:58:12 +0000
commit15cf746b80e01cf463f402340943e81b5c8db698 (patch)
tree36041abe357d6b49045e369721984539b353c222
parent4894ec8c413c0447ed3fd60ea2fcf3975ee96ceb (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.cc3
-rw-r--r--libs/ardour/ardour/automation_event.h3
-rw-r--r--libs/ardour/automation_event.cc197
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 ();
}