+ if (update_value) {
+ /* permanently apply masters value */
+ double new_val = old_val * master_ratio;
+
+ if (old_val != new_val) {
+ AutomationControl::set_double (new_val, Controllable::NoGroup);
+ }
+
+ /* ..and update automation */
+ if (_list) {
+ XMLNode* before = &alist ()->get_state ();
+ if (!masters.empty()) {
+ for (ControlList::const_iterator m = masters.begin(); m != masters.end(); ++m) {
+ _list->list_merge (*(*m)->list().get(), boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, _2));
+ }
+ _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, list_ratio));
+ } else {
+ _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
+ }
+ XMLNode* after = &alist ()->get_state ();
+ if (*before != *after) {
+ _session.begin_reversible_command (string_compose (_("Merge VCA automation into %1"), name ()));
+ _session.commit_reversible_command (alist()->memento_command (before, after));
+ }
+ }
+ }
+
+ MasterStatusChange (); /* EMIT SIGNAL */
+
+ /* no need to update boolean masters records, since all MRs will have
+ * been removed already.
+ */
+}
+
+bool
+SlavableAutomationControl::find_next_event_locked (double now, double end, Evoral::ControlEvent& next_event) const
+{
+ 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_locked (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;
+ }
+ }