fix plugin silence runs (e.g. during audition)
[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 Route::GainControllable::GainControllable (Session& s, AutomationType atype, boost::shared_ptr<Route> r)
98         : GainControl (s, Evoral::Parameter(atype))
99         , _route (r)
100 {
101
102 }
103
104 Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
105         : RouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r)
106 {
107         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
108         gl->set_interpolation(Evoral::ControlList::Discrete);
109         set_list (gl);
110 }
111
112 void
113 Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
114 {
115         if (writable()) {
116                 _set_value (val, group_override);
117         }
118 }
119
120 void
121 Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
122 {
123         boost::shared_ptr<Route> r = _route.lock ();
124         if (!r) {
125                 return;
126         }
127         r->set_control (SoloAutomation, val, group_override);
128 }
129
130 void
131 Route::SoloControllable::set_value_unchecked (double val)
132 {
133         /* Used only by automation playback */
134
135         _set_value (val, Controllable::NoGroup);
136 }
137
138 double
139 Route::SoloControllable::get_value () const
140 {
141         boost::shared_ptr<Route> r = _route.lock ();
142         if (!r) {
143                 return 0;
144         }
145
146         if (Config->get_solo_control_is_listen_control()) {
147                 return r->listening_via_monitor() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
148         } else {
149                 return r->self_soloed() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
150         }
151 }
152
153 Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r)
154         : RouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r)
155         , _route (r)
156 {
157         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
158         gl->set_interpolation(Evoral::ControlList::Discrete);
159         set_list (gl);
160 }
161
162 void
163 Route::MuteControllable::set_superficial_value(bool muted)
164 {
165         /* Note we can not use AutomationControl::set_value here since it will emit
166            Changed(), but the value will not be correct to the observer. */
167
168         const bool to_list = _list && ((AutomationList*)_list.get ())->automation_write ();
169         const double where = _session.audible_frame ();
170         if (to_list) {
171                 /* Note that we really need this:
172                  *  if (as == Touch && _list->in_new_write_pass ()) {
173                  *       alist->start_write_pass (_session.audible_frame ());
174                  *  }
175                  * here in the case of the user calling from a GUI or whatever.
176                  * Without the ability to distinguish between user and
177                  * automation-initiated changes, we lose the "touch mute"
178                  * behaviour we have in AutomationController::toggled ().
179                  */
180                 _list->set_in_write_pass (true, false, where);
181         }
182
183         Control::set_double (muted, where, to_list);
184 }
185
186 void
187 Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
188 {
189         if (writable()) {
190                 _set_value (val, group_override);
191         }
192 }
193
194 void
195 Route::MuteControllable::set_value_unchecked (double val)
196 {
197         /* used only automation playback */
198         _set_value (val, Controllable::NoGroup);
199 }
200
201 void
202 Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
203 {
204         boost::shared_ptr<Route> r = _route.lock ();
205
206         if (!r) {
207                 return;
208         }
209
210         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
211                 // Set superficial/automation value to drive controller (and possibly record)
212                 const bool bval = ((val >= 0.5) ? true : false);
213                 set_superficial_value (bval);
214                 // Playing back automation, set route mute directly
215                 r->set_mute (bval, Controllable::NoGroup);
216         } else {
217                 r->set_control (MuteAutomation, val, group_override);
218         }
219 }
220
221 double
222 Route::MuteControllable::get_value () const
223 {
224         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
225                 // Playing back automation, get the value from the list
226                 return AutomationControl::get_value();
227         }
228
229         // Not playing back automation, get the actual route mute value
230         boost::shared_ptr<Route> r = _route.lock ();
231         return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
232 }
233
234 Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r)
235         : RouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r)
236         , _current_phase (0)
237 {
238         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation)));
239         gl->set_interpolation(Evoral::ControlList::Discrete);
240         set_list (gl);
241 }
242
243 void
244 Route::PhaseControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */)
245 {
246         boost::shared_ptr<Route> r = _route.lock ();
247         if (r->phase_invert().size()) {
248                 if (v == 0 || (v < 1 && v > 0.9) ) {
249                         r->set_phase_invert (_current_phase, false);
250                 } else {
251                         r->set_phase_invert (_current_phase, true);
252                 }
253         }
254 }
255
256 double
257 Route::PhaseControllable::get_value () const
258 {
259         boost::shared_ptr<Route> r = _route.lock ();
260         if (!r) {
261                 return 0.0;
262         }
263         return (double) r->phase_invert (_current_phase);
264 }
265
266 void
267 Route::PhaseControllable::set_channel (uint32_t c)
268 {
269         _current_phase = c;
270 }
271
272 uint32_t
273 Route::PhaseControllable::channel () const
274 {
275         return _current_phase;
276 }
277
278 Route::SoloIsolateControllable::SoloIsolateControllable (std::string name, boost::shared_ptr<Route> r)
279         : RouteAutomationControl (name, SoloIsolateAutomation, boost::shared_ptr<AutomationList>(), r)
280 {
281         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloIsolateAutomation)));
282         gl->set_interpolation(Evoral::ControlList::Discrete);
283         set_list (gl);
284 }
285
286
287 double
288 Route::SoloIsolateControllable::get_value () const
289 {
290         boost::shared_ptr<Route> r = _route.lock ();
291         if (!r) {
292                 return 0.0; /* "false" */
293         }
294
295         return r->solo_isolated() ? 1.0 : 0.0;
296 }
297
298 void
299 Route::SoloIsolateControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
300 {
301         _set_value (val, gcd);
302 }
303
304 void
305 Route::SoloIsolateControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
306 {
307         boost::shared_ptr<Route> r = _route.lock ();
308         if (!r) {
309                 return;
310         }
311
312         /* no group semantics yet */
313         r->set_solo_isolated (val >= 0.5 ? true : false);
314 }
315
316 Route::SoloSafeControllable::SoloSafeControllable (std::string name, boost::shared_ptr<Route> r)
317         : RouteAutomationControl (name, SoloSafeAutomation, boost::shared_ptr<AutomationList>(), r)
318 {
319         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloSafeAutomation)));
320         gl->set_interpolation(Evoral::ControlList::Discrete);
321         set_list (gl);
322 }
323
324 void
325 Route::SoloSafeControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
326 {
327         _set_value (val, gcd);
328 }
329
330 void
331 Route::SoloSafeControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
332 {
333         boost::shared_ptr<Route> r = _route.lock ();
334         if (!r) {
335                 return;
336         }
337
338         /* no group semantics yet */
339         r->set_solo_safe (val >= 0.5 ? true : false);
340 }
341
342 double
343 Route::SoloSafeControllable::get_value () const
344 {
345         boost::shared_ptr<Route> r = _route.lock ();
346         if (!r) {
347                 return 0.0; /* "false" */
348         }
349
350         return r->solo_safe() ? 1.0 : 0.0;
351 }
352