add new debug bit for backend callbacks
[ardour.git] / libs / ardour / mute_control.cc
1 /*
2  * Copyright (C) 2016-2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #include "evoral/ControlList.hpp"
21
22 #include "ardour/mute_master.h"
23 #include "ardour/session.h"
24 #include "ardour/mute_control.h"
25
26 #include "pbd/i18n.h"
27
28 using namespace ARDOUR;
29 using namespace std;
30
31
32 MuteControl::MuteControl (Session& session, std::string const & name, Muteable& m)
33         : SlavableAutomationControl (session, MuteAutomation, ParameterDescriptor (MuteAutomation),
34                                      boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (MuteAutomation))),
35                                      name)
36         , _muteable (m)
37 {
38         _list->set_interpolation (Evoral::ControlList::Discrete);
39         /* mute changes must be synchronized by the process cycle */
40         set_flags (Controllable::Flag (flags() | Controllable::RealTime));
41 }
42
43 void
44 MuteControl::post_add_master (boost::shared_ptr<AutomationControl> m)
45 {
46         if (m->get_value()) {
47
48                 /* boolean masters records are not updated until AFTER
49                  * ::post_add_master() is called, so we can use them to check
50                  * on whether any master was already enabled before the new
51                  * one was added.
52                  */
53
54                 if (!muted_by_self() && !get_boolean_masters()) {
55                         _muteable.mute_master()->set_muted_by_masters (true);
56                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
57                 }
58         }
59 }
60
61 void
62 MuteControl::pre_remove_master (boost::shared_ptr<AutomationControl> m)
63 {
64         if (!m) {
65                 /* null control ptr means we're removing all masters */
66                 _muteable.mute_master()->set_muted_by_masters (false);
67                 /* Changed will be emitted in SlavableAutomationControl::clear_masters() */
68                 return;
69         }
70
71         if (m->get_value() && get_boolean_masters() == 1) {
72                 _muteable.mute_master()->set_muted_by_masters (false);
73                 if (!muted_by_self()) {
74                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
75                 }
76         }
77 }
78
79 void
80 MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
81 {
82         if (muted_by_self() != bool (val)) {
83                 _muteable.mute_master()->set_muted_by_self (val);
84
85                 /* allow the Muteable to respond to the mute change
86                    before anybody else knows about it.
87                 */
88                 _muteable.act_on_mute ();
89         }
90
91         SlavableAutomationControl::actually_set_value (val, gcd);
92 }
93
94 bool
95 MuteControl::handle_master_change (boost::shared_ptr<AutomationControl> m)
96 {
97         bool send_signal = false;
98         boost::shared_ptr<MuteControl> mc = boost::dynamic_pointer_cast<MuteControl> (m);
99         if (!mc) {
100                 return false;
101         }
102
103         if (m->get_value()) {
104                 /* this master is now enabled */
105                 if (get_boolean_masters() == 0) {
106                         _muteable.mute_master()->set_muted_by_masters (true);
107                         if (!muted_by_self()) {
108                                 send_signal = true;
109                         }
110                 }
111         } else {
112                 /* this master is disabled and there was only 1 enabled before */
113                 if (get_boolean_masters() == 1) {
114                         _muteable.mute_master()->set_muted_by_masters (false);
115                         if (!muted_by_self()) {
116                                 send_signal = true;
117                         }
118                 }
119         }
120         return send_signal;
121 }
122
123 double
124 MuteControl::get_value () const
125 {
126         if (slaved ()) {
127                 return muted_by_self() || muted_by_masters ();
128         }
129
130         if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) {
131                 // Playing back automation, get the value from the list
132                 return AutomationControl::get_value();
133         }
134
135         return muted();
136 }
137
138 void
139 MuteControl::set_mute_points (MuteMaster::MutePoint mp)
140 {
141         _muteable.mute_master()->set_mute_points (mp);
142         _muteable.mute_points_changed (); /* EMIT SIGNAL */
143
144         if (_muteable.mute_master()->muted_by_self()) {
145                 Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
146         }
147 }
148
149 MuteMaster::MutePoint
150 MuteControl::mute_points () const
151 {
152         return _muteable.mute_master()->mute_points ();
153 }
154
155 bool
156 MuteControl::muted () const
157 {
158         /* have to get (self-muted) value from somewhere. could be our own
159            Control, or the Muteable that we sort-of proxy for. Since this
160            method is called by ::get_value(), use the latter to avoid recursion.
161         */
162         return _muteable.mute_master()->muted_by_self() || muted_by_masters ();
163 }
164
165 bool
166 MuteControl::muted_by_self () const
167 {
168         return _muteable.mute_master()->muted_by_self();
169 }
170
171 bool
172 MuteControl::muted_by_masters () const
173 {
174         return _muteable.mute_master()->muted_by_masters ();
175 }
176
177 bool
178 MuteControl::muted_by_others_soloing () const
179 {
180         return _muteable.muted_by_others_soloing ();
181 }
182
183 void
184 MuteControl::automation_run (samplepos_t start, pframes_t len)
185 {
186         boolean_automation_run (start, len);
187
188         bool valid = false;
189         bool mute  = false;
190
191         if (list() && automation_playback()) {
192                 mute = list()->rt_safe_eval (start, valid) >= 0.5;
193         }
194
195         if (!valid) {
196                 return;
197         }
198
199         if (muted_by_masters ()) {
200                 /* already muted, no need to check further,
201                  * except we need to up update implicit/explict mute
202                  */
203                 if (muted_by_self () != mute) {
204                         set_value_unchecked (mute ? 1. : 0.);
205                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
206                 }
207                 return;
208         }
209
210         if (mute && !muted()) {
211                 set_value_unchecked (1.0);  // mute
212                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
213         } else if (!mute && muted()) {
214                 set_value_unchecked (0.0);  // unmute
215                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
216         }
217 }