6e59964905fa8031b6a5f0164aedbcc1101def38
[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         boost::shared_ptr<ControlList> cl (new ControlList);
134         cl->push_back (_current_stripable->mute_control());
135         session->set_controls (cl, !_current_stripable->mute_control()->muted(), PBD::Controllable::UseGroup);
136 }
137
138 void
139 FaderPort::solo ()
140 {
141         if (!_current_stripable) {
142                 return;
143         }
144
145         _current_stripable->solo_control()->set_value (_current_stripable->solo_control()->soloed() ? 0.0 : 1.0, PBD::Controllable::UseGroup);
146 }
147
148 void
149 FaderPort::rec_enable ()
150 {
151         if (!_current_stripable) {
152                 return;
153         }
154
155         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_current_stripable);
156
157         if (!t) {
158                 return;
159         }
160
161         t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), Controllable::UseGroup);
162 }
163
164 void
165 FaderPort::use_master ()
166 {
167         boost::shared_ptr<Stripable> r = session->master_out();
168         if (r) {
169                 if (_current_stripable == r) {
170                         r = pre_master_stripable.lock();
171                         set_current_stripable (r);
172                         get_button(Output).set_led_state (_output_port, false);
173                         blinkers.remove (Output);
174                 } else {
175                         if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
176                                 pre_master_stripable = boost::weak_ptr<Stripable> (_current_stripable);
177                         }
178                         set_current_stripable (r);
179                         get_button(Output).set_led_state (_output_port, true);
180                         blinkers.remove (Output);
181                 }
182         }
183 }
184
185 void
186 FaderPort::use_monitor ()
187 {
188         boost::shared_ptr<Stripable> r = session->monitor_out();
189
190         if (r) {
191                 if (_current_stripable == r) {
192                         r = pre_monitor_stripable.lock();
193                         set_current_stripable (r);
194                         get_button(Output).set_led_state (_output_port, false);
195                         blinkers.remove (Output);
196                 } else {
197                         if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
198                                 pre_monitor_stripable = boost::weak_ptr<Stripable> (_current_stripable);
199                         }
200                         set_current_stripable (r);
201                         get_button(Output).set_led_state (_output_port, true);
202                         blinkers.push_back (Output);
203                 }
204         } else {
205         }
206 }
207
208 void
209 FaderPort::ardour_pan_azimuth (int delta)
210 {
211         if (!_current_stripable) {
212                 return;
213         }
214
215         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
216
217         if (!r) {
218                 return;
219         }
220
221         boost::shared_ptr<Pannable> pannable = r->pannable ();
222
223         if (!pannable) {
224                 return;
225         }
226
227         boost::shared_ptr<AutomationControl> azimuth = pannable->pan_azimuth_control;
228
229         if (!azimuth) {
230                 return;
231         }
232
233         azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
234 }
235
236
237 void
238 FaderPort::ardour_pan_width(int delta)
239 {
240         if (!_current_stripable) {
241                 return;
242         }
243
244         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
245
246         if (!r) {
247                 return;
248         }
249
250         boost::shared_ptr<Pannable> pannable = r->pannable ();
251
252         if (!pannable) {
253                 return;
254         }
255
256         boost::shared_ptr<AutomationControl> width = pannable->pan_width_control;
257
258         if (!width) {
259                 return;
260         }
261
262         width->set_value (width->interface_to_internal (width->internal_to_interface (width->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
263 }
264
265 void
266 FaderPort::mixbus_pan (int delta)
267 {
268 #ifdef MIXBUS
269         if (!_current_stripable) {
270                 return;
271         }
272         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_current_stripable);
273
274         if (!r) {
275                 return;
276         }
277
278
279         const uint32_t port_channel_post_pan = 2; // gtk2_ardour/mixbus_ports.h
280         boost::shared_ptr<ARDOUR::PluginInsert> plug = r->ch_post();
281
282         if (!plug) {
283                 return;
284         }
285
286         boost::shared_ptr<AutomationControl> azimuth = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_channel_post_pan)));
287
288         if (!azimuth) {
289                 return;
290         }
291
292         azimuth->set_value (azimuth->interface_to_internal (azimuth->internal_to_interface (azimuth->get_value()) + (delta / encoder_divider)), Controllable::NoGroup);
293 #endif
294 }
295
296 void
297 FaderPort::punch ()
298 {
299         access_action ("Transport/TogglePunch");
300 }