summaryrefslogtreecommitdiff
path: root/libs/ardour/automatable.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-11-18 15:06:59 +0100
committerRobin Gareus <robin@gareus.org>2019-11-18 15:55:13 +0100
commitf49d11d5e306c8f053856e7c4bf85d1e320adcf4 (patch)
tree4f44ab1f0873a34cae0b580ea8cb03984be8a485 /libs/ardour/automatable.cc
parent81d8f0faa7ba174d3c40b1576409336471bb6540 (diff)
Automation event lookup when rolling backwards
When rolling backwards we need to be able to find the *next* event before "start".
Diffstat (limited to 'libs/ardour/automatable.cc')
-rw-r--r--libs/ardour/automatable.cc45
1 files changed, 41 insertions, 4 deletions
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc
index c146aa9757..47945326ff 100644
--- a/libs/ardour/automatable.cc
+++ b/libs/ardour/automatable.cc
@@ -620,13 +620,17 @@ Automatable::clear_controls ()
bool
Automatable::find_next_event (double start, double end, Evoral::ControlEvent& next_event, bool only_active) const
{
- next_event.when = std::numeric_limits<double>::max();
+ next_event.when = start <= end ? std::numeric_limits<double>::max() : 0;
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 (start <= end) {
+ find_next_ac_event (*ci, start, end, next_event);
+ } else {
+ find_prev_ac_event (*ci, start, end, next_event);
+ }
}
}
} else {
@@ -634,16 +638,22 @@ Automatable::find_next_event (double start, double end, Evoral::ControlEvent& ne
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (c) {
- find_next_ac_event (c, start, end, next_event);
+ if (start <= end) {
+ find_next_ac_event (c, start, end, next_event);
+ } else {
+ find_prev_ac_event (c, start, end, next_event);
+ }
}
}
}
- return next_event.when != std::numeric_limits<double>::max();
+ return next_event.when != (start <= end ? std::numeric_limits<double>::max() : 0);
}
void
Automatable::find_next_ac_event (boost::shared_ptr<AutomationControl> c, double start, double end, Evoral::ControlEvent& next_event) const
{
+ assert (start <= end);
+
boost::shared_ptr<SlavableAutomationControl> sc
= boost::dynamic_pointer_cast<SlavableAutomationControl>(c);
@@ -670,3 +680,30 @@ Automatable::find_next_ac_event (boost::shared_ptr<AutomationControl> c, double
}
}
}
+
+void
+Automatable::find_prev_ac_event (boost::shared_ptr<AutomationControl> c, double start, double end, Evoral::ControlEvent& next_event) const
+{
+ assert (start > end);
+ boost::shared_ptr<SlavableAutomationControl> sc
+ = boost::dynamic_pointer_cast<SlavableAutomationControl>(c);
+
+ if (sc) {
+ sc->find_next_event (start, end, next_event);
+ }
+
+ boost::shared_ptr<const Evoral::ControlList> alist (c->list());
+ if (!alist) {
+ return;
+ }
+
+ Evoral::ControlEvent cp (end, 0.0f);
+ Evoral::ControlList::const_iterator i = upper_bound (alist->begin(), alist->end(), &cp, Evoral::ControlList::time_comparator);
+
+ while (i != alist->end() && (*i)->when < start) {
+ if ((*i)->when > next_event.when) {
+ next_event.when = (*i)->when;
+ }
+ ++i;
+ }
+}