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:
@@ -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; }
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user