summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/slavable_automation_control.h2
-rw-r--r--libs/ardour/automatable.cc7
-rw-r--r--libs/ardour/slavable_automation_control.cc48
3 files changed, 57 insertions, 0 deletions
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<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);
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
@@ -345,6 +345,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<AutomationControl> ac (mr->second.master());
+
+ boost::shared_ptr<SlavableAutomationControl> sc
+ = boost::dynamic_pointer_cast<SlavableAutomationControl>(ac);
+
+ if (sc && sc->find_next_event (now, end, next_event)) {
+ rv = true;
+ }
+
+ Evoral::ControlList::const_iterator i;
+ boost::shared_ptr<const Evoral::ControlList> 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<AutomationControl> m) const
{
Glib::Threads::RWLock::ReaderLock lm (master_lock);