add a new constructor for RouteAutomationControllable that takes a ParameterDescriptor
[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                 return;
45                 break;
46
47         case TrimAutomation:
48                 /* route must mediate group control */
49                 set_trim (val, group_override);
50                 return;
51                 break;
52
53         case RecEnableAutomation:
54                 /* session must mediate group control */
55                 rl.reset (new RouteList);
56                 rl->push_back (shared_from_this());
57                 _session.set_record_enabled (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
58                 return;
59                 break;
60
61         case SoloAutomation:
62                 /* session must mediate group control */
63                 rl.reset (new RouteList);
64                 rl->push_back (shared_from_this());
65                 if (Config->get_solo_control_is_listen_control()) {
66                         _session.set_listen (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
67                 } else {
68                         _session.set_solo (rl, val >= 0.5 ? true : false);
69                 }
70
71                 return;
72                 break;
73
74         case MuteAutomation:
75                 /* session must mediate group control */
76                 rl.reset (new RouteList);
77                 rl->push_back (shared_from_this());
78                 _session.set_mute (rl, !muted(), Session::rt_cleanup, group_override);
79                 return;
80                 break;
81
82         default:
83                 /* Not a route automation control */
84                 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;
85                 /*NOTREACHED*/
86                 return;
87         }
88 }
89
90
91 Route::RouteAutomationControl::RouteAutomationControl (const std::string& name,
92                                                        AutomationType atype,
93                                                        boost::shared_ptr<AutomationList> alist,
94                                                        boost::shared_ptr<Route> r)
95         : AutomationControl (r->session(), Evoral::Parameter (atype),
96                              ParameterDescriptor (Evoral::Parameter (atype)),
97                              alist, name)
98         , _route (r)
99 {
100 }
101
102 Route::RouteAutomationControl::RouteAutomationControl (const std::string& name,
103                                                        AutomationType atype,
104                                                        const ParameterDescriptor& desc,
105                                                        boost::shared_ptr<AutomationList> alist,
106                                                        boost::shared_ptr<Route> r)
107         : AutomationControl (r->session(), Evoral::Parameter (atype), desc, alist, name)
108         , _route (r)
109 {
110 }
111
112 Route::GainControllable::GainControllable (Session& s, AutomationType atype, boost::shared_ptr<Route> r)
113         : GainControl (s, Evoral::Parameter(atype))
114         , _route (r)
115 {
116
117 }
118
119 Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
120         : RouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r)
121 {
122         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
123         gl->set_interpolation(Evoral::ControlList::Discrete);
124         set_list (gl);
125 }
126
127 void
128 Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
129 {
130         if (writable()) {
131                 _set_value (val, group_override);
132         }
133 }
134
135 void
136 Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
137 {
138         const bool bval = ((val >= 0.5) ? true : false);
139
140         boost::shared_ptr<RouteList> rl (new RouteList);
141
142         boost::shared_ptr<Route> r = _route.lock ();
143         if (!r) {
144                 return;
145         }
146
147         rl->push_back (r);
148
149         if (Config->get_solo_control_is_listen_control()) {
150                 _session.set_listen (rl, bval, Session::rt_cleanup, group_override);
151         } else {
152                 _session.set_solo (rl, bval, Session::rt_cleanup, group_override);
153         }
154 }
155
156 void
157 Route::SoloControllable::set_value_unchecked (double val)
158 {
159         /* Used only by automation playback */
160
161         _set_value (val, Controllable::NoGroup);
162 }
163
164 double
165 Route::SoloControllable::get_value () const
166 {
167         boost::shared_ptr<Route> r = _route.lock ();
168         if (!r) {
169                 return 0;
170         }
171
172         if (Config->get_solo_control_is_listen_control()) {
173                 return r->listening_via_monitor() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
174         } else {
175                 return r->self_soloed() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
176         }
177 }
178
179 Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r)
180         : RouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r)
181         , _route (r)
182 {
183         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
184         gl->set_interpolation(Evoral::ControlList::Discrete);
185         set_list (gl);
186 }
187
188 void
189 Route::MuteControllable::set_superficial_value(bool muted)
190 {
191         /* Note we can not use AutomationControl::set_value here since it will emit
192            Changed(), but the value will not be correct to the observer. */
193
194         const bool to_list = _list && ((AutomationList*)_list.get ())->automation_write ();
195         const double where = _session.audible_frame ();
196         if (to_list) {
197                 /* Note that we really need this:
198                  *  if (as == Touch && _list->in_new_write_pass ()) {
199                  *       alist->start_write_pass (_session.audible_frame ());
200                  *  }
201                  * here in the case of the user calling from a GUI or whatever.
202                  * Without the ability to distinguish between user and
203                  * automation-initiated changes, we lose the "touch mute"
204                  * behaviour we have in AutomationController::toggled ().
205                  */
206                 _list->set_in_write_pass (true, false, where);
207         }
208
209         Control::set_double (muted, where, to_list);
210 }
211
212 void
213 Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
214 {
215         if (writable()) {
216                 _set_value (val, group_override);
217         }
218 }
219
220 void
221 Route::MuteControllable::set_value_unchecked (double val)
222 {
223         /* used only automation playback */
224         _set_value (val, Controllable::NoGroup);
225 }
226
227 void
228 Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
229 {
230         const bool bval = ((val >= 0.5) ? true : false);
231
232         boost::shared_ptr<Route> r = _route.lock ();
233         if (!r) {
234                 return;
235         }
236
237         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
238                 // Set superficial/automation value to drive controller (and possibly record)
239                 set_superficial_value (bval);
240                 // Playing back automation, set route mute directly
241                 r->set_mute (bval, Controllable::NoGroup);
242         } else {
243                 // Set from user, queue mute event
244                 boost::shared_ptr<RouteList> rl (new RouteList);
245                 rl->push_back (r);
246                 _session.set_mute (rl, bval, Session::rt_cleanup, group_override);
247         }
248 }
249
250 double
251 Route::MuteControllable::get_value () const
252 {
253         if (_list && ((AutomationList*)_list.get())->automation_playback()) {
254                 // Playing back automation, get the value from the list
255                 return AutomationControl::get_value();
256         }
257
258         // Not playing back automation, get the actual route mute value
259         boost::shared_ptr<Route> r = _route.lock ();
260         return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
261 }
262
263 Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r)
264         : RouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r)
265 {
266         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation)));
267         gl->set_interpolation(Evoral::ControlList::Discrete);
268         set_list (gl);
269 }
270
271 void
272 Route::PhaseControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */)
273 {
274         boost::shared_ptr<Route> r = _route.lock ();
275         if (r->phase_invert().size()) {
276                 if (v == 0 || (v < 1 && v > 0.9) ) {
277                         r->set_phase_invert (_current_phase, false);
278                 } else {
279                         r->set_phase_invert (_current_phase, true);
280                 }
281         }
282 }
283
284 double
285 Route::PhaseControllable::get_value () const
286 {
287         boost::shared_ptr<Route> r = _route.lock ();
288         return (double) r->phase_invert (_current_phase);
289 }
290
291 void
292 Route::PhaseControllable::set_channel (uint32_t c)
293 {
294         _current_phase = c;
295 }
296
297 uint32_t
298 Route::PhaseControllable::channel () const
299 {
300         return _current_phase;
301 }
302