From 8e6f71b8c190d2311e5547e349c4cc1fc37f131f Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 13 Jun 2017 20:57:01 +0200 Subject: Apply master-value to automation on disconnect. --- libs/ardour/ardour/slavable_automation_control.h | 1 + libs/ardour/slavable_automation_control.cc | 62 +++++++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/slavable_automation_control.h b/libs/ardour/ardour/slavable_automation_control.h index 3cfc22405c..88114d24c6 100644 --- a/libs/ardour/ardour/slavable_automation_control.h +++ b/libs/ardour/ardour/slavable_automation_control.h @@ -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); virtual bool boolean_automation_run_locked (framepos_t start, pframes_t len); diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index 53808c862a..a1fd18571a 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -314,6 +314,15 @@ SlavableAutomationControl::master_going_away (boost::weak_ptr } } +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 m) { @@ -323,17 +332,20 @@ SlavableAutomationControl::remove_master (boost::shared_ptr 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 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()); @@ -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 -- cgit v1.2.3