+void
+Automatable::automation_run (samplepos_t start, pframes_t nframes, bool only_active)
+{
+ if (only_active) {
+ boost::shared_ptr<ControlList> cl = _automated_controls.reader ();
+ for (ControlList::const_iterator ci = cl->begin(); ci != cl->end(); ++ci) {
+ (*ci)->automation_run (start, nframes);
+ }
+ return;
+ }
+
+ for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
+ boost::shared_ptr<AutomationControl> c =
+ boost::dynamic_pointer_cast<AutomationControl>(li->second);
+ if (!c) {
+ continue;
+ }
+ c->automation_run (start, nframes);
+ }
+}
+
+void
+Automatable::automation_list_automation_state_changed (Evoral::Parameter param, AutoState as)
+{
+ {
+ boost::shared_ptr<AutomationControl> c (automation_control(param));
+ assert (c && c->list());
+
+ RCUWriter<ControlList> writer (_automated_controls);
+ boost::shared_ptr<ControlList> cl = writer.get_copy ();
+
+ ControlList::iterator fi = std::find (cl->begin(), cl->end(), c);
+ if (fi != cl->end()) {
+ cl->erase (fi);
+ }
+ switch (as) {
+ /* all potential automation_playback() states */
+ case Play:
+ case Touch:
+ case Latch:
+ cl->push_back (c);
+ break;
+ case Off:
+ case Write:
+ break;
+ }
+ }
+ _automated_controls.flush();
+}
+