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