From 65ecc1b40e91d9b352ebf1bf3dc0cf22821085c7 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 15 Aug 2020 01:52:38 +0200 Subject: [PATCH] Do not interpolate away explicit MIDI automation points #8362 --- libs/evoral/ControlList.cc | 31 +++++++++++++++++++++++++++---- libs/evoral/Sequence.cc | 2 +- libs/evoral/evoral/ControlList.h | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/libs/evoral/ControlList.cc b/libs/evoral/ControlList.cc index cde1718e23..5b8b6349f4 100644 --- a/libs/evoral/ControlList.cc +++ b/libs/evoral/ControlList.cc @@ -1587,7 +1587,7 @@ ControlList::rt_safe_earliest_event_discrete_unlocked (double start, double& x, * \return true if event is found (and \a x and \a y are valid). */ bool -ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, double& y, bool inclusive) const +ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, double& y, bool inclusive, double min_x_delta) const { // cout << "earliest_event(start: " << start << ", x: " << x << ", y: " << y << ", inclusive: " << inclusive << ")" << endl; @@ -1595,9 +1595,30 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, do if (_events.empty()) { // 0 events return false; } else if (_events.end() == ++length_check_iter) { // 1 event - return rt_safe_earliest_event_discrete_unlocked (start, x, y, inclusive); + return rt_safe_earliest_event_discrete_unlocked (start + min_x_delta, x, y, inclusive); } + + if (min_x_delta > 0) { + /* if there is an event between [start and start + min_x_delta], use it, + * otherwise interpolate at start + min_x_delta + */ + build_search_cache_if_necessary (start); + const ControlEvent* first = *_search_cache.first; + if (_search_cache.first != _events.end()) { + if (((first->when > start) || (inclusive && first->when == start)) && first->when < start + min_x_delta) { + x = first->when; + y = first->value; + /* Move left of cache to this point + * (Optimize for immediate call this cycle within range) */ + _search_cache.left = x; + return true; + } + } + } + + start += min_x_delta; + // Hack to avoid infinitely repeating the same event build_search_cache_if_necessary (start); @@ -1671,9 +1692,11 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, do x = first->when + (y - first->value) / (double)slope; } - /*cerr << first->value << " @ " << first->when << " ... " +#if 0 + cerr << first->value << " @ " << first->when << " ... " << next->value << " @ " << next->when - << " = " << y << " @ " << x << endl;*/ + << " = " << y << " @ " << x << endl; +#endif assert( (y >= first->value && y <= next->value) || (y <= first->value && y >= next->value) ); diff --git a/libs/evoral/Sequence.cc b/libs/evoral/Sequence.cc index 0f501732d0..2ba0b0bb24 100644 --- a/libs/evoral/Sequence.cc +++ b/libs/evoral/Sequence.cc @@ -370,7 +370,7 @@ Sequence