update pad colors when selected track colors chane
[ardour.git] / libs / surfaces / push2 / push2.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_push2_h__
20 #define __ardour_push2_h__
21
22 #include <vector>
23 #include <map>
24 #include <stack>
25 #include <list>
26 #include <set>
27
28 #include <libusb.h>
29
30 #define ABSTRACT_UI_EXPORTS
31 #include "pbd/abstract_ui.h"
32
33 #include "midi++/types.h"
34
35 #include "ardour/types.h"
36
37 #include "control_protocol/control_protocol.h"
38 #include "control_protocol/types.h"
39
40 #include "canvas/colors.h"
41
42 #include "midi_byte_array.h"
43 #include "mode.h"
44
45 namespace Pango {
46         class Layout;
47 }
48
49 namespace MIDI {
50         class Parser;
51         class Port;
52 }
53
54 namespace ARDOUR {
55         class AsyncMIDIPort;
56         class Port;
57         class MidiBuffer;
58         class MidiTrack;
59 }
60
61 namespace ArdourSurface {
62
63 struct Push2Request : public BaseUI::BaseRequestObject {
64 public:
65         Push2Request () {}
66         ~Push2Request () {}
67 };
68
69 class P2GUI;
70 class Push2Menu;
71 class Push2Layout;
72 class Push2Canvas;
73
74 class Push2 : public ARDOUR::ControlProtocol
75             , public AbstractUI<Push2Request>
76 {
77   public:
78         enum ButtonID {
79                 TapTempo,
80                 Metronome,
81                 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
82                 Setup,
83                 User,
84                 Delete,
85                 AddDevice,
86                 Device,
87                 Mix,
88                 Undo,
89                 AddTrack,
90                 Browse,
91                 Clip,
92                 Mute,
93                 Solo,
94                 Stop,
95                 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
96                 Master,
97                 Convert,
98                 DoubleLoop,
99                 Quantize,
100                 Duplicate,
101                 New,
102                 FixedLength,
103                 Automate,
104                 RecordEnable,
105                 Play,
106                 Fwd32ndT,
107                 Fwd32nd,
108                 Fwd16thT,
109                 Fwd16th,
110                 Fwd8thT,
111                 Fwd8th,
112                 Fwd4trT,
113                 Fwd4tr,
114                 Up,
115                 Right,
116                 Down,
117                 Left,
118                 Repeat,
119                 Accent,
120                 Scale,
121                 Layout,
122                 Note,
123                 Session,
124                 OctaveUp,
125                 PageRight,
126                 OctaveDown,
127                 PageLeft,
128                 Shift,
129                 Select
130         };
131
132         struct LED
133         {
134                 enum State {
135                         NoTransition,
136                         OneShot24th,
137                         OneShot16th,
138                         OneShot8th,
139                         OneShot4th,
140                         OneShot2th,
141                         Pulsing24th,
142                         Pulsing16th,
143                         Pulsing8th,
144                         Pulsing4th,
145                         Pulsing2th,
146                         Blinking24th,
147                         Blinking16th,
148                         Blinking8th,
149                         Blinking4th,
150                         Blinking2th
151                 };
152
153                 enum Colors {
154                         Black = 0,
155                         Red = 127,
156                         Green = 126,
157                         Blue = 125,
158                         DarkGray = 124,
159                         LightGray = 123,
160                         White = 122
161                 };
162
163                 LED (uint8_t e) : _extra (e), _color_index (Black), _state (NoTransition) {}
164                 virtual ~LED() {}
165
166                 uint8_t extra () const { return _extra; }
167                 uint8_t color_index () const { return _color_index; }
168                 State   state () const { return _state; }
169
170                 void set_color (uint8_t color_index);
171                 void set_state (State state);
172
173                 virtual MidiByteArray state_msg() const = 0;
174
175              protected:
176                 uint8_t _extra;
177                 uint8_t _color_index;
178                 State   _state;
179         };
180
181         struct Pad : public LED {
182                 enum WhenPressed {
183                         Nothing,
184                         FlashOn,
185                         FlashOff,
186                 };
187
188                 Pad (int xx, int yy, uint8_t ex)
189                         : LED (ex)
190                         , x (xx)
191                         , y (yy)
192                         , do_when_pressed (FlashOn)
193                         , filtered (ex)
194                         , perma_color (LED::Black)
195                 {}
196
197                 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, _color_index); }
198
199                 int coord () const { return (y * 8) + x; }
200                 int note_number() const { return extra(); }
201
202                 int x;
203                 int y;
204                 int do_when_pressed;
205                 int filtered;
206                 int perma_color;
207         };
208
209         struct Button : public LED {
210                 Button (ButtonID bb, uint8_t ex)
211                         : LED (ex)
212                         , id (bb)
213                         , press_method (&Push2::relax)
214                         , release_method (&Push2::relax)
215                         , long_press_method (&Push2::relax)
216                 {}
217
218                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
219                         : LED (ex)
220                         , id (bb)
221                         , press_method (press)
222                         , release_method (&Push2::relax)
223                         , long_press_method (&Push2::relax)
224                 {}
225
226                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
227                         : LED (ex)
228                         , id (bb)
229                         , press_method (press)
230                         , release_method (release)
231                         , long_press_method (&Push2::relax)
232                 {}
233
234                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
235                         : LED (ex)
236                         , id (bb)
237                         , press_method (press)
238                         , release_method (release)
239                         , long_press_method (long_press)
240                 {}
241
242                 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, _color_index); }
243                 int controller_number() const { return extra(); }
244
245                 ButtonID id;
246                 void (Push2::*press_method)();
247                 void (Push2::*release_method)();
248                 void (Push2::*long_press_method)();
249                 sigc::connection timeout_connection;
250         };
251
252         struct ColorButton : public Button {
253                 ColorButton (ButtonID bb, uint8_t ex)
254                         : Button (bb, ex) {}
255
256
257                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
258                         : Button (bb, ex, press) {}
259
260                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
261                         : Button (bb, ex, press, release) {}
262
263                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
264                         : Button (bb, ex, press, release, long_press) {}
265         };
266
267         struct WhiteButton : public Button {
268                 WhiteButton (ButtonID bb, uint8_t ex)
269                         : Button (bb, ex) {}
270
271                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
272                         : Button (bb, ex, press) {}
273
274                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
275                         : Button (bb, ex, press, release) {}
276
277                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
278                         : Button (bb, ex, press, release, long_press) {}
279         };
280
281         enum ColorName {
282                 DarkBackground,
283                 LightBackground,
284
285                 ParameterName,
286                 StripableName,
287                 ClockText,
288
289                 KnobArcBackground,
290                 KnobArcStart,
291                 KnobArcEnd,
292
293                 KnobLine,
294                 KnobLineShadow,
295
296                 KnobForeground,
297                 KnobBackground,
298                 KnobShadow,
299                 KnobBorder,
300         };
301
302         enum PressureMode {
303                 AfterTouch,
304                 PolyPressure,
305         };
306
307   public:
308         Push2 (ARDOUR::Session&);
309         ~Push2 ();
310
311         static bool probe ();
312         static void* request_factory (uint32_t);
313
314         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
315
316         bool has_editor () const { return true; }
317         void* get_gui () const;
318         void  tear_down_gui ();
319
320         int set_active (bool yn);
321         XMLNode& get_state();
322         int set_state (const XMLNode & node, int version);
323
324         PBD::Signal0<void> ConnectionChange;
325
326         boost::shared_ptr<ARDOUR::Port> input_port();
327         boost::shared_ptr<ARDOUR::Port> output_port();
328
329         int pad_note (int row, int col) const;
330         PBD::Signal0<void> PadChange;
331
332         void update_selection_color ();
333
334         void set_pad_scale (int root, int octave, MusicalMode::Type mode, bool inkey);
335         PBD::Signal0<void> ScaleChange;
336
337         MusicalMode::Type mode() const { return  _mode; }
338         int scale_root() const { return _scale_root; }
339         int root_octave() const { return _root_octave; }
340         bool in_key() const { return _in_key; }
341
342         Push2Layout* current_layout() const;
343         void         use_previous_layout ();
344
345         Push2Canvas* canvas() const { return _canvas; }
346
347         enum ModifierState {
348                 None = 0,
349                 ModShift = 0x1,
350                 ModSelect = 0x2,
351         };
352
353         ModifierState modifier_state() const { return _modifier_state; }
354
355         Button* button_by_id (ButtonID);
356         static std::string button_name_by_id (ButtonID);
357
358         void strip_buttons_off ();
359
360         void write (const MidiByteArray&);
361
362         uint8_t get_color_index (ArdourCanvas::Color rgba);
363         ArdourCanvas::Color get_color (ColorName);
364
365         PressureMode pressure_mode () const { return _pressure_mode; }
366         void set_pressure_mode (PressureMode);
367         PBD::Signal1<void,PressureMode> PressureModeChange;
368
369         libusb_device_handle* usb_handle() const { return handle; }
370
371   private:
372         libusb_device_handle *handle;
373         ModifierState _modifier_state;
374
375         void do_request (Push2Request*);
376         int stop ();
377         int open ();
378         int close ();
379
380         void relax () {}
381
382         /* map of Buttons by CC */
383         typedef std::map<int,Button*> CCButtonMap;
384         CCButtonMap cc_button_map;
385         /* map of Buttons by ButtonID */
386         typedef std::map<ButtonID,Button*> IDButtonMap;
387         IDButtonMap id_button_map;
388         std::set<ButtonID> buttons_down;
389         std::set<ButtonID> consumed;
390
391         bool button_long_press_timeout (ButtonID id);
392         void start_press_timeout (Button&, ButtonID);
393
394         void init_buttons (bool startup);
395         void init_touch_strip ();
396
397         /* map of Pads by note number (the "fixed" note number sent by the
398          * hardware, not the note number generated if the pad is touched)
399          */
400         typedef std::map<int,Pad*> NNPadMap;
401         NNPadMap nn_pad_map;
402
403         /* map of Pads by note number they generate (their "filtered" value)
404          */
405         typedef std::multimap<int,Pad*> FNPadMap;
406         FNPadMap fn_pad_map;
407
408         void set_button_color (ButtonID, uint8_t color_index);
409         void set_button_state (ButtonID, LED::State);
410         void set_led_color (ButtonID, uint8_t color_index);
411         void set_led_state (ButtonID, LED::State);
412
413         void build_maps ();
414
415         // Bundle to represent our input ports
416         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
417         // Bundle to represent our output ports
418         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
419
420         MIDI::Port* _input_port;
421         MIDI::Port* _output_port;
422         boost::shared_ptr<ARDOUR::Port> _async_in;
423         boost::shared_ptr<ARDOUR::Port> _async_out;
424
425         void connect_to_parser ();
426         void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
427         void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
428         void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
429         void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
430         void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
431
432         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
433
434         sigc::connection periodic_connection;
435         bool periodic ();
436
437         void thread_init ();
438
439         PBD::ScopedConnectionList session_connections;
440         void connect_session_signals ();
441         void notify_record_state_changed ();
442         void notify_transport_state_changed ();
443         void notify_loop_state_changed ();
444         void notify_parameter_changed (std::string);
445         void notify_solo_active_changed (bool);
446
447         /* Button methods */
448         void button_play ();
449         void button_recenable ();
450         void button_up ();
451         void button_down ();
452         void button_right ();
453         void button_left ();
454         void button_metronome ();
455         void button_repeat ();
456         void button_mute ();
457         void button_solo ();
458         void button_solo_long_press ();
459         void button_fixed_length ();
460         void button_new ();
461         void button_browse ();
462         void button_clip ();
463         void button_undo ();
464         void button_fwd32t ();
465         void button_fwd32 ();
466         void button_fwd16t ();
467         void button_fwd16 ();
468         void button_fwd8t ();
469         void button_fwd8 ();
470         void button_fwd4t ();
471         void button_fwd4 ();
472         void button_add_track ();
473         void button_stop ();
474         void button_master ();
475         void button_quantize ();
476         void button_duplicate ();
477         void button_shift_press ();
478         void button_shift_release ();
479         void button_shift_long_press ();
480         void button_select_press ();
481         void button_select_release ();
482         void button_select_long_press ();
483         void button_page_left ();
484         void button_page_right ();
485         void button_octave_up ();
486         void button_octave_down ();
487         void button_layout_press ();
488         void button_scale_press ();
489         void button_mix_press ();
490
491         void button_upper (uint32_t n);
492         void button_lower (uint32_t n);
493
494         void button_upper_1 () { button_upper (0); }
495         void button_upper_2 () { button_upper (1); }
496         void button_upper_3 () { button_upper (2); }
497         void button_upper_4 () { button_upper (3); }
498         void button_upper_5 () { button_upper (4); }
499         void button_upper_6 () { button_upper (5); }
500         void button_upper_7 () { button_upper (6); }
501         void button_upper_8 () { button_upper (7); }
502         void button_lower_1 () { button_lower (0); }
503         void button_lower_2 () { button_lower (1); }
504         void button_lower_3 () { button_lower (2); }
505         void button_lower_4 () { button_lower (3); }
506         void button_lower_5 () { button_lower (4); }
507         void button_lower_6 () { button_lower (5); }
508         void button_lower_7 () { button_lower (6); }
509         void button_lower_8 () { button_lower (7); }
510
511         void start_shift ();
512         void end_shift ();
513
514         /* non-strip encoders */
515
516         void other_vpot (int, int);
517         void other_vpot_touch (int, bool);
518
519         /* special Stripables */
520
521         boost::shared_ptr<ARDOUR::Stripable> master;
522         boost::shared_ptr<ARDOUR::Stripable> monitor;
523
524         sigc::connection vblank_connection;
525         bool vblank ();
526
527         void splash ();
528         ARDOUR::microseconds_t splash_start;
529
530         /* the canvas */
531
532         Push2Canvas* _canvas;
533
534         /* Layouts */
535
536         mutable Glib::Threads::Mutex layout_lock;
537         Push2Layout* _current_layout;
538         Push2Layout* _previous_layout;
539         Push2Layout* mix_layout;
540         Push2Layout* scale_layout;
541         Push2Layout* track_mix_layout;
542         Push2Layout* splash_layout;
543         void set_current_layout (Push2Layout*);
544
545         bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
546
547         boost::weak_ptr<ARDOUR::MidiTrack> current_pad_target;
548
549         PBD::ScopedConnection port_reg_connection;
550         void port_registration_handler ();
551
552         enum ConnectionState {
553                 InputConnected = 0x1,
554                 OutputConnected = 0x2
555         };
556
557         int connection_state;
558         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
559         PBD::ScopedConnection port_connection;
560         void connected ();
561
562         /* GUI */
563
564         mutable P2GUI* gui;
565         void build_gui ();
566
567         /* pad mapping */
568
569         PBD::ScopedConnection selection_connection;
570         void stripable_selection_change (ARDOUR::StripableNotificationListPtr);
571
572         MusicalMode::Type _mode;
573         int _scale_root;
574         int _root_octave;
575         bool _in_key;
576
577         int octave_shift;
578
579         bool percussion;
580         void set_percussive_mode (bool);
581
582         /* color map (device side) */
583
584         typedef std::map<ArdourCanvas::Color,uint8_t> ColorMap;
585         typedef std::stack<uint8_t> ColorMapFreeList;
586         ColorMap color_map;
587         ColorMapFreeList color_map_free_list;
588         void build_color_map ();
589
590         /* our own colors */
591
592         typedef std::map<ColorName,ArdourCanvas::Color> Colors;
593         Colors colors;
594         void fill_color_table ();
595         void reset_pad_colors ();
596
597         PressureMode _pressure_mode;
598         void request_pressure_mode ();
599
600         uint8_t selection_color;
601         uint8_t contrast_color;
602 };
603
604 } /* namespace */
605
606 #endif /* __ardour_push2_h__ */