summaryrefslogtreecommitdiff
path: root/libs/ardour/slavable_automation_control.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-06-13 20:57:01 +0200
committerRobin Gareus <robin@gareus.org>2017-06-13 20:57:37 +0200
commit8e6f71b8c190d2311e5547e349c4cc1fc37f131f (patch)
treea5b33e4f6db799c5eddc839295a81905af616fa3 /libs/ardour/slavable_automation_control.cc
parentc1912b6d516b69db67757687de38a115b3b6ab69 (diff)
Apply master-value to automation on disconnect.
Diffstat (limited to 'libs/ardour/slavable_automation_control.cc')
-rw-r--r--libs/ardour/slavable_automation_control.cc62
1 files changed, 49 insertions, 13 deletions
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<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