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;
|
bool masters_curve_multiply (framepos_t, framepos_t, float*, framecnt_t) const;
|
||||||
|
|
||||||
virtual double reduce_by_masters_locked (double val, bool) 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 handle_master_change (boost::shared_ptr<AutomationControl>);
|
||||||
virtual bool boolean_automation_run_locked (framepos_t start, pframes_t len);
|
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
|
void
|
||||||
SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
|
SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
|
||||||
{
|
{
|
||||||
@ -323,17 +332,20 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
|
|||||||
}
|
}
|
||||||
|
|
||||||
pre_remove_master (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);
|
Glib::Threads::RWLock::WriterLock lm (master_lock);
|
||||||
|
|
||||||
Masters::const_iterator mi = _masters.find (m->id ());
|
Masters::const_iterator mi = _masters.find (m->id ());
|
||||||
|
|
||||||
/* when un-assigning we apply the master-value permanently */
|
|
||||||
if (mi != _masters.end()) {
|
if (mi != _masters.end()) {
|
||||||
new_val *= mi->second.master_ratio ();
|
master_ratio = mi->second.master_ratio ();
|
||||||
|
update_value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_masters.erase (m->id())) {
|
if (!_masters.erase (m->id())) {
|
||||||
@ -341,10 +353,21 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_value) {
|
||||||
|
/* when un-assigning we apply the master-value permanently */
|
||||||
|
double new_val = old_val * master_ratio;
|
||||||
|
|
||||||
if (old_val != new_val) {
|
if (old_val != new_val) {
|
||||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
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 */
|
MasterStatusChange (); /* EMIT SIGNAL */
|
||||||
|
|
||||||
/* no need to update boolean masters records, since the MR will have
|
/* no need to update boolean masters records, since the MR will have
|
||||||
@ -360,8 +383,10 @@ SlavableAutomationControl::clear_masters ()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double new_val = AutomationControl::get_double();
|
const double old_val = AutomationControl::get_double();
|
||||||
const double old_val = new_val;
|
|
||||||
|
bool update_value = false;
|
||||||
|
double master_ratio = 0;
|
||||||
|
|
||||||
/* null ptr means "all masters */
|
/* null ptr means "all masters */
|
||||||
pre_remove_master (boost::shared_ptr<AutomationControl>());
|
pre_remove_master (boost::shared_ptr<AutomationControl>());
|
||||||
@ -371,15 +396,26 @@ SlavableAutomationControl::clear_masters ()
|
|||||||
if (_masters.empty()) {
|
if (_masters.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* permanently apply masters value */
|
master_ratio = get_masters_value_locked ();
|
||||||
new_val *= get_masters_value_locked ();
|
update_value = true;
|
||||||
|
|
||||||
_masters.clear ();
|
_masters.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_value) {
|
||||||
|
/* permanently apply masters value */
|
||||||
|
double new_val = old_val * master_ratio;
|
||||||
|
|
||||||
if (old_val != new_val) {
|
if (old_val != new_val) {
|
||||||
AutomationControl::set_double (new_val, Controllable::NoGroup);
|
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 */
|
MasterStatusChange (); /* EMIT SIGNAL */
|
||||||
|
|
||||||
/* no need to update boolean masters records, since all MRs will have
|
/* no need to update boolean masters records, since all MRs will have
|
||||||
|
@ -123,6 +123,8 @@ public:
|
|||||||
void slide (iterator before, double distance);
|
void slide (iterator before, double distance);
|
||||||
void shift (double before, double distance);
|
void shift (double before, double distance);
|
||||||
|
|
||||||
|
void y_transform (boost::function<double(double)> callback);
|
||||||
|
|
||||||
/** add automation events
|
/** add automation events
|
||||||
* @param when absolute time in samples
|
* @param when absolute time in samples
|
||||||
* @param value parameter value
|
* @param value parameter value
|
||||||
|
@ -250,6 +250,19 @@ ControlList::extend_to (double when)
|
|||||||
return true;
|
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
|
void
|
||||||
ControlList::_x_scale (double factor)
|
ControlList::_x_scale (double factor)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user