start removal of NoteFixer code
[ardour.git] / libs / ardour / slavable_automation_control.cc
1 /*
2  * Copyright (C) 2016-2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017-2018 Robin Gareus <robin@gareus.org>
4  * Copyright (C) 2017 Tim Mayberry <mojofunk@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #ifndef __libardour_slavable_automation_control_h__
22 #define __libardour_slavable_automation_control_h__
23
24 #include "pbd/enumwriter.h"
25 #include "pbd/error.h"
26 #include "pbd/memento_command.h"
27 #include "pbd/types_convert.h"
28
29 #include "evoral/Curve.hpp"
30
31 #include "ardour/audioengine.h"
32 #include "ardour/runtime_functions.h"
33 #include "ardour/slavable_automation_control.h"
34 #include "ardour/session.h"
35
36 #include "pbd/i18n.h"
37
38 using namespace std;
39 using namespace ARDOUR;
40 using namespace PBD;
41
42 SlavableAutomationControl::SlavableAutomationControl(ARDOUR::Session& s,
43                                                      const Evoral::Parameter&                  parameter,
44                                                      const ParameterDescriptor&                desc,
45                                                      boost::shared_ptr<ARDOUR::AutomationList> l,
46                                                      const std::string&                        name,
47                                                      Controllable::Flag                        flags)
48         : AutomationControl (s, parameter, desc, l, name, flags)
49         , _masters_node (0)
50 {
51 }
52
53 SlavableAutomationControl::~SlavableAutomationControl ()
54 {
55         if (_masters_node) {
56                 delete _masters_node;
57                 _masters_node = 0;
58         }
59 }
60
61 double
62 SlavableAutomationControl::get_masters_value_locked () const
63 {
64         if (_desc.toggled) {
65                 for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
66                         if (mr->second.master()->get_value()) {
67                                 return _desc.upper;
68                         }
69                 }
70                 return _desc.lower;
71         } else {
72
73                 double v = 1.0; /* the masters function as a scaling factor */
74
75                 for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
76                         v *= mr->second.master_ratio ();
77                 }
78
79                 return v;
80         }
81 }
82
83 double
84 SlavableAutomationControl::get_value_locked() const
85 {
86         /* read or write masters lock must be held */
87
88         if (_masters.empty()) {
89                 return Control::get_double (false, _session.transport_sample());
90         }
91
92         if (_desc.toggled) {
93                 /* for boolean/toggle controls, if this slave OR any master is
94                  * enabled, this slave is enabled. So check our own value
95                  * first, because if we are enabled, we can return immediately.
96                  */
97                 if (Control::get_double (false, _session.transport_sample())) {
98                         return _desc.upper;
99                 }
100         }
101
102         return Control::get_double() * get_masters_value_locked ();
103 }
104
105 /** Get the current effective `user' value based on automation state */
106 double
107 SlavableAutomationControl::get_value() const
108 {
109         bool from_list = _list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback();
110
111         Glib::Threads::RWLock::ReaderLock lm (master_lock);
112         if (!from_list) {
113                 if (!_masters.empty() && automation_write ()) {
114                         /* writing automation takes the fader value as-is, factor out the master */
115                         return Control::user_double ();
116                 }
117                 return get_value_locked ();
118         } else {
119                 return Control::get_double (true, _session.transport_sample()) * get_masters_value_locked();
120         }
121 }
122
123 bool
124 SlavableAutomationControl::get_masters_curve_locked (samplepos_t, samplepos_t, float*, samplecnt_t) const
125 {
126         /* Every AutomationControl needs to implement this as-needed.
127          *
128          * This class also provides some convenient methods which
129          * could be used as defaults here (depending on  AutomationType)
130          * e.g. masters_curve_multiply()
131          */
132         return false;
133 }
134
135 bool
136 SlavableAutomationControl::masters_curve_multiply (samplepos_t start, samplepos_t end, float* vec, samplecnt_t veclen) const
137 {
138         gain_t* scratch = _session.scratch_automation_buffer ();
139         bool from_list = _list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback();
140         bool rv = from_list && list()->curve().rt_safe_get_vector (start, end, scratch, veclen);
141         if (rv) {
142                 for (samplecnt_t i = 0; i < veclen; ++i) {
143                         vec[i] *= scratch[i];
144                 }
145         } else {
146                 apply_gain_to_buffer (vec, veclen, Control::get_double ());
147         }
148         if (_masters.empty()) {
149                 return rv;
150         }
151
152         for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
153                 boost::shared_ptr<SlavableAutomationControl> sc
154                         = boost::dynamic_pointer_cast<SlavableAutomationControl>(mr->second.master());
155                 assert (sc);
156                 rv |= sc->masters_curve_multiply (start, end, vec, veclen);
157                 apply_gain_to_buffer (vec, veclen, mr->second.val_master_inv ());
158         }
159         return rv;
160 }
161
162 double
163 SlavableAutomationControl::reduce_by_masters_locked (double value, bool ignore_automation_state) const
164 {
165         if (!_desc.toggled) {
166                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
167                 if (!_masters.empty() && (ignore_automation_state || !automation_write ())) {
168                         /* need to scale given value by current master's scaling */
169                         const double masters_value = get_masters_value_locked();
170                         if (masters_value == 0.0) {
171                                 value = 0.0;
172                         } else {
173                                 value /= masters_value;
174                                 value = std::max (lower(), std::min(upper(), value));
175                         }
176                 }
177         }
178         return value;
179 }
180
181 void
182 SlavableAutomationControl::actually_set_value (double value, PBD::Controllable::GroupControlDisposition gcd)
183 {
184         value = reduce_by_masters (value);
185         /* this will call Control::set_double() and emit Changed signals as appropriate */
186         AutomationControl::actually_set_value (value, gcd);
187 }
188
189 void
190 SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
191 {
192         std::pair<Masters::iterator,bool> res;
193
194         {
195                 const double master_value = m->get_value();
196                 Glib::Threads::RWLock::WriterLock lm (master_lock);
197
198                 pair<PBD::ID,MasterRecord> newpair (m->id(), MasterRecord (boost::weak_ptr<AutomationControl> (m), get_value_locked(), master_value));
199                 res = _masters.insert (newpair);
200
201                 if (res.second) {
202
203                         /* note that we bind @param m as a weak_ptr<AutomationControl>, thus
204                            avoiding holding a reference to the control in the binding
205                            itself.
206                         */
207                         m->DropReferences.connect_same_thread (res.first->second.dropped_connection, boost::bind (&SlavableAutomationControl::master_going_away, this, boost::weak_ptr<AutomationControl>(m)));
208
209                         /* Store the connection inside the MasterRecord, so
210                            that when we destroy it, the connection is destroyed
211                            and we no longer hear about changes to the
212                            AutomationControl.
213
214                            Note that this also makes it safe to store a
215                            boost::shared_ptr<AutomationControl> in the functor,
216                            since we know we will destroy the functor when the
217                            connection is destroyed, which happens when we
218                            disconnect from the master (for any reason).
219
220                            Note that we fix the "from_self" argument that will
221                            be given to our own Changed signal to "false",
222                            because the change came from the master.
223                         */
224
225                         m->Changed.connect_same_thread (res.first->second.changed_connection, boost::bind (&SlavableAutomationControl::master_changed, this, _1, _2, boost::weak_ptr<AutomationControl>(m)));
226                 }
227         }
228
229         if (res.second) {
230                 /* this will notify everyone that we're now slaved to the master */
231                 MasterStatusChange (); /* EMIT SIGNAL */
232         }
233
234         post_add_master (m);
235
236         update_boolean_masters_records (m);
237 }
238
239 int32_t
240 SlavableAutomationControl::get_boolean_masters () const
241 {
242         int32_t n = 0;
243
244         if (_desc.toggled) {
245                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
246                 for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
247                         if (mr->second.yn()) {
248                                 ++n;
249                         }
250                 }
251         }
252
253         return n;
254 }
255
256 void
257 SlavableAutomationControl::update_boolean_masters_records (boost::shared_ptr<AutomationControl> m)
258 {
259         if (_desc.toggled) {
260                 /* We may modify a MasterRecord, but we not modify the master
261                  * map, so we use a ReaderLock
262                  */
263                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
264                 Masters::iterator mi = _masters.find (m->id());
265                 if (mi != _masters.end()) {
266                         /* update MasterRecord to show whether the master is
267                            on/off. We need to store this because the master
268                            may change (in the sense of emitting Changed())
269                            several times without actually changing the result
270                            of ::get_value(). This is a feature of
271                            AutomationControls (or even just Controllables,
272                            really) which have more than a simple scalar
273                            value. For example, the master may be a mute control
274                            which can be muted_by_self() and/or
275                            muted_by_masters(). When either of those two
276                            conditions changes, Changed() will be emitted, even
277                            though ::get_value() will return the same value each
278                            time (1.0 if either are true, 0.0 if neither is).
279
280                            This provides a way for derived types to check
281                            the last known state of a Master when the Master
282                            changes. We update it after calling
283                            ::master_changed() (though derived types must do
284                            this themselves).
285                         */
286                         mi->second.set_yn (m->get_value());
287                 }
288         }
289 }
290
291 void
292 SlavableAutomationControl::master_changed (bool /*from_self*/, GroupControlDisposition gcd, boost::weak_ptr<AutomationControl> wm)
293 {
294         boost::shared_ptr<AutomationControl> m = wm.lock ();
295         assert (m);
296         Glib::Threads::RWLock::ReaderLock lm (master_lock);
297         bool send_signal = handle_master_change (m);
298         lm.release (); // update_boolean_masters_records() takes lock
299
300         update_boolean_masters_records (m);
301         if (send_signal) {
302                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
303         }
304 }
305
306 void
307 SlavableAutomationControl::master_going_away (boost::weak_ptr<AutomationControl> wm)
308 {
309         boost::shared_ptr<AutomationControl> m = wm.lock();
310         if (m) {
311                 remove_master (m);
312         }
313 }
314
315 double
316 SlavableAutomationControl::scale_automation_callback (double value, double ratio) const
317 {
318         /* derived classes can override this and e.g. add/subtract. */
319         if (toggled ()) {
320                 // XXX we should use the master's upper/lower as threshold
321                 if (ratio >= 0.5 * (upper () - lower ())) {
322                         value = upper ();
323                 }
324         } else {
325                 value *= ratio;
326         }
327         value = std::max (lower(), std::min(upper(), value));
328         return value;
329 }
330
331 void
332 SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
333 {
334         if (_session.deletion_in_progress()) {
335                 /* no reason to care about new values or sending signals */
336                 return;
337         }
338
339         pre_remove_master (m);
340
341         const double old_val = AutomationControl::get_double();
342
343         bool update_value = false;
344         double master_ratio = 0;
345         double list_ratio = toggled () ? 0 : 1;
346
347         boost::shared_ptr<AutomationControl> master;
348
349         {
350                 Glib::Threads::RWLock::WriterLock lm (master_lock);
351
352                 Masters::const_iterator mi = _masters.find (m->id ());
353
354                 if (mi != _masters.end()) {
355                         master_ratio = mi->second.master_ratio ();
356                         update_value = true;
357                         master = mi->second.master();
358                         list_ratio *= mi->second.val_master_inv ();
359                 }
360
361                 if (!_masters.erase (m->id())) {
362                         return;
363                 }
364         }
365
366         if (update_value) {
367                 /* when un-assigning we apply the master-value permanently */
368                 double new_val = old_val * master_ratio;
369
370                 if (old_val != new_val) {
371                         AutomationControl::set_double (new_val, Controllable::NoGroup);
372                 }
373
374                 /* ..and update automation */
375                 if (_list) {
376                         XMLNode* before = &alist ()->get_state ();
377                         if (master->automation_playback () && master->list()) {
378                                 _list->list_merge (*master->list().get(), boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, _2));
379                                 printf ("y-t %s  %f\n", name().c_str(), list_ratio);
380                                 _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, list_ratio));
381                         } else {
382                                 // do we need to freeze/thaw the list? probably no: iterators & positions don't change
383                                 _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
384                         }
385                         XMLNode* after = &alist ()->get_state ();
386                         if (*before != *after) {
387                                 _session.begin_reversible_command (string_compose (_("Merge VCA automation into %1"), name ()));
388                                 _session.commit_reversible_command (alist()->memento_command (before, after));
389                         }
390                 }
391         }
392
393         MasterStatusChange (); /* EMIT SIGNAL */
394
395         /* no need to update boolean masters records, since the MR will have
396          * been removed already.
397          */
398 }
399
400 void
401 SlavableAutomationControl::clear_masters ()
402 {
403         if (_session.deletion_in_progress()) {
404                 /* no reason to care about new values or sending signals */
405                 return;
406         }
407
408         const double old_val = AutomationControl::get_double();
409
410         ControlList masters;
411         bool update_value = false;
412         double master_ratio = 0;
413         double list_ratio = toggled () ? 0 : 1;
414
415         /* null ptr means "all masters */
416         pre_remove_master (boost::shared_ptr<AutomationControl>());
417
418         {
419                 Glib::Threads::RWLock::WriterLock lm (master_lock);
420                 if (_masters.empty()) {
421                         return;
422                 }
423
424                 for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
425                         boost::shared_ptr<AutomationControl> master = mr->second.master();
426                         if (master->automation_playback () && master->list()) {
427                                 masters.push_back (mr->second.master());
428                                 list_ratio *= mr->second.val_master_inv ();
429                         } else {
430                                 list_ratio *= mr->second.master_ratio ();
431                         }
432                 }
433
434                 master_ratio = get_masters_value_locked ();
435                 update_value = true;
436                 _masters.clear ();
437         }
438
439         if (update_value) {
440                 /* permanently apply masters value */
441                         double new_val = old_val * master_ratio;
442
443                         if (old_val != new_val) {
444                                 AutomationControl::set_double (new_val, Controllable::NoGroup);
445                         }
446
447                         /* ..and update automation */
448                         if (_list) {
449                                 XMLNode* before = &alist ()->get_state ();
450                                 if (!masters.empty()) {
451                                         for (ControlList::const_iterator m = masters.begin(); m != masters.end(); ++m) {
452                                                 _list->list_merge (*(*m)->list().get(), boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, _2));
453                                         }
454                                         _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, list_ratio));
455                                 } else {
456                                         _list->y_transform (boost::bind (&SlavableAutomationControl::scale_automation_callback, this, _1, master_ratio));
457                                 }
458                                 XMLNode* after = &alist ()->get_state ();
459                                 if (*before != *after) {
460                                         _session.begin_reversible_command (string_compose (_("Merge VCA automation into %1"), name ()));
461                                         _session.commit_reversible_command (alist()->memento_command (before, after));
462                                 }
463                         }
464         }
465
466         MasterStatusChange (); /* EMIT SIGNAL */
467
468         /* no need to update boolean masters records, since all MRs will have
469          * been removed already.
470          */
471 }
472
473 bool
474 SlavableAutomationControl::find_next_event_locked (double now, double end, Evoral::ControlEvent& next_event) const
475 {
476         if (_masters.empty()) {
477                 return false;
478         }
479         bool rv = false;
480         /* iterate over all masters check their automation lists
481          * for any event between "now" and "end" which is earlier than
482          * next_event.when. If found, set next_event.when and return true.
483          * (see also Automatable::find_next_event)
484          */
485         for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
486                 boost::shared_ptr<AutomationControl> ac (mr->second.master());
487
488                 boost::shared_ptr<SlavableAutomationControl> sc
489                         = boost::dynamic_pointer_cast<SlavableAutomationControl>(ac);
490
491                 if (sc && sc->find_next_event_locked (now, end, next_event)) {
492                         rv = true;
493                 }
494
495                 Evoral::ControlList::const_iterator i;
496                 boost::shared_ptr<const Evoral::ControlList> alist (ac->list());
497                 Evoral::ControlEvent cp (now, 0.0f);
498                 if (!alist) {
499                         continue;
500                 }
501
502                 for (i = lower_bound (alist->begin(), alist->end(), &cp, Evoral::ControlList::time_comparator);
503                      i != alist->end() && (*i)->when < end; ++i) {
504                         if ((*i)->when > now) {
505                                 break;
506                         }
507                 }
508
509                 if (i != alist->end() && (*i)->when < end) {
510                         if ((*i)->when < next_event.when) {
511                                 next_event.when = (*i)->when;
512                                 rv = true;
513                         }
514                 }
515         }
516
517         return rv;
518 }
519
520 bool
521 SlavableAutomationControl::handle_master_change (boost::shared_ptr<AutomationControl>)
522 {
523         /* Derived classes can implement this for special cases (e.g. mute).
524          * This method is called with a ReaderLock (master_lock) held.
525          *
526          * return true if the changed master value resulted
527          * in a change of the control itself. */
528         return true; // emit Changed
529 }
530
531 void
532 SlavableAutomationControl::automation_run (samplepos_t start, pframes_t nframes)
533 {
534         if (!automation_playback ()) {
535                 return;
536         }
537
538         assert (_list);
539         bool valid = false;
540         double val = _list->rt_safe_eval (start, valid);
541         if (!valid) {
542                 return;
543         }
544         if (toggled ()) {
545                 const double thresh = .5 * (_desc.upper - _desc.lower);
546                 bool on = (val >= thresh) || (get_masters_value () >= thresh);
547                 set_value_unchecked (on ? _desc.upper : _desc.lower);
548         } else {
549                 set_value_unchecked (val * get_masters_value ());
550         }
551 }
552
553 bool
554 SlavableAutomationControl::boolean_automation_run_locked (samplepos_t start, pframes_t len)
555 {
556         bool rv = false;
557         if (!_desc.toggled) {
558                 return false;
559         }
560         for (Masters::iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
561                 boost::shared_ptr<AutomationControl> ac (mr->second.master());
562                 if (!ac->automation_playback ()) {
563                         continue;
564                 }
565                 if (!ac->toggled ()) {
566                         continue;
567                 }
568                 boost::shared_ptr<SlavableAutomationControl> sc = boost::dynamic_pointer_cast<MuteControl>(ac);
569                 if (sc) {
570                         rv |= sc->boolean_automation_run (start, len);
571                 }
572                 boost::shared_ptr<const Evoral::ControlList> alist (ac->list());
573                 bool valid = false;
574                 const bool yn = alist->rt_safe_eval (start, valid) >= 0.5;
575                 if (!valid) {
576                         continue;
577                 }
578                 /* ideally we'd call just master_changed() which calls update_boolean_masters_records()
579                  * but that takes the master_lock, which is already locked */
580                 if (mr->second.yn() != yn) {
581                         rv |= handle_master_change (ac);
582                         mr->second.set_yn (yn);
583                 }
584         }
585         return rv;
586 }
587
588 bool
589 SlavableAutomationControl::boolean_automation_run (samplepos_t start, pframes_t len)
590 {
591         bool change = false;
592         {
593                  Glib::Threads::RWLock::ReaderLock lm (master_lock);
594                  change = boolean_automation_run_locked (start, len);
595         }
596         if (change) {
597                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
598         }
599         return change;
600 }
601
602 bool
603 SlavableAutomationControl::slaved_to (boost::shared_ptr<AutomationControl> m) const
604 {
605         Glib::Threads::RWLock::ReaderLock lm (master_lock);
606         return _masters.find (m->id()) != _masters.end();
607 }
608
609 bool
610 SlavableAutomationControl::slaved () const
611 {
612         Glib::Threads::RWLock::ReaderLock lm (master_lock);
613         return !_masters.empty();
614 }
615
616 int
617 SlavableAutomationControl::MasterRecord::set_state (XMLNode const& n, int)
618 {
619         n.get_property (X_("yn"), _yn);
620         n.get_property (X_("val-ctrl"), _val_ctrl);
621         n.get_property (X_("val-master"), _val_master);
622         return 0;
623 }
624
625 void
626 SlavableAutomationControl::use_saved_master_ratios ()
627 {
628         if (!_masters_node) {
629                 return;
630         }
631
632         Glib::Threads::RWLock::ReaderLock lm (master_lock);
633
634         XMLNodeList nlist = _masters_node->children();
635         XMLNodeIterator niter;
636
637         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
638                 ID id_val;
639                 if (!(*niter)->get_property (X_("id"), id_val)) {
640                         continue;
641                 }
642                 Masters::iterator mi = _masters.find (id_val);
643                 if (mi == _masters.end()) {
644                         continue;
645                 }
646                 mi->second.set_state (**niter, Stateful::loading_state_version);
647         }
648
649         delete _masters_node;
650         _masters_node = 0;
651
652         return;
653 }
654
655
656 XMLNode&
657 SlavableAutomationControl::get_state ()
658 {
659         XMLNode& node (AutomationControl::get_state());
660
661         /* store VCA master ratios */
662
663         {
664                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
665                 if (!_masters.empty()) {
666                         XMLNode* masters_node = new XMLNode (X_("masters"));
667                         for (Masters::iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
668                                 XMLNode* mnode = new XMLNode (X_("master"));
669                                 mnode->set_property (X_("id"), mr->second.master()->id());
670
671                                 if (_desc.toggled) {
672                                         mnode->set_property (X_("yn"), mr->second.yn());
673                                 } else {
674                                         mnode->set_property (X_("val-ctrl"), mr->second.val_ctrl());
675                                         mnode->set_property (X_("val-master"), mr->second.val_master());
676                                 }
677                                 masters_node->add_child_nocopy (*mnode);
678                         }
679                         node.add_child_nocopy (*masters_node);
680                 }
681         }
682
683         return node;
684 }
685
686 int
687 SlavableAutomationControl::set_state (XMLNode const& node, int version)
688 {
689         XMLNodeList nlist = node.children();
690         XMLNodeIterator niter;
691
692         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
693                 if ((*niter)->name() == X_("masters")) {
694                         _masters_node = new XMLNode (**niter);
695                 }
696         }
697
698         return AutomationControl::set_state (node, version);
699 }
700
701
702 #endif /* __libardour_slavable_automation_control_h__ */