operate directly on realtime controls, not via Session
[ardour.git] / libs / surfaces / faderport / operations.cc
1 /*
2     Copyright (C) 2015 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 #include "ardour/async_midi_port.h"
21 #include "ardour/monitor_processor.h"
22 #include "ardour/pannable.h"
23 #include "ardour/plugin_insert.h"
24 #include "ardour/rc_configuration.h"
25 #include "ardour/record_enable_control.h"
26 #include "ardour/session.h"
27 #include "ardour/track.h"
28 #include "ardour/types.h"
29
30 #include "faderport.h"
31
32 using namespace ARDOUR;
33 using namespace ArdourSurface;
34 using namespace PBD;
35
36 /* this value is chosen to given smooth motion from 0..1.0 in about 270 degrees
37  * of encoder rotation.
38  */
39 static const double encoder_divider = 24.0;
40
41 void
42 FaderPort::left ()
43 {
44         access_action ("Editor/select-prev-route");
45
46         //ToDo:  bank by 8?
47         //if ( (button_state & ShiftDown) == ShiftDown )
48
49 }
50
51 void
52 FaderPort::right ()
53 {
54         access_action ("Editor/select-next-route");
55
56         //ToDo:  bank by 8?
57         //if ( (button_state & ShiftDown) == ShiftDown )
58 }
59
60
61 void
62 FaderPort::read ()
63 {
64         if (_current_stripable) {
65                 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
66                 if (gain) {
67                         gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Play );
68                 }
69         }
70 }
71
72 void
73 FaderPort::write ()
74 {
75         if (_current_stripable) {
76                 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
77                 if (gain) {
78                         gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Write );
79                 }
80         }
81 }
82
83 void
84 FaderPort::touch ()
85 {
86         if (_current_stripable) {
87                 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
88                 if (gain) {
89                         gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Touch );
90                 }
91         }
92 }
93
94 void
95 FaderPort::off ()
96 {
97         if (_current_stripable) {
98                 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
99                 if (gain) {
100                         gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Off );
101                 }
102         }
103 }
104
105
106
107
108 void
109 FaderPort::undo ()
110 {
111         ControlProtocol::Undo (); /* EMIT SIGNAL */
112 }
113
114 void
115 FaderPort::redo ()
116 {
117         ControlProtocol::Redo (); /* EMIT SIGNAL */
118 }
119
120 void
121 FaderPort::mute ()
122 {
123         if (!_current_stripable) {
124                 return;
125         }
126
127         if (_current_stripable == session->monitor_out()) {
128                 boost::shared_ptr<MonitorProcessor> mp = _current_stripable->monitor_control();
129                 mp->set_cut_all (!mp->cut_all());
130                 return;
131         }
132
133         _current_stripable->mute_control()->set_value (!_current_stripable->mute_control()->muted(), PBD::Controllable::UseGroup);
134 }
135
136 void
137 FaderPort::solo ()
138 {
139         if (!_current_stripable) {
140                 return;
141         }
142
143         _current_stripable->solo_control()->set_value (_current_stripable->solo_control()->soloed(), PBD::Controllable::UseGroup);
144 }
145
146 void
147 FaderPort::rec_enable ()
148 {
149         if (!_current_stripable) {
150                 return;
151         }
152
153         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_current_stripable);
154
155         if (!t) {
156                 return;
157         }
158
159         t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), Controllable::UseGroup);
160 }
161
162 void
163 FaderPort::use_master ()
164 {
165         boost::shared_ptr<Stripable> r = session->master_out();
166         if (r) {
167                 if (_current_stripable == r) {
168                         r = pre_master_stripable.lock();
169                         set_current_stripable (r);
170                         get_button(Output).set_led_state (_output_port, false);
171                         blinkers.remove (Output);
172                 } else {
173                         if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
174                                 pre_master_stripable = boost::weak_ptr<Stripable> (_current_stripable);
175                         }
176                         set_current_stripable (r);
177                         get_button(Output).set_led_state (_output_port, true);
178                         blinkers.remove (Output);
179                 }
180         }
181 }
182
183 void
184 FaderPort::use_monitor ()
185 {
186         boost::shared_ptr<Stripable> r = session->monitor_out();
187
188         if (r) {
189                 if (_current_stripable == r) {
190                         r = pre_monitor_stripable.lock();
191                         set_current_stripable (r);
192                         get_button(Output).set_led_state (_output_port, false);
193                         blinkers.remove (Output);
194                 } else {
195                         if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
196                                 pre_monitor_stripable = boost::weak_ptr<Stripable> (_current_stripable);
197                         }
198                         set_current_stripable (r);
199                         get_button(Output).set_led_state (_output_port, true);
200                         blinkers.push_back (Output);
201                 }
202         } else {
203         }
204 }
205
206 void
207 FaderPort::ardour_pan_azimuth (int delta)
208 {
209         if (!_current_stripable) {
210                 return;
211         }
212
213         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
214
215         if (!r) {
216                 return;
217         }
218
219         boost::shared_ptr<Pannable> pannable = r->pannable ();
220
221         if (!pannable) {
222                 return;
223         }
224
225         boost::shared_ptr<AutomationControl> azimuth = pannable->pan_azimuth_control;
226
227         if (!azimuth) {
228                 return;
229         }
230
231         azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
232 }
233
234
235 void
236 FaderPort::ardour_pan_width(int delta)
237 {
238         if (!_current_stripable) {
239                 return;
240         }
241
242         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
243
244         if (!r) {
245                 return;
246         }
247
248         boost::shared_ptr<Pannable> pannable = r->pannable ();
249
250         if (!pannable) {
251                 return;
252         }
253
254         boost::shared_ptr<AutomationControl> width = pannable->pan_width_control;
255
256         if (!width) {
257                 return;
258         }
259
260         width->set_value (width->interface_to_internal (width->internal_to_interface (width->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
261 }
262
263 void
264 FaderPort::mixbus_pan (int delta)
265 {
266 #ifdef MIXBUS
267         if (!_current_stripable) {
268                 return;
269         }
270         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
271
272         if (!r) {
273                 return;
274         }
275
276
277         const uint32_t port_channel_post_pan = 2; // gtk2_ardour/mixbus_ports.h
278         boost::shared_ptr<ARDOUR::PluginInsert> plug = r->ch_post();
279
280         if (!plug) {
281                 return;
282         }
283
284         boost::shared_ptr<AutomationControl> azimuth = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_channel_post_pan)));
285
286         if (!azimuth) {
287                 return;
288         }
289
290         azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
291 #endif
292 }
293
294 void
295 FaderPort::punch ()
296 {
297         access_action ("Transport/TogglePunch");
298 }