Only show user-presets in favorite sidebar
[ardour.git] / libs / surfaces / launch_control_xl / launch_control_xl.h
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 #ifndef __ardour_launch_control_h__
20 #define __ardour_launch_control_h__
21
22 #include <vector>
23 #include <map>
24 #include <stack>
25 #include <list>
26 #include <set>
27
28 #define ABSTRACT_UI_EXPORTS
29 #include "pbd/abstract_ui.h"
30
31 #include "midi++/types.h"
32
33 #include "ardour/mode.h"
34 #include "ardour/types.h"
35
36 #include "control_protocol/control_protocol.h"
37 #include "control_protocol/types.h"
38
39 #include "midi_byte_array.h"
40
41 namespace MIDI {
42 class Parser;
43 class Port;
44 } // namespace MIDI
45
46 namespace ARDOUR {
47 class AsyncMIDIPort;
48 class Port;
49 class MidiBuffer;
50 class MidiTrack;
51 } // namespace ARDOUR
52
53 namespace ArdourSurface {
54
55
56 struct LaunchControlRequest : public BaseUI::BaseRequestObject {
57         public:
58                 LaunchControlRequest() {}
59                 ~LaunchControlRequest() {}
60 };
61
62 class LCXLGUI;
63 class LaunchControlMenu;
64
65 class LaunchControlXL : public ARDOUR::ControlProtocol,
66                         public AbstractUI<LaunchControlRequest>
67 {
68 public:
69         enum TrackMode {
70                 TrackMute,
71                 TrackSolo,
72                 TrackRecord
73         };
74
75         enum ButtonID {
76                 Focus1 = 0,
77                 Focus2,
78                 Focus3,
79                 Focus4,
80                 Focus5,
81                 Focus6,
82                 Focus7,
83                 Focus8,
84                 Control1,
85                 Control2,
86                 Control3,
87                 Control4,
88                 Control5,
89                 Control6,
90                 Control7,
91                 Control8,
92                 Device,
93                 Mute,
94                 Solo,
95                 Record,
96                 SelectUp,
97                 SelectDown,
98                 SelectLeft,
99                 SelectRight
100         };
101
102         enum FaderID {
103                 Fader1 = 0,
104                 Fader2,
105                 Fader3,
106                 Fader4,
107                 Fader5,
108                 Fader6,
109                 Fader7,
110                 Fader8
111         };
112
113         enum KnobID {
114                 SendA1 = 0,
115                 SendA2,
116                 SendA3,
117                 SendA4,
118                 SendA5,
119                 SendA6,
120                 SendA7,
121                 SendA8,
122                 SendB1,
123                 SendB2,
124                 SendB3,
125                 SendB4,
126                 SendB5,
127                 SendB6,
128                 SendB7,
129                 SendB8,
130                 Pan1,
131                 Pan2,
132                 Pan3,
133                 Pan4,
134                 Pan5,
135                 Pan6,
136                 Pan7,
137                 Pan8
138         };
139
140         enum DeviceStatus {
141                 dev_nonexistant = 0,
142                 dev_inactive,
143                 dev_active
144         };
145
146         enum LEDFlag { Normal = 0xC, Blink = 0x8, DoubleBuffering = 0x0 };
147         enum LEDColor { Off=0, RedLow = 1, RedFull = 3, GreenLow = 16, GreenFull = 48, YellowLow = 34, YellowFull = 51, AmberLow = 18, AmberFull = 35};
148
149
150 #ifdef MIXBUS
151         enum CompParam {
152                 CompMakeup,
153                 CompMode,
154                 CompSpeed
155         };
156 #endif
157
158         struct Controller {
159                 Controller(uint8_t cn,  uint8_t val, boost::function<void ()> action)
160                 : _controller_number(cn)
161                 , _value(val)
162                 , action_method(action) {}
163
164                 uint8_t  controller_number() const { return _controller_number; }
165                 uint8_t value() const { return _value; }
166                 void set_value(uint8_t val) { _value = val; }
167
168                 protected:
169                 uint8_t _controller_number;
170                 uint8_t _value;
171
172                 public:
173                 boost::function<void ()> action_method;
174         };
175
176         struct LED {
177                 LED(uint8_t i, LEDColor c, LaunchControlXL& l) : _index(i), _color(c), _flag(Normal), lcxl(&l)  {}
178                 LED(uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& lcxl) : _index(i), _color(c), _flag(f) {}
179                 virtual ~LED() {}
180
181                 LEDColor color() const { return _color; }
182                 LEDFlag flag() const { return _flag; }
183                 uint8_t index() const { return _index; }
184                 void set_flag(LEDFlag f) { _flag = f; }
185
186                 virtual MidiByteArray state_msg(bool light) const = 0;
187
188                 protected:
189                 uint8_t _index;
190                 LEDColor _color;
191                 LEDFlag _flag;
192                 MidiByteArray _state_msg;
193                 LaunchControlXL* lcxl;
194         };
195
196         struct MultiColorLED : public LED {
197                 MultiColorLED (uint8_t i, LEDColor c, LaunchControlXL& l) : LED(i, c, l) {}
198                 MultiColorLED (uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& l)
199                         : LED(i, c, f, l) {}
200
201                 void set_color(LEDColor c) { _color = c; }
202         };
203
204         struct Button {
205                 Button(ButtonID id, boost::function<void ()> press, boost::function<void ()> release,
206                                 boost::function<void ()> long_press)
207                         : press_method(press)
208                         , release_method(release)
209                         , long_press_method(long_press),
210                         _id(id) {}
211
212                 virtual ~Button() {}
213
214                 ButtonID id() const { return _id; }
215
216                 boost::function<void ()> press_method;
217                 boost::function<void ()> release_method;
218                 boost::function<void ()> long_press_method;
219
220                 sigc::connection timeout_connection;
221
222                 protected:
223                 ButtonID _id;
224         };
225
226         struct ControllerButton : public Button {
227                 ControllerButton(ButtonID id, uint8_t cn,
228                                 boost::function<void ()> press,
229                                 boost::function<void ()> release,
230                                 boost::function<void ()> long_release)
231                         : Button(id, press, release, long_release), _controller_number(cn) {}
232
233
234
235                 uint8_t controller_number() const { return _controller_number; }
236
237                 private:
238                 uint8_t _controller_number;
239         };
240
241         struct NoteButton : public Button {
242                 NoteButton(ButtonID id, uint8_t cn,
243                                 boost::function<void ()> press,
244                                 boost::function<void ()> release,
245                                 boost::function<void ()> release_long)
246                         : Button(id, press, release, release_long), _note_number(cn) {}
247
248                 uint8_t note_number() const { return _note_number; }
249
250                 private:
251                 uint8_t _note_number;
252         };
253
254         struct TrackButton : public NoteButton, public MultiColorLED {
255                 TrackButton(ButtonID id, uint8_t nn, uint8_t index, LEDColor c_on, LEDColor c_off,
256                                 boost::function<void ()> press,
257                                 boost::function<void ()> release,
258                                 boost::function<void ()> release_long,
259                                 boost::function<uint8_t ()> check,
260                                 LaunchControlXL& l)
261                         : NoteButton(id, nn, press, release, release_long)
262                         , MultiColorLED(index, Off, l)
263                         , check_method(check)
264                         , _color_enabled (c_on)
265                         , _color_disabled (c_off) {}
266
267
268
269
270                 LEDColor color_enabled() const { return _color_enabled; }
271                 LEDColor color_disabled() const { return _color_disabled; }
272                 void set_color_enabled (LEDColor c_on) { _color_enabled = c_on; }
273                 void set_color_disabled (LEDColor c_off) { _color_disabled = c_off; }
274                 boost::function<uint8_t ()> check_method;
275
276
277                 MidiByteArray state_msg(bool light = true) const;
278
279                 private:
280                 LEDColor _color_enabled;
281                 LEDColor _color_disabled;
282         };
283
284         struct SelectButton : public ControllerButton, public LED {
285                 SelectButton(ButtonID id, uint8_t cn, uint8_t index,
286                                 boost::function<void ()> press,
287                                 boost::function<void ()> release,
288                                 boost::function<void ()> long_release,
289                                 LaunchControlXL& l)
290                         : ControllerButton(id, cn, press, release, long_release), LED(index, RedFull, l) {}
291
292
293                 MidiByteArray state_msg(bool light) const;
294         };
295
296         struct TrackStateButton : public NoteButton, public LED {
297                 TrackStateButton(ButtonID id, uint8_t nn, uint8_t index,
298                                 boost::function<void ()> press,
299                                 boost::function<void ()> release,
300                                 boost::function<void ()> release_long,
301                                 LaunchControlXL& l)
302                         : NoteButton(id, nn, press, release, release_long)
303                         , LED(index, YellowLow, l) {}
304
305                 MidiByteArray state_msg(bool light) const;
306         };
307
308         struct Fader : public Controller {
309                 Fader(FaderID id, uint8_t cn, boost::function<void ()> action)
310                         : Controller(cn, 0, action), _id(id) {} // minimal value
311
312                 FaderID id() const { return _id; }
313
314                 void controller_changed(Controller* controller);
315
316                 private:
317                 FaderID _id;
318         };
319
320         struct Knob : public Controller, public MultiColorLED {
321                 Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, boost::function<void ()> action,
322                         LaunchControlXL &l)
323                         : Controller(cn, 64, action)
324                         , MultiColorLED(index, Off, l)
325                         , _id(id)
326                         , _color_enabled (c_on)
327                         , _color_disabled (c_off) {} // knob 50/50 value
328
329                 Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, boost::function<void ()> action,
330                         boost::function<uint8_t ()> check, LaunchControlXL &l)
331                         : Controller(cn, 64, action)
332                         , MultiColorLED(index, Off, l)
333                         , check_method(check)
334                         , _id(id)
335                         , _color_enabled (c_on)
336                         , _color_disabled (c_off) {} // knob 50/50 value
337
338
339
340                 KnobID id() const { return _id; }
341                 LEDColor color_enabled() const { return _color_enabled; }
342                 LEDColor color_disabled() const { return _color_disabled; }
343                 boost::function<uint8_t ()> check_method;
344
345                 MidiByteArray state_msg(bool light = true) const;
346
347                 private:
348                 KnobID _id;
349                 LEDColor _color_enabled;
350                 LEDColor _color_disabled;
351         };
352
353 public:
354         LaunchControlXL(ARDOUR::Session &);
355         ~LaunchControlXL();
356
357
358         static bool probe();
359         static void *request_factory(uint32_t);
360
361         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles();
362
363         bool has_editor() const { return true; }
364         void *get_gui() const;
365         void tear_down_gui();
366
367         int get_amount_of_tracks();
368
369         int set_active(bool yn);
370         XMLNode &get_state();
371         int set_state(const XMLNode &node, int version);
372
373         PBD::Signal0<void> ConnectionChange;
374
375         boost::shared_ptr<ARDOUR::Port> input_port();
376         boost::shared_ptr<ARDOUR::Port> output_port();
377
378         Button *button_by_id(ButtonID);
379
380         static std::string button_name_by_id(ButtonID);
381         static std::string knob_name_by_id(KnobID);
382         static std::string fader_name_by_id(FaderID);
383
384         void write(const MidiByteArray &);
385         void reset(uint8_t chan);
386
387         void set_fader8master (bool yn);
388         bool fader8master () const { return _fader8master; }
389
390         void set_refresh_leds_flag (bool yn);
391         bool refresh_leds_flag () const { return _refresh_leds_flag; }
392
393         void set_device_mode (bool yn);
394         bool device_mode () const { return _device_mode; }
395
396 #ifdef MIXBUS32C
397         void store_fss_type();
398         bool fss_is_mixbus() const { return _fss_is_mixbus; }
399 #endif
400         TrackMode track_mode() const { return _track_mode; }
401         void set_track_mode(TrackMode mode);
402
403         uint8_t template_number() const { return _template_number; }
404
405         void set_send_bank (int offset);
406         void send_bank_switch(bool up);
407         int send_bank_base () const { return _send_bank_base; }
408
409 private:
410         bool in_use;
411         TrackMode _track_mode;
412         uint8_t _template_number;
413
414         bool _fader8master;
415         bool _device_mode;
416 #ifdef MIXBUS32C
417         bool _fss_is_mixbus;
418 #endif
419         bool _refresh_leds_flag;
420
421         int _send_bank_base;
422
423         void do_request(LaunchControlRequest *);
424
425         int begin_using_device();
426         int stop_using_device();
427         int ports_acquire();
428         void ports_release();
429         void run_event_loop();
430         void stop_event_loop();
431
432         void relax() {}
433
434         /* map of NoteButtons by NoteNumber */
435         typedef std::map<int, boost::shared_ptr<NoteButton> > NNNoteButtonMap;
436         NNNoteButtonMap nn_note_button_map;
437         /* map of NoteButtons by ButtonID */
438         typedef std::map<ButtonID, boost::shared_ptr<NoteButton> > IDNoteButtonMap;
439         IDNoteButtonMap id_note_button_map;
440         /* map of ControllerNoteButtons by CC */
441         typedef std::map<int, boost::shared_ptr<ControllerButton> > CCControllerButtonMap;
442         CCControllerButtonMap cc_controller_button_map;
443         /* map of ControllerButtons by ButtonID */
444         typedef std::map<ButtonID, boost::shared_ptr<ControllerButton> > IDControllerButtonMap;
445         IDControllerButtonMap id_controller_button_map;
446
447
448         /* map of Fader by CC */
449         typedef std::map<int, boost::shared_ptr<Fader> > CCFaderMap;
450         CCFaderMap cc_fader_map;
451         /* map of Fader by FaderID */
452         typedef std::map<FaderID, boost::shared_ptr<Fader> > IDFaderMap;
453         IDFaderMap id_fader_map;
454
455         /* map of Knob by CC */
456         typedef std::map<int, boost::shared_ptr<Knob> > CCKnobMap;
457         CCKnobMap cc_knob_map;
458         /* map of Knob by KnobID */
459         typedef std::map<KnobID, boost::shared_ptr<Knob> > IDKnobMap;
460         IDKnobMap id_knob_map;
461
462         std::set<ButtonID> buttons_down;
463         std::set<ButtonID> consumed;
464
465         bool button_long_press_timeout(ButtonID id, boost::shared_ptr<Button> button);
466         void start_press_timeout(boost::shared_ptr<Button> , ButtonID);
467
468         void init_buttons();
469         void init_buttons(bool startup);
470         void init_buttons (ButtonID buttons[], uint8_t i);
471         void init_knobs();
472         void init_knobs(KnobID knobs[], uint8_t i);
473         void init_knobs_and_buttons();
474
475         void init_device_mode();
476         void init_dm_callbacks();
477
478         void switch_template(uint8_t t);
479         void filter_stripables (ARDOUR::StripableList& strips) const;
480
481         void build_maps();
482
483         // Bundle to represent our input ports
484         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
485         // Bundle to represent our output ports
486         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
487
488         MIDI::Port *_input_port;
489         MIDI::Port *_output_port;
490         boost::shared_ptr<ARDOUR::Port> _async_in;
491         boost::shared_ptr<ARDOUR::Port> _async_out;
492
493         void connect_to_parser();
494         void handle_button_message(boost::shared_ptr<Button> button, MIDI::EventTwoBytes *);
495
496         bool check_pick_up(boost::shared_ptr<Controller> controller, boost::shared_ptr<ARDOUR::AutomationControl> ac);
497
498         void handle_midi_controller_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
499         void handle_midi_note_on_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
500         void handle_midi_note_off_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
501         void handle_midi_sysex(MIDI::Parser &, MIDI::byte *, size_t count);
502
503         bool midi_input_handler(Glib::IOCondition ioc, MIDI::Port *port);
504
505         void thread_init();
506
507         PBD::ScopedConnectionList session_connections;
508         void connect_session_signals();
509         void notify_transport_state_changed();
510         void notify_loop_state_changed();
511         void notify_parameter_changed(std::string);
512
513         /* Knob methods */
514         boost::shared_ptr<Knob> knob_by_id(KnobID id);
515         boost::shared_ptr<Knob>* knobs_by_column(uint8_t col, boost::shared_ptr<Knob>* knob_col);
516         void update_knob_led_by_strip(uint8_t n);
517         void update_knob_led_by_id(uint8_t id, LEDColor color);
518
519         void knob_sendA(uint8_t n);
520         void knob_sendB(uint8_t n);
521         void knob_pan(uint8_t n);
522
523         uint8_t dm_check_dummy(DeviceStatus ds);
524
525         void dm_fader(FaderID id);
526         uint8_t dm_check_pan_azi ();
527         void dm_pan_azi(KnobID k);
528         uint8_t dm_check_pan_width();
529         void dm_pan_width (KnobID k);
530         uint8_t dm_check_trim ();
531         void dm_trim(KnobID k);
532         uint8_t dm_mute_enabled();
533         void dm_mute_switch();
534         uint8_t dm_solo_enabled();
535         void dm_solo_switch();
536         uint8_t dm_recenable_enabled();
537         void dm_recenable_switch();
538         void dm_select_prev_strip();
539         void dm_select_next_strip();
540
541 #ifdef MIXBUS
542         void dm_mb_eq_switch();
543         void dm_mb_eq (KnobID k, bool gain, uint8_t band);
544         uint8_t dm_mb_eq_freq_enabled();
545         uint8_t dm_mb_eq_gain_enabled(uint8_t band);
546         void dm_mb_eq_shape_switch(uint8_t band);
547         uint8_t dm_mb_eq_shape_enabled(uint8_t band);
548         uint8_t dm_mb_flt_enabled();
549         void dm_mb_flt_frq (KnobID k, bool hpf);
550         void dm_mb_flt_switch();
551         void dm_mb_send_enabled(KnobID k);
552         uint8_t dm_mb_check_send_knob(KnobID k);
553         uint8_t dm_mb_check_send_button(uint8_t s);
554         void dm_mb_sends (KnobID k);
555         void dm_mb_send_switch (ButtonID b);
556         uint8_t dm_mb_comp_enabled();
557         void dm_mb_comp_switch();
558         void dm_mb_comp (KnobID k, CompParam c);
559         void dm_mb_comp_thresh (FaderID id);
560         uint8_t dm_mb_has_tapedrive();
561         void dm_mb_tapedrive (KnobID k);
562         uint8_t dm_mb_master_assign_enabled();
563         void dm_mb_master_assign_switch();
564 #endif
565
566         /* Fader methods */
567         void fader(uint8_t n);
568
569
570         /* Button methods */
571         boost::shared_ptr<TrackButton> track_button_by_range(uint8_t n, uint8_t first, uint8_t middle);
572         boost::shared_ptr<TrackButton> focus_button_by_column(uint8_t col) { return track_button_by_range(col, 41, 57) ; }
573         boost::shared_ptr<TrackButton> control_button_by_column(uint8_t col) { return track_button_by_range(col, 73, 89) ; }
574
575
576         void button_device();
577         void button_device_long_press();
578         void button_track_mode(TrackMode state);
579         void button_mute();
580         void button_mute_long_press();
581         void button_solo();
582         void button_solo_long_press();
583         void button_record();
584         void button_select_up();
585         void button_select_down();
586         void button_select_left();
587         void button_select_right();
588
589         void button_track_focus(uint8_t n);
590         void button_press_track_control(uint8_t n);
591         void button_release_track_control(uint8_t n);
592
593         boost::shared_ptr<ARDOUR::AutomationControl> get_ac_by_state(uint8_t n);
594         void update_track_focus_led(uint8_t n);
595         void update_track_control_led(uint8_t n);
596
597         void send_bank_switch_0() { send_bank_switch(0); }
598         void send_bank_switch_1() { send_bank_switch(1); }
599
600         /* stripables */
601
602         int32_t bank_start;
603         PBD::ScopedConnectionList stripable_connections;
604         boost::shared_ptr<ARDOUR::Stripable> stripable[8];
605
606         void stripables_added ();
607
608         void stripable_property_change (PBD::PropertyChange const& what_changed, uint32_t which);
609
610         void switch_bank (uint32_t base);
611
612         void solo_changed (uint32_t n) { solo_mute_rec_changed(n); }
613         void mute_changed (uint32_t n) { solo_mute_rec_changed(n); }
614         void rec_changed (uint32_t n) { solo_mute_rec_changed(n); }
615         void solo_iso_changed (uint32_t n);
616         void solo_iso_led_bank ();
617 #ifdef MIXBUS
618         void master_send_changed (uint32_t n);
619         void master_send_led_bank ();
620 #endif
621
622         void solo_mute_rec_changed (uint32_t n);
623
624         /* special Stripable */
625
626         boost::shared_ptr<ARDOUR::Stripable> master;
627
628         PBD::ScopedConnection port_reg_connection;
629         void port_registration_handler();
630
631         enum ConnectionState { InputConnected = 0x1, OutputConnected = 0x2 };
632
633         int connection_state;
634         bool connection_handler(boost::weak_ptr<ARDOUR::Port>, std::string name1,
635                         boost::weak_ptr<ARDOUR::Port>, std::string name2,
636                         bool yn);
637         PBD::ScopedConnection port_connection;
638         void connected();
639
640         /* GUI */
641
642         mutable LCXLGUI *gui;
643         void build_gui();
644
645         void stripable_selection_changed();
646
647         bool in_range_select;
648 };
649
650
651 } // namespace ArdourSurface
652
653 #endif /* __ardour_launch_control_h__ */