diff options
author | Robin Gareus <robin@gareus.org> | 2017-06-03 13:18:31 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-06-03 13:55:14 +0200 |
commit | 9581cb26e444229301d5fdafadd14ca5c0a83a18 (patch) | |
tree | 9b11e817aa385f4120f3d671c1d666abae842f7c /libs | |
parent | d662e6e0bfc4f541be2424cfe4d42b32b20c898c (diff) |
Add infrastructure for evaluating VCA automation curves
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/slavable_automation_control.h | 8 | ||||
-rw-r--r-- | libs/ardour/slavable_automation_control.cc | 55 |
2 files changed, 63 insertions, 0 deletions
diff --git a/libs/ardour/ardour/slavable_automation_control.h b/libs/ardour/ardour/slavable_automation_control.h index 6467dcd6de..f89d29c0d2 100644 --- a/libs/ardour/ardour/slavable_automation_control.h +++ b/libs/ardour/ardour/slavable_automation_control.h @@ -50,6 +50,14 @@ class LIBARDOUR_API SlavableAutomationControl : public AutomationControl return get_masters_value_locked (); } + bool get_masters_curve (framepos_t s, framepos_t e, float* v, framecnt_t l) const { + Glib::Threads::RWLock::ReaderLock lm (master_lock); + return get_masters_curve_locked (s, e, v, l); + } + virtual bool get_masters_curve_locked (framepos_t, framepos_t, float*, framecnt_t) const; + + bool masters_curve_multiply (framepos_t, framepos_t, float*, framecnt_t) const; + /* for toggled/boolean controls, returns a count of the number of masters currently enabled. For other controls, returns zero. */ diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index 6df2dd2720..40f4cb486f 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -24,6 +24,8 @@ #include "pbd/types_convert.h" #include "pbd/i18n.h" +#include "evoral/Curve.hpp" + #include "ardour/audioengine.h" #include "ardour/slavable_automation_control.h" #include "ardour/session.h" @@ -110,6 +112,59 @@ SlavableAutomationControl::get_value() const } } +bool +SlavableAutomationControl::get_masters_curve_locked (framepos_t, framepos_t, float*, framecnt_t) const +{ + /* Every AutomationControl needs to implement this as-needed. + * + * This class also provides some convenient methods which + * could be used as defaults here (depending on AutomationType) + * e.g. masters_curve_multiply() + */ + return false; +} + +bool +SlavableAutomationControl::masters_curve_multiply (framepos_t start, framepos_t end, float* vec, framecnt_t veclen) const +{ + bool rv = list()->curve().rt_safe_get_vector (start, end, vec, veclen); + if (_masters.empty()) { + return rv; + } + gain_t* scratch = _session.scratch_automation_buffer (); + for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) { + boost::shared_ptr<AutomationControl> ac (mr->second.master()); + bool got_curve; + + boost::shared_ptr<SlavableAutomationControl> sc + = boost::dynamic_pointer_cast<SlavableAutomationControl>(ac); + if (sc) { + got_curve = sc->get_masters_curve_locked (start, end, scratch, veclen); + } else { + got_curve = ac->list()->curve().rt_safe_get_vector (start, end, scratch, veclen); + } + if (got_curve) { + // TODO use SSE/AVX methods, e.g. ARDOUR::apply_gain_to_buffer, mix_buffers_no_gain + // which works as long as automation _types_ gain_t == ARDOUR::Sample type == float + if (!rv) { + // TODO optimize this, in case rv is false, direcly use "vec" above. + rv = true; + memcpy (vec, scratch, sizeof (float) * veclen); + } else { + for (framecnt_t i = 0; i < veclen; ++i) { + vec[i] *= scratch[i]; + } + } + } else if (rv) { + const float v = get_masters_value (); + for (framecnt_t i = 0; i < veclen; ++i) { + vec[i] *= v; + } + } + } + return rv; +} + void SlavableAutomationControl::actually_set_value (double value, PBD::Controllable::GroupControlDisposition gcd) { |