47e4ab051e69e9598e951b66b26477ea94dc6481
[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 set_pad_scale (int root, int octave, MusicalMode::Type mode, bool inkey);
333         PBD::Signal0<void> ScaleChange;
334
335         MusicalMode::Type mode() const { return  _mode; }
336         int scale_root() const { return _scale_root; }
337         int root_octave() const { return _root_octave; }
338         bool in_key() const { return _in_key; }
339
340         Push2Layout* current_layout() const;
341         void         use_previous_layout ();
342
343         Push2Canvas* canvas() const { return _canvas; }
344
345         enum ModifierState {
346                 None = 0,
347                 ModShift = 0x1,
348                 ModSelect = 0x2,
349         };
350
351         ModifierState modifier_state() const { return _modifier_state; }
352
353         Button* button_by_id (ButtonID);
354         static std::string button_name_by_id (ButtonID);
355
356         void strip_buttons_off ();
357
358         void write (const MidiByteArray&);
359
360         uint8_t get_color_index (ArdourCanvas::Color rgba);
361         ArdourCanvas::Color get_color (ColorName);
362
363         PressureMode pressure_mode () const { return _pressure_mode; }
364         void set_pressure_mode (PressureMode);
365         PBD::Signal1<void,PressureMode> PressureModeChange;
366
367         libusb_device_handle* usb_handle() const { return handle; }
368
369   private:
370         libusb_device_handle *handle;
371         ModifierState _modifier_state;
372
373         void do_request (Push2Request*);
374         int stop ();
375         int open ();
376         int close ();
377
378         void relax () {}
379
380         /* map of Buttons by CC */
381         typedef std::map<int,Button*> CCButtonMap;
382         CCButtonMap cc_button_map;
383         /* map of Buttons by ButtonID */
384         typedef std::map<ButtonID,Button*> IDButtonMap;
385         IDButtonMap id_button_map;
386         std::set<ButtonID> buttons_down;
387         std::set<ButtonID> consumed;
388
389         bool button_long_press_timeout (ButtonID id);
390         void start_press_timeout (Button&, ButtonID);
391
392         void init_buttons (bool startup);
393         void init_touch_strip ();
394
395         /* map of Pads by note number (the "fixed" note number sent by the
396          * hardware, not the note number generated if the pad is touched)
397          */
398         typedef std::map<int,Pad*> NNPadMap;
399         NNPadMap nn_pad_map;
400
401         /* map of Pads by note number they generate (their "filtered" value)
402          */
403         typedef std::multimap<int,Pad*> FNPadMap;
404         FNPadMap fn_pad_map;
405
406         void set_button_color (ButtonID, uint8_t color_index);
407         void set_button_state (ButtonID, LED::State);
408         void set_led_color (ButtonID, uint8_t color_index);
409         void set_led_state (ButtonID, LED::State);
410
411         void build_maps ();
412
413         // Bundle to represent our input ports
414         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
415         // Bundle to represent our output ports
416         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
417
418         MIDI::Port* _input_port;
419         MIDI::Port* _output_port;
420         boost::shared_ptr<ARDOUR::Port> _async_in;
421         boost::shared_ptr<ARDOUR::Port> _async_out;
422
423         void connect_to_parser ();
424         void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
425         void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
426         void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
427         void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
428         void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
429
430         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
431
432         sigc::connection periodic_connection;
433         bool periodic ();
434
435         void thread_init ();
436
437         PBD::ScopedConnectionList session_connections;
438         void connect_session_signals ();
439         void notify_record_state_changed ();
440         void notify_transport_state_changed ();
441         void notify_loop_state_changed ();
442         void notify_parameter_changed (std::string);
443         void notify_solo_active_changed (bool);
444
445         /* Button methods */
446         void button_play ();
447         void button_recenable ();
448         void button_up ();
449         void button_down ();
450         void button_right ();
451         void button_left ();
452         void button_metronome ();
453         void button_repeat ();
454         void button_mute ();
455         void button_solo ();
456         void button_solo_long_press ();
457         void button_fixed_length ();
458         void button_new ();
459         void button_browse ();
460         void button_clip ();
461         void button_undo ();
462         void button_fwd32t ();
463         void button_fwd32 ();
464         void button_fwd16t ();
465         void button_fwd16 ();
466         void button_fwd8t ();
467         void button_fwd8 ();
468         void button_fwd4t ();
469         void button_fwd4 ();
470         void button_add_track ();
471         void button_stop ();
472         void button_master ();
473         void button_quantize ();
474         void button_duplicate ();
475         void button_shift_press ();
476         void button_shift_release ();
477         void button_shift_long_press ();
478         void button_select_press ();
479         void button_select_release ();
480         void button_select_long_press ();
481         void button_page_left ();
482         void button_page_right ();
483         void button_octave_up ();
484         void button_octave_down ();
485         void button_layout_press ();
486         void button_scale_press ();
487         void button_mix_press ();
488
489         void button_upper (uint32_t n);
490         void button_lower (uint32_t n);
491
492         void button_upper_1 () { button_upper (0); }
493         void button_upper_2 () { button_upper (1); }
494         void button_upper_3 () { button_upper (2); }
495         void button_upper_4 () { button_upper (3); }
496         void button_upper_5 () { button_upper (4); }
497         void button_upper_6 () { button_upper (5); }
498         void button_upper_7 () { button_upper (6); }
499         void button_upper_8 () { button_upper (7); }
500         void button_lower_1 () { button_lower (0); }
501         void button_lower_2 () { button_lower (1); }
502         void button_lower_3 () { button_lower (2); }
503         void button_lower_4 () { button_lower (3); }
504         void button_lower_5 () { button_lower (4); }
505         void button_lower_6 () { button_lower (5); }
506         void button_lower_7 () { button_lower (6); }
507         void button_lower_8 () { button_lower (7); }
508
509         void start_shift ();
510         void end_shift ();
511
512         /* non-strip encoders */
513
514         void other_vpot (int, int);
515         void other_vpot_touch (int, bool);
516
517         /* special Stripables */
518
519         boost::shared_ptr<ARDOUR::Stripable> master;
520         boost::shared_ptr<ARDOUR::Stripable> monitor;
521
522         sigc::connection vblank_connection;
523         bool vblank ();
524
525         void splash ();
526         ARDOUR::microseconds_t splash_start;
527
528         /* the canvas */
529
530         Push2Canvas* _canvas;
531
532         /* Layouts */
533
534         mutable Glib::Threads::Mutex layout_lock;
535         Push2Layout* _current_layout;
536         Push2Layout* _previous_layout;
537         Push2Layout* mix_layout;
538         Push2Layout* scale_layout;
539         Push2Layout* track_mix_layout;
540         Push2Layout* splash_layout;
541         void set_current_layout (Push2Layout*);
542
543         bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
544
545         boost::weak_ptr<ARDOUR::MidiTrack> current_pad_target;
546
547         PBD::ScopedConnection port_reg_connection;
548         void port_registration_handler ();
549
550         enum ConnectionState {
551                 InputConnected = 0x1,
552                 OutputConnected = 0x2
553         };
554
555         int connection_state;
556         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
557         PBD::ScopedConnection port_connection;
558         void connected ();
559
560         /* GUI */
561
562         mutable P2GUI* gui;
563         void build_gui ();
564
565         /* pad mapping */
566
567         PBD::ScopedConnection selection_connection;
568         void stripable_selection_change (ARDOUR::StripableNotificationListPtr);
569
570         MusicalMode::Type _mode;
571         int _scale_root;
572         int _root_octave;
573         bool _in_key;
574
575         int octave_shift;
576
577         bool percussion;
578         void set_percussive_mode (bool);
579
580         /* color map (device side) */
581
582         typedef std::map<ArdourCanvas::Color,uint8_t> ColorMap;
583         typedef std::stack<uint8_t> ColorMapFreeList;
584         ColorMap color_map;
585         ColorMapFreeList color_map_free_list;
586         void build_color_map ();
587
588         /* our own colors */
589
590         typedef std::map<ColorName,ArdourCanvas::Color> Colors;
591         Colors colors;
592         void fill_color_table ();
593         void reset_pad_colors ();
594
595         PressureMode _pressure_mode;
596         void request_pressure_mode ();
597
598         uint8_t selection_color;
599         uint8_t contrast_color;
600 };
601
602 } /* namespace */
603
604 #endif /* __ardour_push2_h__ */