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.
This commit is contained in:
Robin Gareus 2018-12-16 04:07:55 +01:00
parent e4d3ebfb66
commit 6b1b72a247
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 44 additions and 34 deletions

View file

@ -126,6 +126,8 @@ protected:
SlavableControlList slavables () const { return SlavableControlList(); }
private:
inline void find_next_ac_event (boost::shared_ptr<AutomationControl>, double start, double end, Evoral::ControlEvent& ev) const;
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
};

View file

@ -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<double>::max();
for (li = _controls.begin(); li != _controls.end(); ++li) {
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (only_active && (!c || !c->automation_playback())) {
continue;
}
boost::shared_ptr<SlavableAutomationControl> sc
= boost::dynamic_pointer_cast<SlavableAutomationControl>(li->second);
if (sc) {
sc->find_next_event (now, end, next_event);
}
Evoral::ControlList::const_iterator i;
boost::shared_ptr<const Evoral::ControlList> alist (li->second->list());
Evoral::ControlEvent cp (now, 0.0f);
if (!alist) {
continue;
}
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;
if (only_active) {
boost::shared_ptr<ControlList> 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);
}
}
if (i != alist->end() && (*i)->when < end) {
if ((*i)->when < next_event.when) {
next_event.when = (*i)->when;
} else {
for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) {
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (c) {
find_next_ac_event (c, start, end, next_event);
}
}
}
return next_event.when != std::numeric_limits<double>::max();
}
void
Automatable::find_next_ac_event (boost::shared_ptr<AutomationControl> c, double start, double end, Evoral::ControlEvent& next_event) const
{
boost::shared_ptr<SlavableAutomationControl> sc
= boost::dynamic_pointer_cast<SlavableAutomationControl>(c);
if (sc) {
sc->find_next_event (start, end, next_event);
}
Evoral::ControlList::const_iterator i;
boost::shared_ptr<const Evoral::ControlList> 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 > start) {
break;
}
}
if (i != alist->end() && (*i)->when < end) {
if ((*i)->when < next_event.when) {
next_event.when = (*i)->when;
}
}
}