From 67f9f6fd75c0786d413705ad83ffc1d878eda52e Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 30 May 2017 15:13:37 +0200 Subject: [PATCH] Prepare for automation control master Basic infrastructure to allow VCA automation and Trim automation: look up events during automation playback. --- .../ardour/slavable_automation_control.h | 2 + libs/ardour/automatable.cc | 7 +++ libs/ardour/slavable_automation_control.cc | 48 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/libs/ardour/ardour/slavable_automation_control.h b/libs/ardour/ardour/slavable_automation_control.h index f1a78891e4..8827b29f6b 100644 --- a/libs/ardour/ardour/slavable_automation_control.h +++ b/libs/ardour/ardour/slavable_automation_control.h @@ -64,6 +64,8 @@ class LIBARDOUR_API SlavableAutomationControl : public AutomationControl int set_state (XMLNode const&, int); XMLNode& get_state(); + bool find_next_event (double now, double end, Evoral::ControlEvent& next_event) const; + protected: class MasterRecord { diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 00dcdec8f0..462f4f2974 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -563,6 +563,13 @@ Automatable::find_next_event (double now, double end, Evoral::ControlEvent& next continue; } + boost::shared_ptr sc + = boost::dynamic_pointer_cast(li->second); + + if (sc) { + sc->find_next_event (now, end, next_event); + } + Evoral::ControlList::const_iterator i; boost::shared_ptr alist (li->second->list()); Evoral::ControlEvent cp (now, 0.0f); diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index c06d8db7a5..51b2d30004 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -344,6 +344,54 @@ SlavableAutomationControl::clear_masters () */ } +bool +SlavableAutomationControl::find_next_event (double now, double end, Evoral::ControlEvent& next_event) const +{ + Glib::Threads::RWLock::ReaderLock lm (master_lock); + if (_masters.empty()) { + return false; + } + bool rv = false; + /* iterate over all masters check their automation lists + * for any event between "now" and "end" which is earlier than + * next_event.when. If found, set next_event.when and return true. + * (see also Automatable::find_next_event) + */ + for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) { + boost::shared_ptr ac (mr->second.master()); + + boost::shared_ptr sc + = boost::dynamic_pointer_cast(ac); + + if (sc && sc->find_next_event (now, end, next_event)) { + rv = true; + } + + Evoral::ControlList::const_iterator i; + boost::shared_ptr alist (ac->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 (i != alist->end() && (*i)->when < end) { + if ((*i)->when < next_event.when) { + next_event.when = (*i)->when; + rv = true; + } + } + } + + return rv; +} + bool SlavableAutomationControl::slaved_to (boost::shared_ptr m) const { -- 2.30.2