039084a99ee77bcf7dae039d66deee4cd869db33
[ardour.git] / libs / surfaces / launch_control_xl / controllers.cc
1 /*
2   Copyright (C) 2016 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 #include <algorithm>
20
21 #include "ardour/debug.h"
22 #include "ardour/mute_control.h"
23 #include "ardour/session.h"
24 #include "ardour/solo_control.h"
25 #include "ardour/solo_isolate_control.h"
26
27 #include "launch_control_xl.h"
28
29 using namespace ArdourSurface;
30 using namespace ARDOUR;
31 using namespace PBD;
32 using std::cerr;
33
34 void
35 LaunchControlXL::build_maps ()
36 {
37         cc_knob_map.clear();
38         id_knob_map.clear();
39         cc_fader_map.clear();
40         id_fader_map.clear();
41         nn_note_button_map.clear();
42         id_note_button_map.clear();
43         cc_controller_button_map.clear();
44         id_controller_button_map.clear();
45
46         /* Knobs */
47         boost::shared_ptr<Knob> knob;
48
49         #define MAKE_KNOB(i,cc,index,c_on,c_off,a) \
50                 knob.reset (new Knob ((i), (cc), (index), (c_on), (c_off), (a), (*this))); \
51                 cc_knob_map.insert (std::make_pair (knob->controller_number(), knob)); \
52                 id_knob_map.insert (std::make_pair (knob->id(), knob));
53         #define MAKE_DM_KNOB(i,cc,index,c_on,c_off,action,check) \
54                 knob.reset (new Knob ((i), (cc), (index), (c_on), (c_off), (action), (check), (*this))); \
55                 cc_knob_map.insert (std::make_pair (knob->controller_number(), knob)); \
56                 id_knob_map.insert (std::make_pair (knob->id(), knob));
57
58         if (!device_mode()) {   /* mixer mode */
59                 MAKE_KNOB (SendA1, 13, 0, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 0)));
60                 MAKE_KNOB (SendA2, 14, 1, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 1)));
61                 MAKE_KNOB (SendA3, 15, 2, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 2)));
62                 MAKE_KNOB (SendA4, 16, 3, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 3)));
63                 MAKE_KNOB (SendA5, 17, 4, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 4)));
64                 MAKE_KNOB (SendA6, 18, 5, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 5)));
65                 MAKE_KNOB (SendA7, 19, 6, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 6)));
66                 MAKE_KNOB (SendA8, 20, 7, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendA, this, 7)));
67
68                 MAKE_KNOB (SendB1, 29, 8, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 0)));
69                 MAKE_KNOB (SendB2, 30, 9, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 1)));
70                 MAKE_KNOB (SendB3, 31, 10, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 2)));
71                 MAKE_KNOB (SendB4, 32, 11, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 3)));
72                 MAKE_KNOB (SendB5, 33, 12, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 4)));
73                 MAKE_KNOB (SendB6, 34, 13, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 5)));
74                 MAKE_KNOB (SendB7, 35, 14, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 6)));
75                 MAKE_KNOB (SendB8, 36, 15, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_sendB, this, 7)));
76
77                 MAKE_KNOB (Pan1, 49, 16, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 0)));
78                 MAKE_KNOB (Pan2, 50, 17, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 1)));
79                 MAKE_KNOB (Pan3, 51, 18, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 2)));
80                 MAKE_KNOB (Pan4, 52, 19, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 3)));
81                 MAKE_KNOB (Pan5, 53, 20, RedFull, RedLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 4)));
82                 MAKE_KNOB (Pan6, 54, 21, YellowFull, YellowLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 5)));
83                 MAKE_KNOB (Pan7, 55, 22, GreenFull, GreenLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 6)));
84                 MAKE_KNOB (Pan8, 56, 23, AmberFull, AmberLow, boost::function<void ()> (boost::bind (&LaunchControlXL::knob_pan, this, 7)));
85
86         } else {        /* device mode */
87
88 #ifdef MIXBUS // from here Mixbus Standard + 32C
89                 MAKE_DM_KNOB (SendB5, 33, 12, RedFull, RedLow, boost::function<void ()>
90                                 (boost::bind (&LaunchControlXL::dm_trim, this, SendB5)),
91                                 boost::bind(&LaunchControlXL::dm_check_trim, this));
92                 MAKE_DM_KNOB (SendB6, 34, 13, GreenFull, GreenLow, boost::function<void ()>
93                                 (boost::bind (&LaunchControlXL::dm_mb_comp, this, SendB6, CompMakeup)),
94                                 boost::bind(&LaunchControlXL::dm_mb_comp_enabled,this));
95                 MAKE_DM_KNOB (SendB7, 35, 14, GreenFull, GreenLow, boost::function<void ()>
96                                 (boost::bind (&LaunchControlXL::dm_mb_comp, this, SendB7, CompSpeed)),
97                                 boost::bind(&LaunchControlXL::dm_mb_comp_enabled, this));
98                 MAKE_DM_KNOB (SendB8, 36, 15, GreenFull, GreenLow, boost::function<void ()>
99                                 (boost::bind (&LaunchControlXL::dm_mb_comp, this, SendB8, CompMode)),
100                                 boost::bind(&LaunchControlXL::dm_mb_comp_enabled, this));
101
102                 /* Pan Knobs -> Sends */
103                 for (uint8_t i = 0; i < 8; ++i) {
104                         MAKE_DM_KNOB (static_cast<KnobID>(i + 16), (i + 49), (i + 16), GreenLow, YellowLow, boost::function<void()>
105                                 (boost::bind (&LaunchControlXL::dm_mb_sends, this, static_cast<KnobID>(i + 16))),
106                                 boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_check_send_knob, this, static_cast<KnobID>(i + 16))));
107                 }
108
109 #ifdef MIXBUS32C // from here 32C only
110
111                 if (first_selected_stripable() && (first_selected_stripable()->is_master() || first_selected_stripable()->mixbus())) {
112                         MAKE_DM_KNOB (SendA1, 13, 0, AmberFull, AmberLow, boost::function<void ()>
113                                         (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA1, true, 0)),
114                                         boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 0)));
115                         MAKE_DM_KNOB (SendA2, 14, 1, AmberFull, AmberLow, boost::function<void ()>
116                                         (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA2, true, 1)),
117                                         boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 1)));
118                         MAKE_DM_KNOB (SendA3, 15, 2, AmberFull, AmberLow, boost::function<void ()>
119                                         (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA3, true, 2)),
120                                         boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 2)));
121                         MAKE_DM_KNOB (SendA6, 18, 5, RedLow, RedLow, boost::function<void ()>
122                                         (boost::bind (&LaunchControlXL::dm_pan_width, this, SendA6)),
123                                         boost::bind(&LaunchControlXL::dm_check_pan_width, this));
124                         MAKE_DM_KNOB (SendA7, 19, 6, AmberLow, AmberLow, boost::function<void ()>
125                                         (boost::bind (&LaunchControlXL::dm_mb_tapedrive, this, SendA7)),
126                                         boost::bind(&LaunchControlXL::dm_mb_has_tapedrive, this));
127                 } else {
128                         MAKE_DM_KNOB (SendA1, 13, 0, AmberFull, AmberLow, boost::function<void ()>
129                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA1, false, 0)),
130                                       boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
131                         MAKE_DM_KNOB (SendA2, 14, 1, AmberFull, AmberLow, boost::function<void ()>
132                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA2, true, 0)),
133                                       boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 0)));
134                         MAKE_DM_KNOB (SendA3, 15, 2, YellowLow, AmberLow, boost::function<void ()>
135                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA3, false, 1)),
136                                       boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
137                         MAKE_DM_KNOB (SendA4, 16, 3, YellowLow, AmberLow, boost::function<void ()>
138                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA4, true, 1)),
139                                       boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 1)));
140                         MAKE_DM_KNOB (SendA5, 17, 4, AmberFull, AmberLow, boost::function<void ()>
141                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA5, false, 2)),
142                                       boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
143                         MAKE_DM_KNOB (SendA6, 18, 5, AmberFull, AmberLow, boost::function<void ()>
144                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA6, true, 2)),
145                                       boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 2)));
146                         MAKE_DM_KNOB (SendA7, 19, 6, YellowLow, AmberLow, boost::function<void ()>
147                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA7, false, 3)),
148                                       boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
149                         MAKE_DM_KNOB (SendA8, 20, 7, YellowLow, AmberLow, boost::function<void ()>
150                                       (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA8, true, 3)),
151                                       boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 3)));
152                 }
153                         MAKE_DM_KNOB (SendB1, 29, 8, YellowFull, AmberLow, boost::function<void ()>
154                                       (boost::bind (&LaunchControlXL::dm_mb_flt_frq, this, SendB1, true)),
155                                       boost::bind(&LaunchControlXL::dm_mb_flt_enabled, this));
156                         MAKE_DM_KNOB (SendB2, 30, 9, YellowFull, AmberLow, boost::function<void ()>
157                                       (boost::bind (&LaunchControlXL::dm_mb_flt_frq, this, SendB2, false)),
158                                       boost::bind(&LaunchControlXL::dm_mb_flt_enabled, this));
159                         MAKE_DM_KNOB (SendB4, 32, 11, RedLow, AmberLow, boost::function<void ()>
160                                       (boost::bind (&LaunchControlXL::dm_pan_azi, this, SendB4)),
161                                       boost::bind(&LaunchControlXL::dm_check_pan_azi, this));
162
163 #else   // from here Mixbus Standard only
164                 MAKE_DM_KNOB (SendA1, 13, 0, AmberFull, AmberLow, boost::function<void ()>
165                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA1, true, 0)),
166                                 boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 0)));
167                 MAKE_DM_KNOB (SendA2, 14, 1, AmberFull, AmberLow, boost::function<void ()>
168                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA2, true, 1)),
169                                 boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 1)));
170                 MAKE_DM_KNOB (SendA3, 15, 2, AmberFull, AmberLow, boost::function<void ()>
171                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendA3, true, 2)),
172                                 boost::function<uint8_t ()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 2)));
173                 MAKE_DM_KNOB (SendA5, 17, 4, RedLow, AmberLow, boost::function<void ()>
174                                 (boost::bind (&LaunchControlXL::dm_pan_azi, this, SendA5)),
175                                 boost::bind(&LaunchControlXL::dm_check_pan_azi, this));
176                 MAKE_DM_KNOB (SendA6, 18, 5, RedLow, RedLow, boost::function<void ()>
177                                 (boost::bind (&LaunchControlXL::dm_pan_width, this, SendA6)),
178                                 boost::bind(&LaunchControlXL::dm_check_pan_width, this));
179                 MAKE_DM_KNOB (SendA7, 19, 6, AmberLow, AmberLow, boost::function<void ()>
180                                 (boost::bind (&LaunchControlXL::dm_mb_tapedrive, this, SendA7)),
181                                 boost::bind(&LaunchControlXL::dm_mb_has_tapedrive, this));
182                 MAKE_DM_KNOB (SendB1, 29, 8, YellowFull, AmberLow, boost::function<void ()>
183                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendB1, false, 0)),
184                                 boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
185                 MAKE_DM_KNOB (SendB2, 30, 9, YellowFull, AmberLow, boost::function<void ()>
186                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendB2, false, 1)),
187                                 boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
188                 MAKE_DM_KNOB (SendB3, 31, 10, YellowFull, AmberLow, boost::function<void ()>
189                                 (boost::bind (&LaunchControlXL::dm_mb_eq, this, SendB3, false, 2)),
190                                 boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
191                 MAKE_DM_KNOB (SendB4, 32, 11, YellowFull, AmberLow, boost::function<void ()>
192                                 (boost::bind (&LaunchControlXL::dm_mb_flt_frq, this, SendB4, true)),
193                                 boost::bind(&LaunchControlXL::dm_mb_eq_freq_enabled, this));
194 #endif
195 #else // from here Ardour
196 #endif
197         }
198
199
200         /* Faders */
201         boost::shared_ptr<Fader> fader;
202
203         #define MAKE_FADER(i,cc,a) \
204                 fader.reset (new Fader ((i), (cc), (a))); \
205                 cc_fader_map.insert (std::make_pair (fader->controller_number(), fader)); \
206                 id_fader_map.insert (std::make_pair (fader->id(), fader))
207
208         if (!device_mode()) {   /* mix mode */
209                 for (uint8_t i = 0; i < 8; ++i) {
210                         MAKE_FADER(static_cast<FaderID>(i), i+77, boost::function<void()>
211                                 (boost::bind (&LaunchControlXL::fader, this, i)));
212                 }
213
214         } else {        /* device mode */
215                 MAKE_FADER(Fader1, 77,  boost::function<void()>
216                         (boost::bind (&LaunchControlXL::dm_fader, this, Fader1)));
217 #ifdef MIXBUS
218                 MAKE_FADER(Fader2, 78,  boost::function<void()>
219                         (boost::bind (&LaunchControlXL::dm_mb_comp_thresh, this, Fader2)));
220 #endif
221         }
222
223         /* Buttons */
224         boost::shared_ptr<ControllerButton> controller_button;
225         boost::shared_ptr<NoteButton> note_button;
226
227
228         #define MAKE_TRACK_BUTTON_PRESS(i,nn,index,c_on,c_off,p,check) \
229                 note_button.reset (new TrackButton ((i), (nn), (index), (c_on), (c_off), (p), \
230                 boost::bind(&LaunchControlXL::relax, this), boost::bind(&LaunchControlXL::relax, this), (check), (*this))); \
231                 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
232                 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
233         #define MAKE_CTRL_BUTTON_PRESS(i,nn,index,c_on,c_off,p,check) \
234                 note_button.reset (new TrackButton ((i), (nn), (index), (c_on), (c_off),  (p), \
235                 boost::bind(&LaunchControlXL::relax, this), boost::bind(&LaunchControlXL::relax, this), (check), (*this))); \
236                 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
237                 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
238         #define MAKE_SELECT_BUTTON_PRESS(i,cc,index,p) \
239                 controller_button.reset (new SelectButton ((i), (cc), (index), (p), \
240                 boost::bind(&LaunchControlXL::relax, this), boost::bind(&LaunchControlXL::relax, this), (*this))); \
241                 cc_controller_button_map.insert (std::make_pair (controller_button->controller_number(), controller_button)); \
242                 id_controller_button_map.insert (std::make_pair (controller_button->id(), controller_button))
243         #define MAKE_TRACK_STATE_BUTTON_PRESS(i,nn,index,p) \
244                 note_button.reset (new TrackStateButton ((i), (nn), (index), (p), \
245                 boost::bind(&LaunchControlXL::relax, this), boost::bind(&LaunchControlXL::relax, this), (*this))); \
246                 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
247                 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
248                 #define MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(i,nn,index, p,r,l) \
249                         note_button.reset (new TrackStateButton ((i), (nn), (index), (p), (r), (l), (*this))); \
250                         nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
251                         id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
252
253         /* Track Focus Buttons */
254         if (!device_mode()) {   /* mixer mode */
255                 for (uint8_t i = 0; i < 4; ++i) {
256                         MAKE_TRACK_BUTTON_PRESS(static_cast<ButtonID>(i), i+41, i+24, YellowFull, YellowLow,
257                                 boost::function<void()> (boost::bind (&LaunchControlXL::button_track_focus, this, i)),
258                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_check_dummy, this, dev_nonexistant)));
259                 }
260
261                 for (uint8_t i = 0; i < 4; ++i) {
262                         MAKE_TRACK_BUTTON_PRESS(static_cast<ButtonID>(i+4), i+57, i+28, YellowFull, YellowLow,
263                                 boost::function<void()> (boost::bind (&LaunchControlXL::button_track_focus, this, i+4)),
264                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_check_dummy, this, dev_nonexistant)));
265                 }
266
267         } else {                /* device mode */
268 #ifdef MIXBUS
269                 for (uint8_t i = 0; i < 4; ++i) {
270                         MAKE_TRACK_BUTTON_PRESS(static_cast<ButtonID>(i), i+41, i+24, GreenFull, YellowLow,
271                                 boost::function<void()> (boost::bind (&LaunchControlXL::dm_mb_send_switch, this, static_cast<ButtonID>(i))),
272                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_mb_check_send_button, this, i)));
273
274                 }
275
276                 for (uint8_t i = 0; i < 4; ++i) {
277                         MAKE_TRACK_BUTTON_PRESS(static_cast<ButtonID>(i+4), i+57, i+28, GreenFull, YellowLow,
278                                 boost::function<void()> (boost::bind (&LaunchControlXL::dm_mb_send_switch, this, static_cast<ButtonID>(i+4))),
279                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_mb_check_send_button, this, i+4)));
280                 }
281 #endif
282         }
283         /* Track Control Buttons */
284         if (!device_mode()) {   /* mixer mode */
285                 /* Control Buttons in mix mode change their color dynamically so we won't set them here */
286                 for (uint8_t i = 0; i < 4; ++i) {
287                         MAKE_CTRL_BUTTON_PRESS(static_cast<ButtonID>(i+8), i+73, i+32, Off, Off,
288                                 boost::function<void()> (boost::bind (&LaunchControlXL::button_press_track_control, this, i)),
289                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_check_dummy, this, dev_nonexistant)));
290                 }
291
292                 for (uint8_t i = 0; i < 4; ++i) {
293                         MAKE_CTRL_BUTTON_PRESS(static_cast<ButtonID>(i+12), i+89, i+36, Off, Off,
294                                 boost::function<void()> (boost::bind (&LaunchControlXL::button_press_track_control, this, i+4)),
295                                 boost::function<uint8_t()> (boost::bind (&LaunchControlXL::dm_check_dummy, this, dev_nonexistant)));
296                 }
297
298         } else { /*device mode */
299 #ifdef MIXBUS // from here Mixbus Standard + 32C
300                 MAKE_CTRL_BUTTON_PRESS(Control1, 73, 32, YellowFull, YellowLow, (boost::bind (&LaunchControlXL::dm_mute_switch, this)),
301                         boost::bind (&LaunchControlXL::dm_mute_enabled, this));
302                 MAKE_CTRL_BUTTON_PRESS(Control2, 74, 33, GreenFull, GreenLow, (boost::bind (&LaunchControlXL::dm_solo_switch, this)),
303                         boost::bind (&LaunchControlXL::dm_solo_enabled, this));
304                 MAKE_CTRL_BUTTON_PRESS(Control3, 75, 34, AmberFull, AmberLow, (boost::bind (&LaunchControlXL::dm_mb_eq_switch, this)),
305                         boost::function<uint8_t()> (boost::bind(&LaunchControlXL::dm_mb_eq_gain_enabled, this, 0)));
306
307
308 #ifdef MIXBUS32C // from here 32C only
309                 MAKE_CTRL_BUTTON_PRESS(Control4, 76, 35, AmberFull, AmberLow,
310                         boost::function<void()> (boost::bind (&LaunchControlXL::dm_mb_eq_shape_switch, this, 0)),
311                         boost::function<uint8_t()> (boost::bind(&LaunchControlXL::dm_mb_eq_shape_enabled, this, 0 )));
312                 MAKE_CTRL_BUTTON_PRESS(Control5, 89, 36, AmberFull, AmberLow,
313                         boost::function<void()> (boost::bind (&LaunchControlXL::dm_mb_eq_shape_switch, this, 3)),
314                         boost::function<uint8_t()> (boost::bind(&LaunchControlXL::dm_mb_eq_shape_enabled, this, 3 )));
315                 MAKE_CTRL_BUTTON_PRESS(Control6, 90, 37, YellowFull, YellowLow, (boost::bind (&LaunchControlXL::dm_mb_flt_switch, this)),
316                         boost::bind(&LaunchControlXL::dm_mb_flt_enabled, this));
317                 MAKE_CTRL_BUTTON_PRESS(Control7, 91, 38, GreenFull, GreenLow, (boost::bind (&LaunchControlXL::dm_mb_master_assign_switch, this)),
318                         boost::bind(&LaunchControlXL::dm_mb_master_assign_enabled, this));
319                 MAKE_CTRL_BUTTON_PRESS(Control8, 92, 39, GreenFull, GreenLow, (boost::bind (&LaunchControlXL::dm_mb_comp_switch, this)),
320                         boost::bind(&LaunchControlXL::dm_mb_comp_enabled, this));
321
322 #else // from here Mixbus Standard only
323                 MAKE_CTRL_BUTTON_PRESS(Control5, 89, 36, GreenFull, GreenLow, (boost::bind (&LaunchControlXL::dm_mb_master_assign_switch, this)),
324                         boost::bind(&LaunchControlXL::dm_mb_master_assign_enabled, this));
325                 MAKE_CTRL_BUTTON_PRESS(Control7, 91, 38, GreenFull, GreenLow, (boost::bind (&LaunchControlXL::dm_mb_comp_switch, this)),
326                         boost::bind(&LaunchControlXL::dm_mb_comp_enabled, this));
327                 MAKE_CTRL_BUTTON_PRESS(Control8, 92, 39, RedFull, RedLow, (boost::bind (&LaunchControlXL::dm_recenable_switch, this)),
328                         boost::bind(&LaunchControlXL::dm_recenable_enabled, this));
329
330 #endif
331 #else // Ardour
332 #endif
333         }
334
335         /* Select and Mode Buttons on the right side */
336
337         /* Sends Select buttons are independent of mode */
338         MAKE_SELECT_BUTTON_PRESS(SelectUp, 104, 44, boost::function<void()> (boost::bind (&LaunchControlXL::send_bank_switch, this, false)));
339         MAKE_SELECT_BUTTON_PRESS(SelectDown, 105, 45,  boost::function<void()> (boost::bind (&LaunchControlXL::send_bank_switch, this, true)));
340
341         /* Device Button needs to be always there */
342         MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(Device, 105, 40,
343                 boost::bind (&LaunchControlXL::relax, this) ,
344                 boost::bind (&LaunchControlXL::button_device, this),
345                 boost::bind (&LaunchControlXL::button_device_long_press, this));
346
347
348         if (!device_mode()) {   /* mixer mode */
349                 MAKE_SELECT_BUTTON_PRESS(SelectLeft, 106, 46, boost::bind (&LaunchControlXL::button_select_left, this));
350                 MAKE_SELECT_BUTTON_PRESS(SelectRight, 107, 47, boost::bind (&LaunchControlXL::button_select_right, this));
351
352                 //MAKE_TRACK_STATE_BUTTON_PRESS(Mute, 106, 41, boost::bind (&LaunchControlXL::button_mute, this));
353
354                 MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(Mute, 106, 41,
355                         boost::bind (&LaunchControlXL::relax, this) ,
356                         boost::bind (&LaunchControlXL::button_mute, this),
357                 boost::bind (&LaunchControlXL::button_mute_long_press, this));
358
359                 MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(Solo, 107, 42,
360                         boost::bind (&LaunchControlXL::relax, this) ,
361                         boost::bind (&LaunchControlXL::button_solo, this),
362                 boost::bind (&LaunchControlXL::button_solo_long_press, this));
363
364                 //MAKE_TRACK_STATE_BUTTON_PRESS(Solo, 107, 42, boost::bind (&LaunchControlXL::button_solo, this));
365                 MAKE_TRACK_STATE_BUTTON_PRESS(Record, 108, 43, boost::bind (&LaunchControlXL::button_record, this));
366
367         } else {        /* device mode */
368                 MAKE_SELECT_BUTTON_PRESS(SelectLeft, 106, 46,  boost::bind (&LaunchControlXL::dm_select_prev_strip, this));
369                 MAKE_SELECT_BUTTON_PRESS(SelectRight, 107, 47,  boost::bind (&LaunchControlXL::dm_select_next_strip, this));
370         }
371 }
372
373 std::string
374 LaunchControlXL::button_name_by_id (ButtonID id)
375 {
376         switch (id) {
377                 case Device:
378                         return "Device";
379                 case Mute:
380                         return "Mute";
381                 case Solo:
382                         return "Solo";
383                 case Record:
384                         return "Record";
385                 case SelectUp:
386                         return "Select Up";
387                 case SelectDown:
388                         return "Select Down";
389                 case SelectRight:
390                         return "Select Right";
391                 case SelectLeft:
392                         return "Select Left";
393                 case Focus1:
394                         return "Focus 1";
395                 case Focus2:
396                         return "Focus 2";
397                 case Focus3:
398                         return "Focus 3";
399                 case Focus4:
400                         return "Focus 4";
401                 case Focus5:
402                         return "Focus 5";
403                 case Focus6:
404                         return "Focus 6";
405                 case Focus7:
406                         return "Focus 7";
407                 case Focus8:
408                         return "Focus 8";
409                 case Control1:
410                         return "Control 1";
411                 case Control2:
412                         return "Control 2";
413                 case Control3:
414                         return "Control 3";
415                 case Control4:
416                         return "Control 4";
417                 case Control5:
418                         return "Control 5";
419                 case Control6:
420                         return "Control 6";
421                 case Control7:
422                         return "Control 7";
423                 case Control8:
424                         return "Control 8";
425         default:
426                 break;
427         }
428
429         return "???";
430 }
431
432 std::string
433 LaunchControlXL::knob_name_by_id (KnobID id)
434 {
435         switch (id) {
436                 case SendA1:
437                         return "SendA 1";
438                 case SendA2:
439                         return "SendA 2";
440                 case SendA3:
441                         return "SendA 3";
442                 case SendA4:
443                         return "SendA 4";
444                 case SendA5:
445                         return "SendA 5";
446                 case SendA6:
447                         return "SendA 6";
448                 case SendA7:
449                         return "SendA 7";
450                 case SendA8:
451                         return "SendA 8";
452                 case SendB1:
453                         return "SendB 1";
454                 case SendB2:
455                         return "SendB 2";
456                 case SendB3:
457                         return "SendB 3";
458                 case SendB4:
459                         return "SendB 4";
460                 case SendB5:
461                         return "SendB 5";
462                 case SendB6:
463                         return "SendB 6";
464                 case SendB7:
465                         return "SendB 7";
466                 case SendB8:
467                         return "SendB 8";
468                 case Pan1:
469                         return "Pan 1";
470                 case Pan2:
471                         return "Pan 2";
472                 case Pan3:
473                         return "Pan 3";
474                 case Pan4:
475                         return "Pan 4";
476                 case Pan5:
477                         return "Pan 5";
478                 case Pan6:
479                         return "Pan 6";
480                 case Pan7:
481                         return "Pan 7";
482                 case Pan8:
483                         return "Pan 8";
484         default:
485                 break;
486         }
487
488         return "???";
489 }
490
491 std::string
492 LaunchControlXL::fader_name_by_id (FaderID id)
493 {
494         switch (id) {
495                 case Fader1:
496                         return "Fader 1";
497                 case Fader2:
498                         return "Fader 2";
499                 case Fader3:
500                         return "Fader 3";
501                 case Fader4:
502                         return "Fader 4";
503                 case Fader5:
504                         return "Fader 5";
505                 case Fader6:
506                         return "Fader 6";
507                 case Fader7:
508                         return "Fader 7";
509                 case Fader8:
510                         return "Fader 8";
511         default:
512                 break;
513         }
514
515         return "???";
516 }
517
518 boost::shared_ptr<LaunchControlXL::TrackButton>
519 LaunchControlXL::track_button_by_range(uint8_t n, uint8_t first, uint8_t middle)
520 {
521         NNNoteButtonMap::iterator b;
522         if ( n < 4)     {
523                 b = nn_note_button_map.find (first + n);
524         } else {
525                 b = nn_note_button_map.find (middle + n - 4);
526         }
527
528         if (b != nn_note_button_map.end()) {
529                 return boost::dynamic_pointer_cast<TrackButton> (b->second);
530         }
531
532         return boost::shared_ptr<TrackButton>();
533 }
534
535 void
536 LaunchControlXL::update_track_focus_led(uint8_t n)
537 {
538         boost::shared_ptr<TrackButton> b = focus_button_by_column(n);
539
540         if (!b) {
541                 return;
542         }
543
544         if (stripable[n]) {
545                 if ( stripable[n]->is_selected() ) {
546                         b->set_color(YellowFull);
547                 } else {
548                         b->set_color(AmberLow);
549                 }
550         } else {
551                 b->set_color(Off);
552         }
553
554         write (b->state_msg());
555 }
556
557 boost::shared_ptr<AutomationControl>
558 LaunchControlXL::get_ac_by_state(uint8_t n) {
559                 boost::shared_ptr<AutomationControl> ac;
560
561                 switch(track_mode()) {
562                         case TrackMute:
563                                 ac = stripable[n]->mute_control();
564                                 break;
565
566                         case TrackSolo:
567                                 ac = stripable[n]->solo_control();
568                                 break;
569
570                         case TrackRecord:
571                                 ac = stripable[n]->rec_enable_control();
572                                 break;
573
574                         default:
575                         break;
576                 }
577                 return ac;
578 }
579
580 boost::shared_ptr<LaunchControlXL::Knob>
581 LaunchControlXL::knob_by_id(KnobID id)
582 {
583         IDKnobMap::iterator k = id_knob_map.find(id);
584         return boost::dynamic_pointer_cast<Knob> (k->second);
585
586 }
587
588 boost::shared_ptr<LaunchControlXL::Knob>*
589 LaunchControlXL::knobs_by_column(uint8_t col, boost::shared_ptr<Knob>* knob_col)
590 {
591         for (uint8_t n = 0; n < 3; ++n) {
592                 if (id_knob_map.find(static_cast<KnobID>(col+n*8)) != id_knob_map.end()) {
593                         knob_col[n] = id_knob_map.find(static_cast<KnobID>(col+n*8))->second;
594                 }
595         }
596
597         return knob_col;
598 }
599
600 void
601 LaunchControlXL::update_knob_led_by_id (uint8_t id, LEDColor color)
602 {
603
604         boost::shared_ptr<Knob> knob;
605         IDKnobMap::iterator k = id_knob_map.find(static_cast<KnobID>(id));
606
607         if (k != id_knob_map.end()) {
608                 knob = k->second;
609         }
610
611         knob->set_color(color);
612         write (knob->state_msg());
613 }
614
615 void
616 LaunchControlXL::update_knob_led_by_strip(uint8_t n)
617 {
618         LEDColor color;
619
620         boost::shared_ptr<Knob> knobs_col[3];
621         knobs_by_column(n, knobs_col);
622
623         for  (uint8_t s = 0; s < 3; ++s) {
624                 if (knobs_col[s]) {
625                         if (stripable[n]) {
626                                 if (stripable[n]->is_selected()) {
627                                         color = knobs_col[s]->color_enabled();
628                                 } else {
629                                         color = knobs_col[s]->color_disabled();
630                                 }
631                                 knobs_col[s]->set_color(color);
632                         } else {
633                                 knobs_col[s]->set_color(Off);
634                         }
635                         write (knobs_col[s]->state_msg());
636                 }
637         }
638 }
639
640 void
641 LaunchControlXL::update_track_control_led(uint8_t n)
642 {
643         boost::shared_ptr<TrackButton> b = control_button_by_column(n);
644
645         if (!b) {
646                 return;
647         }
648
649         if ((buttons_down.find(Device) != buttons_down.end())) {
650                 /* Don't update LEDs if Device button is hold - we are working on selected strips */
651                 return;
652         }
653
654         if (stripable[n]) {
655                         boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
656                         if (ac) {
657                                 if (ac->get_value()) {
658                                         b->set_color(b->color_enabled());
659                                 } else {
660                                 b->set_color(b->color_disabled());
661                                 }
662                         } else {
663                                 b->set_color(Off);
664                         }
665         } else {
666                 b->set_color(Off);
667         }
668
669         write (b->state_msg());
670 }
671
672 void
673 LaunchControlXL::solo_mute_rec_changed(uint32_t n) {
674         if (!stripable[n]) {
675                 return;
676         }
677         switch_bank(bank_start);
678         //update_track_control_led(n);
679 }
680
681 void
682 LaunchControlXL::solo_iso_changed(uint32_t n)
683 {
684         if (!stripable[n]) {
685                 return;
686         } else {
687                 solo_iso_led_bank();
688         }
689 }
690
691 void
692 LaunchControlXL::solo_iso_led_bank ()
693 {
694         if (device_mode()) { return; }
695
696         int stripable_counter = get_amount_of_tracks();
697
698         if (!(buttons_down.find(Device) != buttons_down.end())) {
699                 return;
700         } else {
701                 for (int n = 0; n < stripable_counter; ++n) {
702                         boost::shared_ptr<TrackButton> b = focus_button_by_column(n);
703                         if (stripable[n] && stripable[n]->solo_isolate_control()) {
704                                 if (stripable[n]->solo_isolate_control()->get_value()) {
705                                         b->set_color(RedFull);
706                                 } else {
707                                         b->set_color(Off);
708                                 }
709                                 if (b) {
710                                         write (b->state_msg());
711                                 }
712                         }
713                 }
714                 LaunchControlXL::set_refresh_leds_flag(true);
715         }
716 }
717
718 #ifdef MIXBUS
719 void
720 LaunchControlXL::master_send_changed(uint32_t n)
721 {
722         if (!stripable[n]) {
723                 return;
724         } else {
725                 master_send_led_bank();
726         }
727 }
728
729 void
730 LaunchControlXL::master_send_led_bank ()
731 {
732         if (device_mode()) { return; }
733
734         if (!(buttons_down.find(Device) != buttons_down.end())) {
735                 return;
736         } else {
737                 int stripable_counter = LaunchControlXL::get_amount_of_tracks();
738
739                 for (int n = 0; n < stripable_counter; ++n) {
740                         boost::shared_ptr<TrackButton> b = control_button_by_column(n);
741                         if (stripable[n] && stripable[n]->master_send_enable_controllable()) {
742                                 if (stripable[n]->master_send_enable_controllable()->get_value()) {
743                                         b->set_color(GreenFull);
744                                 } else {
745                                         b->set_color(Off);
746                                 }
747                         }
748                         if (b) {
749                                 write (b->state_msg());
750                         }
751                 }
752                 LaunchControlXL::set_refresh_leds_flag(true);
753         }
754 }
755 # endif
756
757 void
758 LaunchControlXL::fader(uint8_t n)
759 {
760         if (!stripable[n]) {
761                 return;
762         }
763
764         boost::shared_ptr<Fader> fader;
765         IDFaderMap::iterator f = id_fader_map.find(static_cast<FaderID>(n));
766
767         if (f != id_fader_map.end()) {
768                 fader = f->second;
769         }
770
771         if (!fader) {
772                 return;
773         }
774
775         boost::shared_ptr<AutomationControl> ac = stripable[fader->id()]->gain_control();
776         if (ac && check_pick_up(fader, ac)) {
777                 ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
778         }
779 }
780
781 void
782 LaunchControlXL::knob_sendA(uint8_t n)
783 {
784         if (!stripable[n]) {
785                 return;
786         }
787
788         boost::shared_ptr<Knob> knob;
789         IDKnobMap::iterator k = id_knob_map.find(static_cast<KnobID>(n));
790
791         if (k != id_knob_map.end()) {
792                 knob = k->second;
793         }
794
795         if (!knob) {
796                 return;
797         }
798
799         boost::shared_ptr<AutomationControl> ac;
800
801         if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
802                 ac = stripable[n]->trim_control();
803         } else {
804                 ac = stripable[n]->send_level_controllable (send_bank_base());
805         }
806
807         if (ac && check_pick_up(knob, ac)) {
808                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
809         }
810 }
811
812 void
813 LaunchControlXL::knob_sendB(uint8_t n)
814 {
815         if (!stripable[n]) {
816                 return;
817         }
818
819         boost::shared_ptr<Knob> knob;
820         IDKnobMap::iterator k = id_knob_map.find(static_cast<KnobID>(n + 8));
821
822         if (k != id_knob_map.end()) {
823                 knob = k->second;
824         }
825
826         if (!knob) {
827                 return;
828         }
829
830         boost::shared_ptr<AutomationControl> ac;
831
832         if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
833         #ifdef MIXBUS
834                 ac = stripable[n]->filter_freq_controllable (true);
835         #else
836                 /* something */
837         #endif
838         } else {
839                 ac = stripable[n]->send_level_controllable (send_bank_base() + 1);
840         }
841
842         if (ac && check_pick_up(knob, ac)) {
843                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
844         }
845 }
846
847 void
848 LaunchControlXL::knob_pan(uint8_t n)
849 {
850         if (!stripable[n]) {
851                 return;
852         }
853
854         boost::shared_ptr<Knob> knob;
855         IDKnobMap::iterator k = id_knob_map.find(static_cast<KnobID>(n + 16));
856
857         if (k != id_knob_map.end()) {
858                 knob = k->second;
859         }
860
861         if (!knob) {
862                 return;
863         }
864
865         boost::shared_ptr<AutomationControl> ac;
866
867         if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
868 #ifdef MIXBUS
869                 ac = stripable[n]->filter_freq_controllable(true);
870 #else
871                 ac = stripable[n]->pan_width_control();
872 #endif
873         } else {
874                 ac = stripable[n]->pan_azimuth_control();
875         }
876
877
878         if (ac && check_pick_up(knob, ac)) {
879                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
880         }
881 }
882
883 void
884 LaunchControlXL::button_track_focus(uint8_t n)
885 {
886         if (buttons_down.find(Device) != buttons_down.end()) {
887                 DEBUG_TRACE (DEBUG::LaunchControlXL, "DEVICE BUTTON HOLD\n");
888                 if (stripable[n]->solo_isolate_control()) {
889                         bool solo_isolate_active = stripable[n]->solo_isolate_control()->get_value();
890                         stripable[n]->solo_isolate_control()->set_value (!solo_isolate_active, PBD::Controllable::UseGroup);
891                 }
892                 return;
893         }
894
895         if (stripable[n]) {
896                 if ( stripable[n]->is_selected() ) {
897                          ControlProtocol::RemoveStripableFromSelection (stripable[n]);
898                 } else {
899                         ControlProtocol::AddStripableToSelection (stripable[n]);
900                 }
901         } else {
902                 return;
903         }
904 }
905
906 void
907 LaunchControlXL::button_press_track_control(uint8_t n) {
908         if (!stripable[n]) {
909                 return;
910         }
911
912         if (buttons_down.find(Device) != buttons_down.end()) {
913                 DEBUG_TRACE (DEBUG::LaunchControlXL, "DEVICE BUTTON HOLD\n");
914 #ifdef MIXBUS
915                 if (stripable[n]->master_send_enable_controllable()) {
916                         bool master_send_active = stripable[n]->master_send_enable_controllable()->get_value();
917
918                         DEBUG_TRACE (DEBUG::LaunchControlXL, "MIXBUS Master Assign\n");
919                         stripable[n]->master_send_enable_controllable()->set_value (!master_send_active, PBD::Controllable::UseGroup);
920                 }
921
922 #else
923                 /* something useful for Ardour */
924 #endif
925                 return;
926         }
927
928         boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
929
930         if (ac) {
931                 session->set_control (ac, !ac->get_value(), PBD::Controllable::UseGroup);
932         }
933 }
934
935 void
936 LaunchControlXL::button_track_mode(TrackMode state)
937 {
938                 set_track_mode(state);
939                 for (uint8_t n = 0; n < 8; ++n) {
940                         update_track_control_led(n);
941                 }
942
943                 boost::shared_ptr<TrackStateButton> mute = boost::dynamic_pointer_cast<TrackStateButton> (id_note_button_map[Mute]);
944                 boost::shared_ptr<TrackStateButton> solo = boost::dynamic_pointer_cast<TrackStateButton> (id_note_button_map[Solo]);
945                 boost::shared_ptr<TrackStateButton> record = boost::dynamic_pointer_cast<TrackStateButton> (id_note_button_map[Record]);
946
947                 if (mute && solo && record) {
948                         write(mute->state_msg((state == TrackMute)));
949                         write(solo->state_msg((state == TrackSolo)));
950                         write(record->state_msg((state == TrackRecord)));
951                 }
952 }
953
954 void
955 LaunchControlXL::button_select_left()
956 {
957         switch_bank (max (0, bank_start - (7 + (fader8master() ? 0 : 1))));
958 }
959
960 void
961 LaunchControlXL::button_select_right()
962 {
963         switch_bank (max (0, bank_start + 7 + (fader8master() ? 0 : 1)));
964 }
965
966 void
967 LaunchControlXL::send_bank_switch(bool down) {
968         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("send_bank_switch - down: %1\n", down));
969         if (down) {
970                 set_send_bank(+2);
971         } else {
972                 set_send_bank(-2);
973         }
974 }
975
976 void
977 LaunchControlXL::button_device()
978 {
979 #ifndef MIXBUS
980         return; // currently device mode only on Mixbus
981 #endif
982         LaunchControlXL::set_device_mode(!device_mode());
983 }
984
985 void
986 LaunchControlXL::button_device_long_press()
987 {
988         if (device_mode()) { return ; }
989
990         solo_iso_led_bank();
991 #ifdef MIXBUS
992         master_send_led_bank();
993 #endif
994 }
995
996 void
997 LaunchControlXL::button_mute()
998 {
999         if (buttons_down.find(Device) != buttons_down.end()) {
1000                 access_action ("Editor/track-mute-toggle");
1001         } else {
1002                 button_track_mode(TrackMute);
1003         }
1004 }
1005
1006 void
1007 LaunchControlXL::button_mute_long_press()
1008 {
1009         session->cancel_all_mute();
1010 }
1011
1012 void
1013 LaunchControlXL::button_solo()
1014 {
1015         if (buttons_down.find(Device) != buttons_down.end()) {
1016                 access_action ("Editor/track-solo-toggle");
1017         } else {
1018                 button_track_mode(TrackSolo);
1019         }
1020 }
1021
1022 void
1023 LaunchControlXL::button_solo_long_press()
1024 {
1025         cancel_all_solo();
1026 }
1027
1028 void
1029 LaunchControlXL::button_record()
1030 {
1031         if (buttons_down.find(Device) != buttons_down.end()) {
1032                 access_action ("Editor/track-record-enable-toggle");
1033         } else {
1034                 button_track_mode(TrackRecord);
1035         }
1036 }
1037
1038 bool
1039 LaunchControlXL::button_long_press_timeout (ButtonID id, boost::shared_ptr<Button> button)
1040 {
1041         if (buttons_down.find (id) != buttons_down.end()) {
1042                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, invoking method\n", id));
1043                 (button->long_press_method) ();
1044         } else {
1045                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, expired/cancelled\n", id));
1046                 /* release happened and somehow we were not cancelled */
1047         }
1048
1049         /* whichever button this was, we've used it ... don't invoke the
1050            release action.
1051         */
1052         consumed.insert (id);
1053
1054         return false; /* don't get called again */
1055 }
1056
1057
1058 void
1059 LaunchControlXL::start_press_timeout (boost::shared_ptr<Button> button, ButtonID id)
1060 {
1061         ButtonID no_timeout_buttons[] = { SelectUp, SelectDown, SelectLeft, SelectRight };
1062
1063         for (size_t n = 0; n < sizeof (no_timeout_buttons) / sizeof (no_timeout_buttons[0]); ++n) {
1064                 if (id == no_timeout_buttons[n]) {
1065                         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("Not using timeout for button id %1\n", id));
1066                         return;
1067                 }
1068         }
1069
1070         Glib::RefPtr<Glib::TimeoutSource> timeout = Glib::TimeoutSource::create (500); // milliseconds
1071         button->timeout_connection = timeout->connect (sigc::bind (sigc::mem_fun (*this, &LaunchControlXL::button_long_press_timeout), id, button));
1072         timeout->attach (main_loop()->get_context());
1073 }
1074
1075
1076 /* Device Mode functions */
1077
1078 void
1079 LaunchControlXL::dm_select_prev_strip()
1080 {
1081         access_action ("Editor/select-prev-stripable");
1082 }
1083
1084 void
1085 LaunchControlXL::dm_select_next_strip()
1086 {
1087         access_action ("Editor/select-next-stripable");
1088 }
1089
1090 uint8_t
1091 LaunchControlXL::dm_check_dummy (DeviceStatus ds)
1092 {
1093         return ds;
1094 }
1095
1096 void
1097 LaunchControlXL::dm_fader (FaderID id) {
1098
1099         if (!first_selected_stripable()) {
1100                 return;
1101         }
1102
1103         boost::shared_ptr<AutomationControl> ac;
1104         boost::shared_ptr<Fader> fader;
1105
1106         IDFaderMap::iterator f = id_fader_map.find(id);
1107
1108         if (f != id_fader_map.end()) {
1109                 fader = f->second;
1110         }
1111
1112         ac = first_selected_stripable()->gain_control();
1113         if (ac && check_pick_up(fader, ac)) {
1114                 ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
1115         }
1116 }
1117
1118 uint8_t
1119 LaunchControlXL::dm_check_pan_azi()
1120 {
1121         if (!first_selected_stripable()) {
1122                 return dev_nonexistant;
1123         }
1124
1125         uint8_t dev_status = dev_nonexistant;
1126         if (first_selected_stripable()->pan_azimuth_control()) {
1127                         dev_status = dev_active;
1128         }
1129
1130         return dev_status;
1131 }
1132
1133 void
1134 LaunchControlXL::dm_pan_azi (KnobID k)
1135 {
1136         if (!first_selected_stripable()) {
1137                 return;
1138         }
1139
1140         boost::shared_ptr<AutomationControl> ac;
1141         boost::shared_ptr<Knob> knob = knob_by_id (k);
1142
1143         ac = first_selected_stripable()->pan_azimuth_control();
1144
1145         if (ac && check_pick_up(knob, ac)) {
1146                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1147         }
1148 }
1149
1150
1151 uint8_t
1152 LaunchControlXL::dm_check_pan_width()
1153 {
1154         if (!first_selected_stripable()) {
1155                 return dev_nonexistant;
1156         }
1157
1158         uint8_t dev_status = dev_nonexistant;
1159         if (first_selected_stripable()->pan_width_control()) {
1160                         dev_status = dev_active;
1161         }
1162
1163         return dev_status;
1164 }
1165
1166 void
1167 LaunchControlXL::dm_pan_width (KnobID k)
1168 {
1169         if (!first_selected_stripable()) {
1170                 return;
1171         }
1172
1173         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_pan_width()\n");
1174         boost::shared_ptr<AutomationControl> ac;
1175         boost::shared_ptr<Knob> knob = knob_by_id (k);
1176
1177         ac = first_selected_stripable()->pan_width_control();
1178
1179         if (ac && check_pick_up(knob, ac)) {
1180                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1181         }
1182 }
1183
1184 uint8_t
1185 LaunchControlXL::dm_check_trim()
1186 {
1187         if (!first_selected_stripable()) {
1188                 return dev_nonexistant;
1189         }
1190
1191         uint8_t dev_status = dev_nonexistant;
1192         if (first_selected_stripable()->trim_control()) {
1193                         dev_status = dev_active;
1194         }
1195
1196         return dev_status;
1197 }
1198
1199 void
1200 LaunchControlXL::dm_trim (KnobID k)
1201 {
1202         if (!first_selected_stripable()) {
1203                 return;
1204         }
1205
1206         boost::shared_ptr<AutomationControl> ac;
1207         boost::shared_ptr<Knob> knob = knob_by_id (k);
1208
1209         ac = first_selected_stripable()->trim_control();
1210
1211         if (ac && check_pick_up(knob, ac)) {
1212                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1213         }
1214 }
1215
1216 uint8_t
1217 LaunchControlXL::dm_mute_enabled()
1218 {
1219         if (!first_selected_stripable()) {
1220                 return dev_nonexistant;
1221         }
1222
1223         uint8_t dev_status = dev_nonexistant;
1224         if (first_selected_stripable()->mute_control()->get_value()) {
1225                 dev_status = dev_active;
1226         } else {
1227                 dev_status = dev_inactive;
1228         }
1229
1230         return dev_status;
1231 }
1232
1233 void
1234 LaunchControlXL::dm_mute_switch()
1235 {
1236         if (!first_selected_stripable()) {
1237                 return;
1238         }
1239
1240         if (first_selected_stripable()->mute_control()) {
1241                 first_selected_stripable()->mute_control()->set_value(!first_selected_stripable()->mute_control()->get_value(), PBD::Controllable::NoGroup);
1242         }
1243 }
1244
1245 uint8_t
1246 LaunchControlXL::dm_solo_enabled()
1247 {
1248         if (!first_selected_stripable() || first_selected_stripable()->is_master()) {
1249                 return dev_nonexistant;
1250         }
1251
1252         uint8_t dev_status = dev_nonexistant;
1253         if (first_selected_stripable()->solo_control()) {
1254                 if (first_selected_stripable()->solo_control()->get_value()) {
1255                         dev_status = dev_active;
1256                 } else {
1257                         dev_status = dev_inactive;
1258                 }
1259         }
1260
1261         return dev_status;
1262 }
1263
1264 void
1265 LaunchControlXL::dm_solo_switch()
1266 {
1267         if (!first_selected_stripable()) {
1268                 return;
1269         }
1270
1271         if (first_selected_stripable()->solo_control()) {
1272                 first_selected_stripable()->solo_control()->set_value(!first_selected_stripable()->solo_control()->get_value(), PBD::Controllable::NoGroup);
1273         }
1274 }
1275
1276 uint8_t
1277 LaunchControlXL::dm_recenable_enabled()
1278 {
1279         if (!first_selected_stripable()) {
1280                 return dev_nonexistant;
1281         }
1282
1283         uint8_t dev_status = dev_nonexistant;
1284         if (first_selected_stripable()->rec_enable_control()) {
1285                 if (first_selected_stripable()->rec_enable_control()->get_value()) {
1286                         dev_status = dev_active;
1287                 }  else {
1288                         dev_status = dev_inactive;
1289                 }
1290         }
1291
1292         return dev_status;
1293 }
1294
1295 void
1296 LaunchControlXL::dm_recenable_switch()
1297 {
1298         if (!first_selected_stripable()) {
1299                 return;
1300         }
1301
1302         if (first_selected_stripable()->rec_enable_control()) {
1303                 first_selected_stripable()->rec_enable_control()->set_value(!first_selected_stripable()->rec_enable_control()->get_value(), PBD::Controllable::NoGroup);
1304         }
1305 }
1306
1307
1308 #ifdef MIXBUS
1309 uint8_t
1310 LaunchControlXL::dm_mb_eq_freq_enabled()
1311 {
1312         if (!first_selected_stripable()) {
1313                 return dev_nonexistant;
1314         }
1315
1316         uint8_t dev_status = dev_nonexistant;
1317
1318         if (first_selected_stripable()->eq_enable_controllable()) {
1319                 if (first_selected_stripable()->eq_enable_controllable()->get_value()) {
1320                         dev_status = dev_active;
1321                 } else {
1322                         dev_status = dev_inactive;
1323                 }
1324         }
1325
1326         if (first_selected_stripable()->mixbus() || first_selected_stripable()->is_master()) {
1327                 dev_status = dev_nonexistant;
1328         }
1329
1330         return dev_status;
1331 }
1332
1333
1334 uint8_t
1335 LaunchControlXL::dm_mb_eq_gain_enabled(uint8_t band)
1336 {
1337         if (!first_selected_stripable()) {
1338                 return dev_nonexistant;
1339         }
1340
1341         uint8_t dev_status = dev_nonexistant;
1342
1343         if (first_selected_stripable()->eq_enable_controllable()) {
1344                 if (first_selected_stripable()->eq_enable_controllable()->get_value()) {
1345                         dev_status = dev_active;
1346                 } else {
1347                         dev_status = dev_inactive;
1348                 }
1349         }
1350
1351         if (first_selected_stripable()->mixbus() && band > 3) {
1352                 dev_status = dev_nonexistant;
1353         }
1354
1355         return dev_status;
1356 }
1357
1358 void
1359 LaunchControlXL::dm_mb_eq (KnobID k, bool gain, uint8_t band)
1360 {
1361         if (!first_selected_stripable()) {
1362                 return;
1363         }
1364
1365         boost::shared_ptr<AutomationControl> ac;
1366         boost::shared_ptr<Knob> knob = knob_by_id (k);
1367         if (gain) {
1368                 ac = first_selected_stripable()->eq_gain_controllable(band);
1369         } else {
1370                 ac = first_selected_stripable()->eq_freq_controllable(band);
1371         }
1372
1373         if (ac && check_pick_up(knob, ac)) {
1374                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1375         }
1376 }
1377
1378 void
1379 LaunchControlXL::dm_mb_eq_shape_switch (uint8_t band)
1380 {
1381         if (!first_selected_stripable()) {
1382                 return;
1383         }
1384
1385         if (first_selected_stripable()->eq_shape_controllable(band)) {
1386         first_selected_stripable()->eq_shape_controllable(band)->set_value
1387                         (!first_selected_stripable()->eq_shape_controllable(band)->get_value(), PBD::Controllable::NoGroup );
1388         }
1389 }
1390
1391
1392 uint8_t
1393 LaunchControlXL::dm_mb_eq_shape_enabled(uint8_t band)
1394 {
1395         if (!first_selected_stripable()) {
1396                 return dev_nonexistant;
1397         }
1398
1399         uint8_t dev_status = dev_nonexistant;
1400
1401         if (first_selected_stripable()->eq_shape_controllable(band)) {
1402                 if (first_selected_stripable()->eq_shape_controllable(band)->get_value()) {
1403                         dev_status = dev_active;
1404                 } else {
1405                         dev_status = dev_inactive;
1406                 }
1407         }
1408
1409         return dev_status;
1410 }
1411
1412
1413 void
1414 LaunchControlXL::dm_mb_eq_switch()
1415 {
1416         if (!first_selected_stripable()) {
1417                 return;
1418         }
1419
1420         if (first_selected_stripable()->eq_enable_controllable()) {
1421                 first_selected_stripable()->eq_enable_controllable()->set_value
1422                         (!first_selected_stripable()->eq_enable_controllable()->get_value(), PBD::Controllable::NoGroup );
1423         }
1424 }
1425
1426 uint8_t
1427 LaunchControlXL::dm_mb_flt_enabled()
1428 {
1429         if (!first_selected_stripable()) {
1430                 return dev_nonexistant;
1431         }
1432
1433         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled()\n");
1434         uint8_t dev_status = dev_nonexistant;
1435
1436         if (first_selected_stripable()->filter_enable_controllable(true)) {
1437                 DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled() - filter exists\n");
1438                 if (first_selected_stripable()->filter_enable_controllable(true)->get_value()) {
1439                         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled: get_value true\n");
1440                         dev_status = dev_active;
1441                 } else {
1442                         dev_status = dev_inactive;
1443                 }
1444         }
1445         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_flt_enabled: dev_status: %1\n", (int)dev_status));
1446         return dev_status;
1447 }
1448
1449
1450 void
1451 LaunchControlXL::dm_mb_flt_switch()
1452 {
1453         if (!first_selected_stripable()) {
1454                 return;
1455         }
1456
1457         if (first_selected_stripable()->filter_enable_controllable(true)) {
1458                 first_selected_stripable()->filter_enable_controllable(true)->set_value
1459                         (!first_selected_stripable()->filter_enable_controllable(true)->get_value(), PBD::Controllable::NoGroup );
1460         }
1461 }
1462
1463
1464
1465 void
1466 LaunchControlXL::dm_mb_flt_frq (KnobID k, bool hpf)
1467 {
1468         if (!first_selected_stripable()) {
1469                 return;
1470         }
1471
1472         boost::shared_ptr<AutomationControl> ac;
1473         boost::shared_ptr<Knob> knob = knob_by_id (k);
1474         if (hpf) {
1475                 ac = first_selected_stripable()->filter_freq_controllable(true);
1476         } else {
1477                 ac = first_selected_stripable()->filter_freq_controllable(false);
1478         }
1479
1480         if (ac && check_pick_up(knob, ac)) {
1481                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1482         }
1483 }
1484
1485 uint8_t
1486 LaunchControlXL::dm_mb_check_send_knob (KnobID k)
1487 {
1488         if (!first_selected_stripable()) {
1489                 return dev_nonexistant;
1490         }
1491
1492         uint8_t send = static_cast<uint8_t> (k) - 16 + 4 * send_bank_base();
1493
1494         uint8_t dev_status = dev_nonexistant;
1495
1496         if (first_selected_stripable()->send_enable_controllable(send)) {
1497                 dev_status = dev_inactive;
1498                 if (first_selected_stripable()->send_enable_controllable(send)->get_value()) {
1499                         dev_status = dev_active;
1500                 }
1501         }
1502
1503         return dev_status;
1504 }
1505
1506 uint8_t
1507 LaunchControlXL::dm_mb_check_send_button (uint8_t s)
1508 {
1509         if (!first_selected_stripable()) {
1510                 return dev_nonexistant;
1511         }
1512
1513
1514         uint8_t send = s + 4 * send_bank_base();
1515
1516         uint8_t dev_status = dev_nonexistant;
1517
1518         if (first_selected_stripable()->send_enable_controllable(send)) {
1519                 dev_status = dev_inactive;
1520                 if (first_selected_stripable()->send_enable_controllable(send)->get_value()) {
1521                         dev_status = dev_active;
1522                 }
1523         }
1524
1525         return dev_status;
1526 }
1527
1528
1529
1530 void
1531 LaunchControlXL::dm_mb_sends (KnobID k)
1532 {
1533         if (!first_selected_stripable()) {
1534                 return;
1535         }
1536
1537         boost::shared_ptr<AutomationControl> ac;
1538         boost::shared_ptr<Knob> knob = knob_by_id (k);
1539
1540         uint8_t send = static_cast<uint8_t> (k) - 16 + 4 * send_bank_base();
1541         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: knobid '%1'\n", k));
1542         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1'\n", (int)send));
1543
1544
1545         if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
1546                 ac = first_selected_stripable()->send_pan_azi_controllable(send);
1547         } else {
1548                 ac = first_selected_stripable()->send_level_controllable(send);
1549         }
1550
1551         if (ac && check_pick_up(knob, ac)) {
1552                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1553         }
1554 }
1555
1556 uint8_t
1557 LaunchControlXL::dm_mb_comp_enabled()
1558 {
1559         if (!first_selected_stripable()) {
1560                 return dev_nonexistant;
1561         }
1562
1563         uint8_t dev_status = dev_nonexistant;
1564         if (first_selected_stripable()->comp_enable_controllable()) {
1565                 if (first_selected_stripable()->comp_enable_controllable()->get_value()) {
1566                         dev_status = dev_active;
1567                 } else {
1568                         dev_status = dev_inactive;
1569                 }
1570         }
1571
1572         return dev_status;
1573 }
1574
1575 void
1576 LaunchControlXL::dm_mb_comp_switch()
1577 {
1578         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_comp_siwtch() \n");
1579         if (!first_selected_stripable()) {
1580                 return;
1581         }
1582
1583         if (first_selected_stripable()->comp_enable_controllable()) {
1584                 DEBUG_TRACE (DEBUG::LaunchControlXL, "comp_enable_controllable exists\n");
1585                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("comp_enable_controllable(): '%1'\n", first_selected_stripable()->comp_enable_controllable()->get_value() ));
1586                 first_selected_stripable()->comp_enable_controllable()->set_value
1587                         (!first_selected_stripable()->comp_enable_controllable()->get_value(), PBD::Controllable::NoGroup);
1588         }
1589
1590 }
1591
1592 void
1593 LaunchControlXL::dm_mb_comp (KnobID k, CompParam c)
1594 {
1595         if (!first_selected_stripable()) {
1596                 return;
1597         }
1598
1599         boost::shared_ptr<AutomationControl> ac;
1600         boost::shared_ptr<Knob> knob = knob_by_id (k);
1601
1602         switch (c) {
1603                 case (CompMakeup):
1604                         ac = first_selected_stripable()->comp_makeup_controllable();
1605                         break;
1606                 case (CompMode):
1607                         ac = first_selected_stripable()->comp_mode_controllable();
1608                         break;
1609                 case (CompSpeed):
1610                         ac = first_selected_stripable()->comp_speed_controllable();
1611                         break;
1612         }
1613
1614                 if (ac && check_pick_up(knob, ac)) {
1615                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1616         }
1617 }
1618
1619 void
1620 LaunchControlXL::dm_mb_comp_thresh (FaderID id) {
1621
1622         if (!first_selected_stripable()) {
1623                 return;
1624         }
1625
1626         boost::shared_ptr<AutomationControl> ac;
1627         boost::shared_ptr<Fader> fader;
1628
1629         IDFaderMap::iterator f = id_fader_map.find(id);
1630
1631         if (f != id_fader_map.end()) {
1632                 fader = f->second;
1633         }
1634
1635         ac = first_selected_stripable()->comp_threshold_controllable();
1636         if (ac && check_pick_up(fader, ac)) {
1637                 ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
1638         }
1639 }
1640
1641 uint8_t
1642 LaunchControlXL::dm_mb_has_tapedrive()
1643 {
1644         if (!first_selected_stripable()) {
1645                 return dev_nonexistant;
1646         }
1647
1648         uint8_t dev_status = dev_nonexistant;
1649
1650         if (first_selected_stripable()->mixbus() || first_selected_stripable()->is_master()) {
1651                 dev_status = dev_active;
1652         }
1653
1654         return dev_status;
1655 }
1656
1657 void
1658 LaunchControlXL::dm_mb_tapedrive (KnobID k)
1659 {
1660         if (!first_selected_stripable()) {
1661                 return;
1662         }
1663
1664         boost::shared_ptr<AutomationControl> ac;
1665         boost::shared_ptr<Knob> knob = knob_by_id (k);
1666
1667         ac = first_selected_stripable()->tape_drive_controllable();
1668
1669         if (ac && check_pick_up(knob, ac)) {
1670                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1671         }
1672 }
1673
1674 uint8_t
1675 LaunchControlXL::dm_mb_master_assign_enabled()
1676 {
1677         if (!first_selected_stripable()) {
1678                 return dev_nonexistant;
1679         }
1680
1681         uint8_t dev_status = dev_nonexistant;
1682
1683         if (first_selected_stripable()->master_send_enable_controllable()) {
1684                 if (first_selected_stripable()->master_send_enable_controllable()->get_value()) {
1685                         dev_status = dev_active;
1686                 } else {
1687                         dev_status = dev_inactive;
1688                 }
1689         }
1690
1691         return dev_status;
1692 }
1693
1694 void
1695 LaunchControlXL::dm_mb_master_assign_switch()
1696 {
1697         if (!first_selected_stripable()) {
1698                 return;
1699         }
1700
1701         if (first_selected_stripable()->master_send_enable_controllable()) {
1702                 first_selected_stripable()->master_send_enable_controllable()->set_value
1703                         (!first_selected_stripable()->master_send_enable_controllable()->get_value(), PBD::Controllable::NoGroup );
1704         }
1705 }
1706
1707 void
1708 LaunchControlXL::dm_mb_send_switch(ButtonID id)
1709 {
1710         if (!first_selected_stripable()) {
1711                 return;
1712         }
1713
1714         boost::shared_ptr<Button> button = id_note_button_map[id];;
1715
1716         uint8_t send = static_cast<uint8_t> (id) + 4 * send_bank_base();
1717         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: buttonid '%1'\n", (int)id));
1718         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1'\n", (int)send));
1719
1720         if (first_selected_stripable()->send_enable_controllable(send)) {
1721                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1' exists\n", (int)send));
1722                 first_selected_stripable()->send_enable_controllable(send)->set_value
1723                         (!first_selected_stripable()->send_enable_controllable(send)->get_value(), PBD::Controllable::UseGroup);
1724         }
1725 }
1726
1727 #endif