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