diff options
author | Robin Gareus <robin@gareus.org> | 2017-07-15 20:52:50 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-07-16 16:52:12 +0200 |
commit | 06ca52d5a5c405a5cb2b3f2d827edc60712412e9 (patch) | |
tree | 4fd2417f75f49743624fb3caa6f9672fc999b769 /libs/ardour | |
parent | 906cf85982c209caebed3053c3a33d77ca6ddee0 (diff) |
Add API to run automation only (emit Changed signal).
Note: MuteControl already implemented this,
This removes the special case of boolean_automation_run().
Likewise this removes special-cases for actually_set_value() during
automation playback.
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/automation_control.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/slavable_automation_control.h | 2 | ||||
-rw-r--r-- | libs/ardour/automation_control.cc | 50 | ||||
-rw-r--r-- | libs/ardour/slavable_automation_control.cc | 33 |
4 files changed, 58 insertions, 29 deletions
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index 6fe88ca52d..0ac4a08c7b 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -104,6 +104,8 @@ public: actually_set_value (val, PBD::Controllable::NoGroup); } + virtual void automation_run (framepos_t start, pframes_t nframes); + double lower() const { return _desc.lower; } double upper() const { return _desc.upper; } double normal() const { return _desc.normal; } diff --git a/libs/ardour/ardour/slavable_automation_control.h b/libs/ardour/ardour/slavable_automation_control.h index eaa4341616..091d55b989 100644 --- a/libs/ardour/ardour/slavable_automation_control.h +++ b/libs/ardour/ardour/slavable_automation_control.h @@ -46,6 +46,8 @@ public: bool slaved_to (boost::shared_ptr<AutomationControl>) const; bool slaved () const; + virtual void automation_run (framepos_t start, pframes_t nframes); + double get_masters_value () const { Glib::Threads::RWLock::ReaderLock lm (master_lock); return get_masters_value_locked (); diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index acd4c7a760..dbff577ead 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -146,6 +146,27 @@ AutomationControl::grouped_controls () const } } +void +AutomationControl::automation_run (framepos_t start, pframes_t nframes) +{ + if (!automation_playback ()) { + return; + } + + assert (_list); + bool valid = false; + double val = _list->rt_safe_eval (start, valid); + if (!valid) { + return; + } + if (toggled ()) { + const double thresh = .5 * (_desc.upper - _desc.lower); + set_value_unchecked (val >= thresh ? _desc.upper : _desc.lower); + } else { + set_value_unchecked (val); + } +} + /** Set the value and do the right thing based on automation state * (e.g. record if necessary, etc.) * @param value `user' value @@ -156,7 +177,6 @@ AutomationControl::actually_set_value (double value, PBD::Controllable::GroupCon boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (_list); const framepos_t pos = _session.transport_frame(); bool to_list; - double old_value; /* We cannot use ::get_value() here since that is virtual, and intended to return a scalar value that in some way reflects the state of the @@ -173,36 +193,28 @@ AutomationControl::actually_set_value (double value, PBD::Controllable::GroupCon anything has changed) is the one derived from the automation event list. */ + float old_value = Control::user_double(); - if (!al) { - to_list = false; - old_value = Control::user_double(); + if (al && al->automation_write ()) { + to_list = true; } else { - if (al->automation_write ()) { - to_list = true; - old_value = Control::user_double (); - } else if (al->automation_playback()) { - to_list = false; - old_value = al->eval (pos); - } else { - to_list = false; - old_value = Control::user_double (); - } + to_list = false; } Control::set_double (value, pos, to_list); - if (old_value != value) { - //AutomationType at = (AutomationType) _parameter.type(); - //std::cerr << "++++ Changed (" << enum_2_string (at) << ", " << enum_2_string (gcd) << ") = " << value - //<< " (was " << old_value << ") @ " << this << std::endl; + if (old_value != (float)value) { +#if 0 + AutomationType at = (AutomationType) _parameter.type(); + std::cerr << "++++ Changed (" << enum_2_string (at) << ", " << enum_2_string (gcd) << ") = " << value + << " (was " << old_value << ") @ " << this << std::endl; +#endif Changed (true, gcd); if (!al || !al->automation_playback ()) { _session.set_dirty (); } } - } void diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index 3128543dde..3285518522 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -290,11 +290,7 @@ SlavableAutomationControl::master_changed (bool /*from_self*/, GroupControlDispo { boost::shared_ptr<AutomationControl> m = wm.lock (); assert (m); - Glib::Threads::RWLock::ReaderLock lm (master_lock, Glib::Threads::TRY_LOCK); - if (!lm.locked ()) { - /* boolean_automation_run_locked () special case */ - return; - } + Glib::Threads::RWLock::ReaderLock lm (master_lock); bool send_signal = handle_master_change (m); lm.release (); // update_boolean_masters_records() takes lock @@ -521,6 +517,28 @@ SlavableAutomationControl::handle_master_change (boost::shared_ptr<AutomationCon return true; // emit Changed } +void +SlavableAutomationControl::automation_run (framepos_t start, pframes_t nframes) +{ + if (!automation_playback ()) { + return; + } + + assert (_list); + bool valid = false; + double val = _list->rt_safe_eval (start, valid); + if (!valid) { + return; + } + if (toggled ()) { + const double thresh = .5 * (_desc.upper - _desc.lower); + bool on = (val >= thresh) || (get_masters_value () >= thresh); + set_value_unchecked (on ? _desc.upper : _desc.lower); + } else { + set_value_unchecked (val * get_masters_value ()); + } +} + bool SlavableAutomationControl::boolean_automation_run_locked (framepos_t start, pframes_t len) { @@ -551,11 +569,6 @@ SlavableAutomationControl::boolean_automation_run_locked (framepos_t start, pfra if (mr->second.yn() != yn) { rv |= handle_master_change (ac); mr->second.set_yn (yn); - /* notify the GUI, without recursion: - * master_changed() above will ignore the change if the lock is held. - */ - ac->set_value_unchecked (yn ? 1. : 0.); - ac->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ } } return rv; |