Apply master-value to automation on disconnect.
This commit is contained in:
parent
c1912b6d51
commit
8e6f71b8c1
@ -138,6 +138,7 @@ protected:
|
||||
bool masters_curve_multiply (framepos_t, framepos_t, float*, framecnt_t) const;
|
||||
|
||||
virtual double reduce_by_masters_locked (double val, bool) const;
|
||||
virtual double scale_automation_callback (double val, double ratio) const;
|
||||
|
||||
virtual bool handle_master_change (boost::shared_ptr<AutomationControl>);
|
||||
virtual bool boolean_automation_run_locked (framepos_t start, pframes_t len);
|
||||
|
@ -314,6 +314,15 @@ SlavableAutomationControl::master_going_away (boost::weak_ptr<AutomationControl>
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
SlavableAutomationControl::scale_automation_callback (double value, double ratio) const
|
||||
{
|
||||
/* derived classes can override this and e.g. add/subtract. */
|
||||
value *= ratio;
|
||||
value = std::max (lower(), std::min(upper(), value));
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
|
||||
{
|
||||
@ -323,17 +332,20 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
|
||||
}
|
||||
|
||||
pre_remove_master (m);
|
||||
double new_val = AutomationControl::get_double();
|
||||
const double old_val = new_val;
|
||||
|
||||
const double old_val = AutomationControl::get_double();
|
||||
|
||||
bool update_value = false;
|
||||
double master_ratio = 0;
|
||||
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (master_lock);
|
||||
|
||||
Masters::const_iterator mi = _masters.find (m->id ());
|
||||
|
||||
/* when un-assigning we apply the master-value permanently */
|
||||
if (mi != _masters.end()) {
|
||||
new_val *= mi->second.master_ratio ();
|
||||
master_ratio = mi->second.master_ratio ();
|
||||
update_value = true;
|
||||
}
|
||||
|
||||
if (!_masters.erase (m->id())) {
|
||||
@ -341,8 +353,19 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
|
||||
}
|
||||
}
|
||||
|
||||
if (old_val != new_val) {
|
||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
||||
if (update_value) {
|
||||
/* when un-assigning we apply the master-value permanently */
|
||||
double new_val = old_val * master_ratio;
|
||||
|
||||
if (old_val != new_val) {
|
||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
||||
}
|
||||
|
||||
/* ..and update automation */
|
||||
if (_list) {
|
||||
// do we need to freeze/thaw the list? probably no: iterators & positions don't change
|
||||
_list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
|
||||
}
|
||||
}
|
||||
|
||||
MasterStatusChange (); /* EMIT SIGNAL */
|
||||
@ -360,8 +383,10 @@ SlavableAutomationControl::clear_masters ()
|
||||
return;
|
||||
}
|
||||
|
||||
double new_val = AutomationControl::get_double();
|
||||
const double old_val = new_val;
|
||||
const double old_val = AutomationControl::get_double();
|
||||
|
||||
bool update_value = false;
|
||||
double master_ratio = 0;
|
||||
|
||||
/* null ptr means "all masters */
|
||||
pre_remove_master (boost::shared_ptr<AutomationControl>());
|
||||
@ -371,15 +396,26 @@ SlavableAutomationControl::clear_masters ()
|
||||
if (_masters.empty()) {
|
||||
return;
|
||||
}
|
||||
/* permanently apply masters value */
|
||||
new_val *= get_masters_value_locked ();
|
||||
|
||||
master_ratio = get_masters_value_locked ();
|
||||
update_value = true;
|
||||
_masters.clear ();
|
||||
}
|
||||
|
||||
if (old_val != new_val) {
|
||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
||||
if (update_value) {
|
||||
/* permanently apply masters value */
|
||||
double new_val = old_val * master_ratio;
|
||||
|
||||
if (old_val != new_val) {
|
||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
||||
}
|
||||
|
||||
/* ..and update automation */
|
||||
if (_list) {
|
||||
// do we need to freeze/thaw the list? probably no: iterators & positions don't change
|
||||
_list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
|
||||
}
|
||||
}
|
||||
|
||||
MasterStatusChange (); /* EMIT SIGNAL */
|
||||
|
||||
/* no need to update boolean masters records, since all MRs will have
|
||||
|
@ -123,6 +123,8 @@ public:
|
||||
void slide (iterator before, double distance);
|
||||
void shift (double before, double distance);
|
||||
|
||||
void y_transform (boost::function<double(double)> callback);
|
||||
|
||||
/** add automation events
|
||||
* @param when absolute time in samples
|
||||
* @param value parameter value
|
||||
|
@ -250,6 +250,19 @@ ControlList::extend_to (double when)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ControlList::y_transform (boost::function<double(double)> callback)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||
for (iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
(*i)->value = callback ((*i)->value);
|
||||
}
|
||||
mark_dirty ();
|
||||
}
|
||||
maybe_signal_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
ControlList::_x_scale (double factor)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user