summaryrefslogtreecommitdiff
path: root/libs/ardour/slavable_automation_control.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-06-14 02:39:15 +0200
committerRobin Gareus <robin@gareus.org>2017-06-14 02:40:09 +0200
commite0a1c7690acc0c79c070bb23c992ab6b62cbf2c6 (patch)
tree2a2bdc24298ba8c18b4c2b3c4ac95b8cd182e512 /libs/ardour/slavable_automation_control.cc
parent8b917c4c1660e4a22d187a676b9dfb562aa06ee2 (diff)
Merge event control lists when disconnecting a master-ctrl
Diffstat (limited to 'libs/ardour/slavable_automation_control.cc')
-rw-r--r--libs/ardour/slavable_automation_control.cc47
1 files changed, 38 insertions, 9 deletions
diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc
index a1fd18571a..46b86c7cf5 100644
--- a/libs/ardour/slavable_automation_control.cc
+++ b/libs/ardour/slavable_automation_control.cc
@@ -166,7 +166,7 @@ SlavableAutomationControl::reduce_by_masters_locked (double value, bool ignore_a
/* need to scale given value by current master's scaling */
const double masters_value = get_masters_value_locked();
if (masters_value == 0.0) {
- value = 0.0;
+ value = 0.0; // XXX 1.0, see master_ratio(), val_master_inv()
} else {
value /= masters_value;
value = std::max (lower(), std::min(upper(), value));
@@ -337,6 +337,9 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
bool update_value = false;
double master_ratio = 0;
+ double list_ratio = 1;
+
+ boost::shared_ptr<AutomationControl> master;
{
Glib::Threads::RWLock::WriterLock lm (master_lock);
@@ -346,6 +349,8 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m
if (mi != _masters.end()) {
master_ratio = mi->second.master_ratio ();
update_value = true;
+ master = mi->second.master();
+ list_ratio *= mi->second.val_master_inv ();
}
if (!_masters.erase (m->id())) {
@@ -355,17 +360,22 @@ 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;
+ double new_val = old_val * master_ratio;
- if (old_val != new_val) {
- AutomationControl::set_double (new_val, Controllable::NoGroup);
- }
+ if (old_val != new_val) {
+ AutomationControl::set_double (new_val, Controllable::NoGroup);
+ }
- /* ..and update automation */
- if (_list) {
+ /* ..and update automation */
+ if (_list) {
+ if (master->automation_playback () && master->list()) {
+ _list->list_merge (*master->list().get(), boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, _2));
+ _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, list_ratio));
+ } else {
// 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 */
@@ -385,8 +395,10 @@ SlavableAutomationControl::clear_masters ()
const double old_val = AutomationControl::get_double();
+ ControlList masters;
bool update_value = false;
double master_ratio = 0;
+ double list_ratio = 1;
/* null ptr means "all masters */
pre_remove_master (boost::shared_ptr<AutomationControl>());
@@ -396,6 +408,17 @@ SlavableAutomationControl::clear_masters ()
if (_masters.empty()) {
return;
}
+
+ for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
+ boost::shared_ptr<AutomationControl> master = mr->second.master();
+ if (master->automation_playback () && master->list()) {
+ masters.push_back (mr->second.master());
+ list_ratio *= mr->second.val_master_inv ();
+ } else {
+ list_ratio *= mr->second.master_ratio ();
+ }
+ }
+
master_ratio = get_masters_value_locked ();
update_value = true;
_masters.clear ();
@@ -411,8 +434,14 @@ SlavableAutomationControl::clear_masters ()
/* ..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));
+ if (!masters.empty()) {
+ for (ControlList::const_iterator m = masters.begin(); m != masters.end(); ++m) {
+ _list->list_merge (*(*m)->list().get(), boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, _2));
+ }
+ _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, list_ratio));
+ } else {
+ _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
+ }
}
}