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