add implicit mute state to MuteMaster and use when a master of a mute control is...
[ardour.git] / libs / ardour / route_controls.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include "ardour/automation_control.h"
25 #include "ardour/parameter_descriptor.h"
26 #include "ardour/route.h"
27 #include "ardour/session.h"
28
29 #include "i18n.h"
30
31 using namespace std;
32 using namespace ARDOUR;
33 using namespace PBD;
34
35 void
36 Route::set_control (AutomationType type, double val, PBD::Controllable::GroupControlDisposition group_override)
37 {
38         boost::shared_ptr<RouteList> rl;
39
40         switch (type) {
41         case GainAutomation:
42                 /* route must mediate group control */
43                 set_gain (val, group_override);
44                 break;
45
46         case TrimAutomation:
47                 /* route must mediate group control */
48                 set_trim (val, group_override);
49                 break;
50
51         case RecEnableAutomation:
52                 /* session must mediate group control */
53                 rl.reset (new RouteList);
54                 rl->push_back (shared_from_this());
55                 _session.set_record_enabled (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
56                 break;
57
58         case SoloAutomation:
59                 /* session must mediate group control */
60                 rl.reset (new RouteList);
61                 rl->push_back (shared_from_this());
62                 if (Config->get_solo_control_is_listen_control()) {
63                         _session.set_listen (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
64                 } else {
65                         _session.set_solo (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
66                 }
67                 break;
68
69         case MuteAutomation:
70                 /* session must mediate group control */
71                 rl.reset (new RouteList);
72                 rl->push_back (shared_from_this());
73                 _session.set_mute (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
74                 return;
75                 break;
76
77         default:
78                 /* Not a route automation control */
79                 fatal << string_compose (_("programming error: %1%2\n"), X_("illegal type of route automation control passed to Route::set_control(): "), enum_2_string(type)) << endmsg;
80                 /*NOTREACHED*/
81                 return;
82         }
83 }
84
85
86 Route::RouteAutomationControl::RouteAutomationControl (const std::string& name,
87                                                        AutomationType atype,
88                                                        boost::shared_ptr<AutomationList> alist,
89                                                        boost::shared_ptr<Route> r)
90         : AutomationControl (r->session(), Evoral::Parameter (atype),
91                              ParameterDescriptor (Evoral::Parameter (atype)),
92                              alist, name)
93         , _route (r)
94 {
95 }
96
97 double
98 Route::BooleanRouteAutomationControl::get_masters_value_locked () const
99 {
100         /* masters (read/write) lock must be held */
101
102         /* if any master is enabled (val > 0.0) then we consider the master
103            value to be 1.0
104         */
105
106         for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
107                 if (mr->second.master()->get_value()) {
108                         return 1.0;
109                 }
110         }
111
112         return 0.0;
113 }
114
115
116
117 Route::GainControllable::GainControllable (Session& s, AutomationType atype, boost::shared_ptr<Route> r)
118         : GainControl (s, Evoral::Parameter(atype))
119         , _route (r)
120 {
121
122 }
123
124 Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
125         : BooleanRouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r)
126 {
127         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
128         gl->set_interpolation(Evoral::ControlList::Discrete);
129         set_list (gl);
130 }
131
132 void
133 Route::SoloControllable::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
134 {
135         boost::shared_ptr<Route> r = _route.lock ();
136
137         if (!r) {
138                 return;
139         }
140
141         bool master_soloed;
142
143         {
144                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
145                 master_soloed = (bool) get_masters_value_locked ();
146         }
147
148         /* Master is considered equivalent to an upstream solo control, not
149          * direct control over self-soloed.
150          */
151
152         r->mod_solo_by_others_upstream (master_soloed ? 1 : -1);
153
154         AutomationControl::master_changed (false, gcd);
155 }
156
157 void
158 Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
159 {
160         if (writable()) {
161                 _set_value (val, group_override);
162         }
163 }
164
165 void
166 Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
167 {
168         boost::shared_ptr<Route> r = _route.lock ();
169         if (!r) {
170                 return;
171         }
172         r->set_control (SoloAutomation, val, group_override);
173 }
174
175 void
176 Route::SoloControllable::set_value_unchecked (double val)
177 {
178         /* Used only by automation playback */
179
180         _set_value (val, Controllable::NoGroup);
181 }
182
183 double
184 Route::SoloControllable::get_value () const
185 {
186         if (slaved()) {
187                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
188                 return get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
189         }
190
191         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
192                 // Playing back automation, get the value from the list
193                 return AutomationControl::get_value();
194         }
195
196         boost::shared_ptr<Route> r = _route.lock ();
197
198         if (!r) {
199                 return 0;
200         }
201
202         if (Config->get_solo_control_is_listen_control()) {
203                 return r->listening_via_monitor() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
204         } else {
205                 return r->self_soloed() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
206         }
207 }
208
209 Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r)
210         : BooleanRouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r)
211         , _route (r)
212 {
213         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
214         gl->set_interpolation(Evoral::ControlList::Discrete);
215         set_list (gl);
216 }
217
218 void
219 Route::MuteControllable::set_superficial_value(bool muted)
220 {
221         /* Note we can not use AutomationControl::set_value here since it will emit
222            Changed(), but the value will not be correct to the observer. */
223
224         const bool to_list = _list && ((AutomationList*)_list.get ())->automation_write ();
225         const double where = _session.audible_frame ();
226
227         if (to_list) {
228                 /* Note that we really need this:
229                  *  if (as == Touch && _list->in_new_write_pass ()) {
230                  *       alist->start_write_pass (_session.audible_frame ());
231                  *  }
232                  * here in the case of the user calling from a GUI or whatever.
233                  * Without the ability to distinguish between user and
234                  * automation-initiated changes, we lose the "touch mute"
235                  * behaviour we have in AutomationController::toggled ().
236                  */
237                 _list->set_in_write_pass (true, false, where);
238         }
239
240         Control::set_double (muted, where, to_list);
241 }
242
243 void
244 Route::MuteControllable::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
245 {
246         bool master_muted;
247
248         {
249                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
250                 master_muted = (bool) get_masters_value_locked ();
251         }
252
253         boost::shared_ptr<Route> r (_route.lock());
254         if (r) {
255                 r->mute_master()->mod_muted_by_others (master_muted ? 1 : -1);
256         }
257
258         AutomationControl::master_changed (false, gcd);
259 }
260
261 void
262 Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
263 {
264         if (writable()) {
265                 _set_value (val, group_override);
266         }
267 }
268
269 void
270 Route::MuteControllable::set_value_unchecked (double val)
271 {
272         /* used only automation playback */
273         _set_value (val, Controllable::NoGroup);
274 }
275
276 void
277 Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
278 {
279         boost::shared_ptr<Route> r = _route.lock ();
280
281         if (!r) {
282                 return;
283         }
284
285         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
286                 // Set superficial/automation value to drive controller (and possibly record)
287                 const bool bval = ((val >= 0.5) ? true : false);
288                 set_superficial_value (bval);
289                 // Playing back automation, set route mute directly
290                 r->set_mute (bval, Controllable::NoGroup);
291         } else {
292                 r->set_control (MuteAutomation, val, group_override);
293         }
294 }
295
296 double
297 Route::MuteControllable::get_value () const
298 {
299         if (slaved()) {
300                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
301                 return get_masters_value_locked () ? 1.0 : 0.0;
302         }
303
304         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
305                 // Playing back automation, get the value from the list
306                 return AutomationControl::get_value();
307         }
308
309         // Not playing back automation, get the actual route mute value
310         boost::shared_ptr<Route> r = _route.lock ();
311         return (r && r->muted()) ? 1.0 : 0.0;
312 }
313
314 Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r)
315         : BooleanRouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r)
316         , _current_phase (0)
317 {
318         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation)));
319         gl->set_interpolation(Evoral::ControlList::Discrete);
320         set_list (gl);
321 }
322
323 void
324 Route::PhaseControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */)
325 {
326         boost::shared_ptr<Route> r = _route.lock ();
327         if (r->phase_invert().size()) {
328                 if (v == 0 || (v < 1 && v > 0.9) ) {
329                         r->set_phase_invert (_current_phase, false);
330                 } else {
331                         r->set_phase_invert (_current_phase, true);
332                 }
333         }
334 }
335
336 double
337 Route::PhaseControllable::get_value () const
338 {
339         boost::shared_ptr<Route> r = _route.lock ();
340         if (!r) {
341                 return 0.0;
342         }
343         return (double) r->phase_invert (_current_phase);
344 }
345
346 void
347 Route::PhaseControllable::set_channel (uint32_t c)
348 {
349         _current_phase = c;
350 }
351
352 uint32_t
353 Route::PhaseControllable::channel () const
354 {
355         return _current_phase;
356 }
357
358 Route::SoloIsolateControllable::SoloIsolateControllable (std::string name, boost::shared_ptr<Route> r)
359         : BooleanRouteAutomationControl (name, SoloIsolateAutomation, boost::shared_ptr<AutomationList>(), r)
360 {
361         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloIsolateAutomation)));
362         gl->set_interpolation(Evoral::ControlList::Discrete);
363         set_list (gl);
364 }
365
366
367 double
368 Route::SoloIsolateControllable::get_value () const
369 {
370         boost::shared_ptr<Route> r = _route.lock ();
371         if (!r) {
372                 return 0.0; /* "false" */
373         }
374
375         return r->solo_isolated() ? 1.0 : 0.0;
376 }
377
378 void
379 Route::SoloIsolateControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
380 {
381         _set_value (val, gcd);
382 }
383
384 void
385 Route::SoloIsolateControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
386 {
387         boost::shared_ptr<Route> r = _route.lock ();
388         if (!r) {
389                 return;
390         }
391
392         /* no group semantics yet */
393         r->set_solo_isolated (val >= 0.5 ? true : false);
394 }
395
396 Route::SoloSafeControllable::SoloSafeControllable (std::string name, boost::shared_ptr<Route> r)
397         : BooleanRouteAutomationControl (name, SoloSafeAutomation, boost::shared_ptr<AutomationList>(), r)
398 {
399         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloSafeAutomation)));
400         gl->set_interpolation(Evoral::ControlList::Discrete);
401         set_list (gl);
402 }
403
404 void
405 Route::SoloSafeControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
406 {
407         _set_value (val, gcd);
408 }
409
410 void
411 Route::SoloSafeControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
412 {
413         boost::shared_ptr<Route> r = _route.lock ();
414         if (!r) {
415                 return;
416         }
417
418         /* no group semantics yet */
419         r->set_solo_safe (val >= 0.5 ? true : false);
420 }
421
422 double
423 Route::SoloSafeControllable::get_value () const
424 {
425         boost::shared_ptr<Route> r = _route.lock ();
426         if (!r) {
427                 return 0.0; /* "false" */
428         }
429
430         return r->solo_safe() ? 1.0 : 0.0;
431 }