only subdivide plugin-cycle when automation is playing

PluginInsert::automation_run() subdivides plugin-run on every
control-port automation event (without splitting the process cycle).

libevoral has no automation-control context, hence this function
must be implemented by Automatable.
This commit is contained in:
Robin Gareus 2015-10-07 10:42:28 +02:00
parent 5fd4ee3ef1
commit 96b45d4909
5 changed files with 43 additions and 33 deletions

View file

@ -57,6 +57,7 @@ public:
automation_control (const Evoral::Parameter& id) const;
virtual void add_control(boost::shared_ptr<Evoral::Control>);
virtual bool find_next_event(double start, double end, Evoral::ControlEvent& ev, bool only_active = true) const;
void clear_controls ();
virtual void transport_located (framepos_t now);

View file

@ -501,3 +501,42 @@ Automatable::value_as_string (boost::shared_ptr<AutomationControl> ac) const
{
return ARDOUR::value_as_string(ac->desc(), ac->get_value());
}
bool
Automatable::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
{
Controls::const_iterator li;
next_event.when = std::numeric_limits<double>::max();
for (li = _controls.begin(); li != _controls.end(); ++li) {
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (only_active && (!c || !c->automation_playback())) {
continue;
}
Evoral::ControlList::const_iterator i;
boost::shared_ptr<const Evoral::ControlList> alist (li->second->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;
}
}
}
return next_event.when != std::numeric_limits<double>::max();
}

View file

@ -60,7 +60,7 @@ public:
virtual void add_control(boost::shared_ptr<Control>);
bool find_next_event(double start, double end, ControlEvent& ev) const;
virtual bool find_next_event(double start, double end, ControlEvent& ev, bool only_active = true) const = 0;
virtual bool controls_empty() const { return _controls.size() == 0; }
virtual void clear_controls();

View file

@ -87,38 +87,6 @@ ControlSet::control (const Parameter& parameter, bool create_if_missing)
}
}
bool
ControlSet::find_next_event (double now, double end, ControlEvent& next_event) const
{
Controls::const_iterator li;
next_event.when = std::numeric_limits<double>::max();
for (li = _controls.begin(); li != _controls.end(); ++li) {
ControlList::const_iterator i;
boost::shared_ptr<const ControlList> alist (li->second->list());
ControlEvent cp (now, 0.0f);
if (!alist) {
continue;
}
for (i = lower_bound (alist->begin(), alist->end(), &cp, 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;
}
}
}
return next_event.when != std::numeric_limits<double>::max();
}
void
ControlSet::clear_controls ()
{

View file

@ -51,6 +51,8 @@ class MySequence : public Sequence<Time> {
public:
MySequence(DummyTypeMap&map) : Sequence<Time>(map) {}
virtual bool find_next_event(double start, double end, ControlEvent& ev, bool only_active) const { return false; }
boost::shared_ptr<Control> control_factory(const Parameter& param) {
const Evoral::ParameterDescriptor desc;
boost::shared_ptr<ControlList> list(new ControlList(param, desc));