From 6b1b72a247bf04c81292fc41af4f69c9b7f90379 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 16 Dec 2018 04:07:55 +0100 Subject: [PATCH] Optimize automation-event process splitting Use RCU of automated parameter when looking for next automation event to use for split processing. This speeds up PluginInsert processing when rolling for plugins with many not-automated parameters. --- libs/ardour/ardour/automatable.h | 2 + libs/ardour/automatable.cc | 70 ++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index fe14cacf77..d2fbb1aa8d 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -126,6 +126,8 @@ protected: SlavableControlList slavables () const { return SlavableControlList(); } private: + inline void find_next_ac_event (boost::shared_ptr, double start, double end, Evoral::ControlEvent& ev) const; + PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals }; diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 51a58ce942..981c4b571f 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -614,47 +614,55 @@ Automatable::clear_controls () } bool -Automatable::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const +Automatable::find_next_event (double start, double end, Evoral::ControlEvent& next_event, bool only_active) const { - Controls::const_iterator li; - next_event.when = std::numeric_limits::max(); - for (li = _controls.begin(); li != _controls.end(); ++li) { - boost::shared_ptr c - = boost::dynamic_pointer_cast(li->second); - - if (only_active && (!c || !c->automation_playback())) { - continue; + if (only_active) { + boost::shared_ptr cl = _automated_controls.reader (); + for (ControlList::const_iterator ci = cl->begin(); ci != cl->end(); ++ci) { + if ((*ci)->automation_playback()) { + find_next_ac_event (*ci, start, end, next_event); + } + } + } else { + for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) { + boost::shared_ptr c + = boost::dynamic_pointer_cast(li->second); + if (c) { + find_next_ac_event (c, start, end, next_event); + } } + } + return next_event.when != std::numeric_limits::max(); +} - boost::shared_ptr sc - = boost::dynamic_pointer_cast(li->second); +void +Automatable::find_next_ac_event (boost::shared_ptr c, double start, double end, Evoral::ControlEvent& next_event) const +{ + boost::shared_ptr sc + = boost::dynamic_pointer_cast(c); - if (sc) { - sc->find_next_event (now, end, next_event); - } + if (sc) { + sc->find_next_event (start, end, next_event); + } - Evoral::ControlList::const_iterator i; - boost::shared_ptr alist (li->second->list()); - Evoral::ControlEvent cp (now, 0.0f); - if (!alist) { - continue; - } + Evoral::ControlList::const_iterator i; + boost::shared_ptr alist (c->list()); + Evoral::ControlEvent cp (start, 0.0f); + if (!alist) { + return; + } - for (i = lower_bound (alist->begin(), alist->end(), &cp, Evoral::ControlList::time_comparator); - i != alist->end() && (*i)->when < end; ++i) { - if ((*i)->when > now) { - break; - } + for (i = lower_bound (alist->begin(), alist->end(), &cp, Evoral::ControlList::time_comparator); i != alist->end() && (*i)->when < end; ++i) { + if ((*i)->when > start) { + break; } + } - if (i != alist->end() && (*i)->when < end) { - if ((*i)->when < next_event.when) { - next_event.when = (*i)->when; - } + if (i != alist->end() && (*i)->when < end) { + if ((*i)->when < next_event.when) { + next_event.when = (*i)->when; } } - - return next_event.when != std::numeric_limits::max(); } -- 2.30.2