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.
This commit is contained in:
Robin Gareus
2017-07-15 20:52:50 +02:00
parent 906cf85982
commit 06ca52d5a5
4 changed files with 58 additions and 29 deletions

View File

@@ -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; }

View File

@@ -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 ();

View File

@@ -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

View File

@@ -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;