From a80ca3079c2301a4ae45fee601662be4121ccb76 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 14 Sep 2011 19:22:49 +0000 Subject: 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 --- libs/ardour/automation_event.cc | 103 +++++++++++++++++++++------------------- 1 file 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::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::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::iterator n = nascent.begin(); n != nascent.end(); ++n) { + for (list::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); } -- cgit v1.2.3