summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-09-14 19:22:49 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-09-14 19:22:49 +0000
commita80ca3079c2301a4ae45fee601662be4121ccb76 (patch)
tree89323750969dc7b9582e0bb0dc0171dbd5e18cfb
parenta3ea8641e4be48a51ad7baaeb533865624a1e895 (diff)
patch from #3537 that fixes crashes when playhead is moved if fader automation is on the 'write' setting (from carl)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@10086 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/automation_event.cc103
1 files changed, 55 insertions, 48 deletions
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index 50942f9c43..065a6b909b 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -352,14 +352,19 @@ AutomationList::rt_add (double when, double value)
if (lm.locked()) {
assert (!nascent.empty());
- if (nascent.back()->events.empty() ){
- nascent.back()->events.push_back (point_factory (when, value));
- } else if (when > nascent.back()->events.back()->when) {
- nascent.back()->events.push_back (point_factory (when, value));
- }
+ /* we don't worry about adding events out of time order as we will
+ sort them in merge_nascent.
+ */
+ nascent.back()->events.push_back (point_factory (when, value));
}
}
+struct ControlEventTimeComparator {
+ bool operator() (ControlEvent* a, ControlEvent* b) {
+ return a->when < b->when;
+ }
+};
+
void
AutomationList::merge_nascent (double when)
{
@@ -370,41 +375,41 @@ AutomationList::merge_nascent (double when)
return;
}
- //thin automation data in each nascent packet
- for (list<NascentInfo*>::iterator n = nascent.begin(); n != nascent.end(); ++n) {
- ControlEvent *next = NULL;
- ControlEvent *cur = NULL;
- ControlEvent *prev = NULL;
- int counter = 0;
- AutomationEventList delete_list;
- for (AutomationEventList::iterator x = (*n)->events.begin(); x != (*n)->events.end(); x++) {
- next = *x;
- counter++;
- if (counter > 2) { //wait for the third iteration so "cur" & "prev" are initialized
+ //thin automation data in each nascent packet
+ for (list<NascentInfo*>::iterator n = nascent.begin(); n != nascent.end(); ++n) {
+ ControlEvent *next = NULL;
+ ControlEvent *cur = NULL;
+ ControlEvent *prev = NULL;
+ int counter = 0;
+ AutomationEventList delete_list;
+ for (AutomationEventList::iterator x = (*n)->events.begin(); x != (*n)->events.end(); x++) {
+ next = *x;
+ counter++;
+ if (counter > 2) { //wait for the third iteration so "cur" & "prev" are initialized
- float area = fabs(
- 0.5 * (
- prev->when*(cur->value - next->value) +
- cur->when*(next->value - prev->value) +
- next->when*(prev->value - cur->value) )
- );
+ float area = fabs(
+ 0.5 * (
+ prev->when*(cur->value - next->value) +
+ cur->when*(next->value - prev->value) +
+ next->when*(prev->value - cur->value) )
+ );
//printf( "area: %3.16f\n", area);
- if (area < ( Config->get_automation_thinning_strength() ) )
- delete_list.push_back(cur);
- }
- prev = cur;
- cur = next;
- }
+ if (area < ( Config->get_automation_thinning_strength() ) )
+ delete_list.push_back(cur);
+ }
+ prev = cur;
+ cur = next;
+ }
- for (AutomationEventList::iterator x = delete_list.begin(); x != delete_list.end(); ++x) {
- (*n)->events.remove(*x);
- delete *x;
- }
+ for (AutomationEventList::iterator x = delete_list.begin(); x != delete_list.end(); ++x) {
+ (*n)->events.remove(*x);
+ delete *x;
+ }
- }
+ }
- for (list<NascentInfo*>::iterator n = nascent.begin(); n != nascent.end(); ++n) {
+ for (list<NascentInfo*>::iterator n = nascent.begin(); n != nascent.end(); ++n) {
NascentInfo* ninfo = *n;
AutomationEventList& nascent_events (ninfo->events);
@@ -416,6 +421,8 @@ AutomationList::merge_nascent (double when)
continue;
}
+ nascent_events.sort (ControlEventTimeComparator ());
+
if (ninfo->start_time < 0.0) {
ninfo->start_time = nascent_events.front()->when;
}
@@ -424,7 +431,7 @@ AutomationList::merge_nascent (double when)
ninfo->end_time = nascent_events.back()->when;
}
- bool preexisting = !events.empty();
+ bool preexisting = !events.empty();
if (!preexisting) {
@@ -482,23 +489,23 @@ AutomationList::merge_nascent (double when)
}
}
- //if you write past the end of existing automation,
- //then treat it as virgin territory
+ //if you write past the end of existing automation,
+ //then treat it as virgin territory
if (range_end == events.end()) {
- need_adjacent_end_clamp = false;
- }
+ need_adjacent_end_clamp = false;
+ }
- /* clamp point before */
- if (need_adjacent_start_clamp) {
- events.insert (range_begin, point_factory (ninfo->start_time-1, start_value));
- }
+ /* clamp point before */
+ if (need_adjacent_start_clamp) {
+ events.insert (range_begin, point_factory (ninfo->start_time-1, start_value));
+ }
- events.insert (range_begin, nascent_events.begin(), nascent_events.end());
+ events.insert (range_begin, nascent_events.begin(), nascent_events.end());
- /* clamp point after */
- if (need_adjacent_end_clamp) {
- events.insert (range_begin, point_factory (ninfo->end_time+1, end_value));
- }
+ /* clamp point after */
+ if (need_adjacent_end_clamp) {
+ events.insert (range_begin, point_factory (ninfo->end_time+1, end_value));
+ }
events.erase (range_begin, range_end);
}