94021fa48127b82a3e23efe432148d3bc512afa8
[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]->comp_threshold_controllable();
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         boost::shared_ptr<AutomationControl> ac;
1100         boost::shared_ptr<Fader> fader;
1101
1102         IDFaderMap::iterator f = id_fader_map.find(id);
1103
1104         if (f != id_fader_map.end()) {
1105                 fader = f->second;
1106         }
1107
1108         ac = first_selected_stripable()->gain_control();
1109         if (ac && check_pick_up(fader, ac)) {
1110                 ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
1111         }
1112 }
1113
1114 uint8_t
1115 LaunchControlXL::dm_check_pan_azi()
1116 {
1117         if (!first_selected_stripable()) {
1118                 return dev_nonexistant;
1119         }
1120
1121         uint8_t dev_status = dev_nonexistant;
1122         if (first_selected_stripable()->pan_azimuth_control()) {
1123                         dev_status = dev_active;
1124         }
1125
1126         return dev_status;
1127 }
1128
1129 void
1130 LaunchControlXL::dm_pan_azi (KnobID k)
1131 {
1132         if (!first_selected_stripable()) {
1133                 return;
1134         }
1135
1136         boost::shared_ptr<AutomationControl> ac;
1137         boost::shared_ptr<Knob> knob = knob_by_id (k);
1138
1139         ac = first_selected_stripable()->pan_azimuth_control();
1140
1141         if (ac && check_pick_up(knob, ac)) {
1142                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1143         }
1144 }
1145
1146
1147 uint8_t
1148 LaunchControlXL::dm_check_pan_width()
1149 {
1150         if (!first_selected_stripable()) {
1151                 return dev_nonexistant;
1152         }
1153
1154         uint8_t dev_status = dev_nonexistant;
1155         if (first_selected_stripable()->pan_width_control()) {
1156                         dev_status = dev_active;
1157         }
1158
1159         return dev_status;
1160 }
1161
1162 void
1163 LaunchControlXL::dm_pan_width (KnobID k)
1164 {
1165         if (!first_selected_stripable()) {
1166                 return;
1167         }
1168
1169         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_pan_width()\n");
1170         boost::shared_ptr<AutomationControl> ac;
1171         boost::shared_ptr<Knob> knob = knob_by_id (k);
1172
1173         ac = first_selected_stripable()->pan_width_control();
1174
1175         if (ac && check_pick_up(knob, ac)) {
1176                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1177         }
1178 }
1179
1180 uint8_t
1181 LaunchControlXL::dm_check_trim()
1182 {
1183         if (!first_selected_stripable()) {
1184                 return dev_nonexistant;
1185         }
1186
1187         uint8_t dev_status = dev_nonexistant;
1188         if (first_selected_stripable()->trim_control()) {
1189                         dev_status = dev_active;
1190         }
1191
1192         return dev_status;
1193 }
1194
1195 void
1196 LaunchControlXL::dm_trim (KnobID k)
1197 {
1198         if (!first_selected_stripable()) {
1199                 return;
1200         }
1201
1202         boost::shared_ptr<AutomationControl> ac;
1203         boost::shared_ptr<Knob> knob = knob_by_id (k);
1204
1205         ac = first_selected_stripable()->trim_control();
1206
1207         if (ac && check_pick_up(knob, ac)) {
1208                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1209         }
1210 }
1211
1212 uint8_t
1213 LaunchControlXL::dm_mute_enabled()
1214 {
1215         if (!first_selected_stripable()) {
1216                 return dev_nonexistant;
1217         }
1218
1219         uint8_t dev_status = dev_nonexistant;
1220         if (first_selected_stripable()->mute_control()->get_value()) {
1221                 dev_status = dev_active;
1222         } else {
1223                 dev_status = dev_inactive;
1224         }
1225
1226         return dev_status;
1227 }
1228
1229 void
1230 LaunchControlXL::dm_mute_switch()
1231 {
1232         if (!first_selected_stripable()) {
1233                 return;
1234         }
1235
1236         if (first_selected_stripable()->mute_control()) {
1237                 first_selected_stripable()->mute_control()->set_value(!first_selected_stripable()->mute_control()->get_value(), PBD::Controllable::NoGroup);
1238         }
1239 }
1240
1241 uint8_t
1242 LaunchControlXL::dm_solo_enabled()
1243 {
1244         if (!first_selected_stripable() || first_selected_stripable()->is_master()) {
1245                 return dev_nonexistant;
1246         }
1247
1248         uint8_t dev_status = dev_nonexistant;
1249         if (first_selected_stripable()->solo_control()) {
1250                 if (first_selected_stripable()->solo_control()->get_value()) {
1251                         dev_status = dev_active;
1252                 } else {
1253                         dev_status = dev_inactive;
1254                 }
1255         }
1256
1257         return dev_status;
1258 }
1259
1260 void
1261 LaunchControlXL::dm_solo_switch()
1262 {
1263         if (!first_selected_stripable()) {
1264                 return;
1265         }
1266
1267         if (first_selected_stripable()->solo_control()) {
1268                 first_selected_stripable()->solo_control()->set_value(!first_selected_stripable()->solo_control()->get_value(), PBD::Controllable::NoGroup);
1269         }
1270 }
1271
1272 uint8_t
1273 LaunchControlXL::dm_recenable_enabled()
1274 {
1275         if (!first_selected_stripable()) {
1276                 return dev_nonexistant;
1277         }
1278
1279         uint8_t dev_status = dev_nonexistant;
1280         if (first_selected_stripable()->rec_enable_control()) {
1281                 if (first_selected_stripable()->rec_enable_control()->get_value()) {
1282                         dev_status = dev_active;
1283                 }  else {
1284                         dev_status = dev_inactive;
1285                 }
1286         }
1287
1288         return dev_status;
1289 }
1290
1291 void
1292 LaunchControlXL::dm_recenable_switch()
1293 {
1294         if (!first_selected_stripable()) {
1295                 return;
1296         }
1297
1298         if (first_selected_stripable()->rec_enable_control()) {
1299                 first_selected_stripable()->rec_enable_control()->set_value(!first_selected_stripable()->rec_enable_control()->get_value(), PBD::Controllable::NoGroup);
1300         }
1301 }
1302
1303
1304 #ifdef MIXBUS
1305 uint8_t
1306 LaunchControlXL::dm_mb_eq_freq_enabled()
1307 {
1308         if (!first_selected_stripable()) {
1309                 return dev_nonexistant;
1310         }
1311
1312         uint8_t dev_status = dev_nonexistant;
1313
1314         if (first_selected_stripable()->eq_enable_controllable()) {
1315                 if (first_selected_stripable()->eq_enable_controllable()->get_value()) {
1316                         dev_status = dev_active;
1317                 } else {
1318                         dev_status = dev_inactive;
1319                 }
1320         }
1321
1322         if (first_selected_stripable()->mixbus() || first_selected_stripable()->is_master()) {
1323                 dev_status = dev_nonexistant;
1324         }
1325
1326         return dev_status;
1327 }
1328
1329
1330 uint8_t
1331 LaunchControlXL::dm_mb_eq_gain_enabled(uint8_t band)
1332 {
1333         if (!first_selected_stripable()) {
1334                 return dev_nonexistant;
1335         }
1336
1337         uint8_t dev_status = dev_nonexistant;
1338
1339         if (first_selected_stripable()->eq_enable_controllable()) {
1340                 if (first_selected_stripable()->eq_enable_controllable()->get_value()) {
1341                         dev_status = dev_active;
1342                 } else {
1343                         dev_status = dev_inactive;
1344                 }
1345         }
1346
1347         if (first_selected_stripable()->mixbus() && band > 3) {
1348                 dev_status = dev_nonexistant;
1349         }
1350
1351         return dev_status;
1352 }
1353
1354 void
1355 LaunchControlXL::dm_mb_eq (KnobID k, bool gain, uint8_t band)
1356 {
1357         if (!first_selected_stripable()) {
1358                 return;
1359         }
1360
1361         boost::shared_ptr<AutomationControl> ac;
1362         boost::shared_ptr<Knob> knob = knob_by_id (k);
1363         if (gain) {
1364                 ac = first_selected_stripable()->eq_gain_controllable(band);
1365         } else {
1366                 ac = first_selected_stripable()->eq_freq_controllable(band);
1367         }
1368
1369         if (ac && check_pick_up(knob, ac)) {
1370                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1371         }
1372 }
1373
1374 void
1375 LaunchControlXL::dm_mb_eq_shape_switch (uint8_t band)
1376 {
1377         if (!first_selected_stripable()) {
1378                 return;
1379         }
1380
1381         if (first_selected_stripable()->eq_shape_controllable(band)) {
1382         first_selected_stripable()->eq_shape_controllable(band)->set_value
1383                         (!first_selected_stripable()->eq_shape_controllable(band)->get_value(), PBD::Controllable::NoGroup );
1384         }
1385 }
1386
1387
1388 uint8_t
1389 LaunchControlXL::dm_mb_eq_shape_enabled(uint8_t band)
1390 {
1391         if (!first_selected_stripable()) {
1392                 return dev_nonexistant;
1393         }
1394
1395         uint8_t dev_status = dev_nonexistant;
1396
1397         if (first_selected_stripable()->eq_shape_controllable(band)) {
1398                 if (first_selected_stripable()->eq_shape_controllable(band)->get_value()) {
1399                         dev_status = dev_active;
1400                 } else {
1401                         dev_status = dev_inactive;
1402                 }
1403         }
1404
1405         return dev_status;
1406 }
1407
1408
1409 void
1410 LaunchControlXL::dm_mb_eq_switch()
1411 {
1412         if (!first_selected_stripable()) {
1413                 return;
1414         }
1415
1416         if (first_selected_stripable()->eq_enable_controllable()) {
1417                 first_selected_stripable()->eq_enable_controllable()->set_value
1418                         (!first_selected_stripable()->eq_enable_controllable()->get_value(), PBD::Controllable::NoGroup );
1419         }
1420 }
1421
1422 uint8_t
1423 LaunchControlXL::dm_mb_flt_enabled()
1424 {
1425         if (!first_selected_stripable()) {
1426                 return dev_nonexistant;
1427         }
1428
1429         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled()\n");
1430         uint8_t dev_status = dev_nonexistant;
1431
1432         if (first_selected_stripable()->filter_enable_controllable(true)) {
1433                 DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled() - filter exists\n");
1434                 if (first_selected_stripable()->filter_enable_controllable(true)->get_value()) {
1435                         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_flt_enabled: get_value true\n");
1436                         dev_status = dev_active;
1437                 } else {
1438                         dev_status = dev_inactive;
1439                 }
1440         }
1441         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_flt_enabled: dev_status: %1\n", (int)dev_status));
1442         return dev_status;
1443 }
1444
1445
1446 void
1447 LaunchControlXL::dm_mb_flt_switch()
1448 {
1449         if (!first_selected_stripable()) {
1450                 return;
1451         }
1452
1453         if (first_selected_stripable()->filter_enable_controllable(true)) {
1454                 first_selected_stripable()->filter_enable_controllable(true)->set_value
1455                         (!first_selected_stripable()->filter_enable_controllable(true)->get_value(), PBD::Controllable::NoGroup );
1456         }
1457 }
1458
1459
1460
1461 void
1462 LaunchControlXL::dm_mb_flt_frq (KnobID k, bool hpf)
1463 {
1464         if (!first_selected_stripable()) {
1465                 return;
1466         }
1467
1468         boost::shared_ptr<AutomationControl> ac;
1469         boost::shared_ptr<Knob> knob = knob_by_id (k);
1470         if (hpf) {
1471                 ac = first_selected_stripable()->filter_freq_controllable(true);
1472         } else {
1473                 ac = first_selected_stripable()->filter_freq_controllable(false);
1474         }
1475
1476         if (ac && check_pick_up(knob, ac)) {
1477                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1478         }
1479 }
1480
1481 uint8_t
1482 LaunchControlXL::dm_mb_check_send_knob (KnobID k)
1483 {
1484         if (!first_selected_stripable()) {
1485                 return dev_nonexistant;
1486         }
1487
1488         uint8_t send = static_cast<uint8_t> (k) - 16 + 4 * send_bank_base();
1489
1490         uint8_t dev_status = dev_nonexistant;
1491
1492         if (first_selected_stripable()->send_enable_controllable(send)) {
1493                 dev_status = dev_inactive;
1494                 if (first_selected_stripable()->send_enable_controllable(send)->get_value()) {
1495                         dev_status = dev_active;
1496                 }
1497         }
1498
1499         return dev_status;
1500 }
1501
1502 uint8_t
1503 LaunchControlXL::dm_mb_check_send_button (uint8_t s)
1504 {
1505         if (!first_selected_stripable()) {
1506                 return dev_nonexistant;
1507         }
1508
1509
1510         uint8_t send = s + 4 * send_bank_base();
1511
1512         uint8_t dev_status = dev_nonexistant;
1513
1514         if (first_selected_stripable()->send_enable_controllable(send)) {
1515                 dev_status = dev_inactive;
1516                 if (first_selected_stripable()->send_enable_controllable(send)->get_value()) {
1517                         dev_status = dev_active;
1518                 }
1519         }
1520
1521         return dev_status;
1522 }
1523
1524
1525
1526 void
1527 LaunchControlXL::dm_mb_sends (KnobID k)
1528 {
1529         if (!first_selected_stripable()) {
1530                 return;
1531         }
1532
1533         boost::shared_ptr<AutomationControl> ac;
1534         boost::shared_ptr<Knob> knob = knob_by_id (k);
1535
1536         uint8_t send = static_cast<uint8_t> (k) - 16 + 4 * send_bank_base();
1537         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: knobid '%1'\n", k));
1538         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1'\n", (int)send));
1539
1540
1541         if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
1542                 ac = first_selected_stripable()->send_pan_azi_controllable(send);
1543         } else {
1544                 ac = first_selected_stripable()->send_level_controllable(send);
1545         }
1546
1547         if (ac && check_pick_up(knob, ac)) {
1548                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1549         }
1550 }
1551
1552 uint8_t
1553 LaunchControlXL::dm_mb_comp_enabled()
1554 {
1555         if (!first_selected_stripable()) {
1556                 return dev_nonexistant;
1557         }
1558
1559         uint8_t dev_status = dev_nonexistant;
1560         if (first_selected_stripable()->comp_enable_controllable()) {
1561                 if (first_selected_stripable()->comp_enable_controllable()->get_value()) {
1562                         dev_status = dev_active;
1563                 } else {
1564                         dev_status = dev_inactive;
1565                 }
1566         }
1567
1568         return dev_status;
1569 }
1570
1571 void
1572 LaunchControlXL::dm_mb_comp_switch()
1573 {
1574         DEBUG_TRACE (DEBUG::LaunchControlXL, "dm_mb_comp_siwtch() \n");
1575         if (!first_selected_stripable()) {
1576                 return;
1577         }
1578
1579         if (first_selected_stripable()->comp_enable_controllable()) {
1580                 DEBUG_TRACE (DEBUG::LaunchControlXL, "comp_enable_controllable exists\n");
1581                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("comp_enable_controllable(): '%1'\n", first_selected_stripable()->comp_enable_controllable()->get_value() ));
1582                 first_selected_stripable()->comp_enable_controllable()->set_value
1583                         (!first_selected_stripable()->comp_enable_controllable()->get_value(), PBD::Controllable::NoGroup);
1584         }
1585
1586 }
1587
1588 void
1589 LaunchControlXL::dm_mb_comp (KnobID k, CompParam c)
1590 {
1591         if (!first_selected_stripable()) {
1592                 return;
1593         }
1594
1595         boost::shared_ptr<AutomationControl> ac;
1596         boost::shared_ptr<Knob> knob = knob_by_id (k);
1597
1598         switch (c) {
1599                 case (CompMakeup):
1600                         ac = first_selected_stripable()->comp_makeup_controllable();
1601                         break;
1602                 case (CompMode):
1603                         ac = first_selected_stripable()->comp_mode_controllable();
1604                         break;
1605                 case (CompSpeed):
1606                         ac = first_selected_stripable()->comp_speed_controllable();
1607                         break;
1608         }
1609
1610                 if (ac && check_pick_up(knob, ac)) {
1611                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1612         }
1613 }
1614
1615 void
1616 LaunchControlXL::dm_mb_comp_thresh (FaderID id) {
1617
1618         if (!first_selected_stripable()) {
1619                 return;
1620         }
1621
1622         boost::shared_ptr<AutomationControl> ac;
1623         boost::shared_ptr<Fader> fader;
1624
1625         IDFaderMap::iterator f = id_fader_map.find(id);
1626
1627         if (f != id_fader_map.end()) {
1628                 fader = f->second;
1629         }
1630
1631         ac = first_selected_stripable()->comp_threshold_controllable();
1632         if (ac && check_pick_up(fader, ac)) {
1633                 ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
1634         }
1635 }
1636
1637 uint8_t
1638 LaunchControlXL::dm_mb_has_tapedrive()
1639 {
1640         if (!first_selected_stripable()) {
1641                 return dev_nonexistant;
1642         }
1643
1644         uint8_t dev_status = dev_nonexistant;
1645
1646         if (first_selected_stripable()->mixbus() || first_selected_stripable()->is_master()) {
1647                 dev_status = dev_active;
1648         }
1649
1650         return dev_status;
1651 }
1652
1653 void
1654 LaunchControlXL::dm_mb_tapedrive (KnobID k)
1655 {
1656         if (!first_selected_stripable()) {
1657                 return;
1658         }
1659
1660         boost::shared_ptr<AutomationControl> ac;
1661         boost::shared_ptr<Knob> knob = knob_by_id (k);
1662
1663         ac = first_selected_stripable()->tape_drive_controllable();
1664
1665         if (ac && check_pick_up(knob, ac)) {
1666                 ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
1667         }
1668 }
1669
1670 uint8_t
1671 LaunchControlXL::dm_mb_master_assign_enabled()
1672 {
1673         if (!first_selected_stripable()) {
1674                 return dev_nonexistant;
1675         }
1676
1677         uint8_t dev_status = dev_nonexistant;
1678
1679         if (first_selected_stripable()->master_send_enable_controllable()) {
1680                 if (first_selected_stripable()->master_send_enable_controllable()->get_value()) {
1681                         dev_status = dev_active;
1682                 } else {
1683                         dev_status = dev_inactive;
1684                 }
1685         }
1686
1687         return dev_status;
1688 }
1689
1690 void
1691 LaunchControlXL::dm_mb_master_assign_switch()
1692 {
1693         if (!first_selected_stripable()) {
1694                 return;
1695         }
1696
1697         if (first_selected_stripable()->master_send_enable_controllable()) {
1698                 first_selected_stripable()->master_send_enable_controllable()->set_value
1699                         (!first_selected_stripable()->master_send_enable_controllable()->get_value(), PBD::Controllable::NoGroup );
1700         }
1701 }
1702
1703 void
1704 LaunchControlXL::dm_mb_send_switch(ButtonID id)
1705 {
1706         if (!first_selected_stripable()) {
1707                 return;
1708         }
1709
1710         boost::shared_ptr<Button> button = id_note_button_map[id];;
1711
1712         uint8_t send = static_cast<uint8_t> (id) + 4 * send_bank_base();
1713         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: buttonid '%1'\n", (int)id));
1714         DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1'\n", (int)send));
1715
1716         if (first_selected_stripable()->send_enable_controllable(send)) {
1717                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("dm_mb_send: send '%1' exists\n", (int)send));
1718                 first_selected_stripable()->send_enable_controllable(send)->set_value
1719                         (!first_selected_stripable()->send_enable_controllable(send)->get_value(), PBD::Controllable::UseGroup);
1720         }
1721 }
1722
1723 #endif