e2da7e7ff21d78e915a6e4ac74282804fbbf3013
[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_shift_press ();
474         void button_shift_release ();
475         void button_shift_long_press ();
476         void button_select_press ();
477         void button_select_release ();
478         void button_select_long_press ();
479         void button_page_left ();
480         void button_page_right ();
481         void button_octave_up ();
482         void button_octave_down ();
483         void button_layout_press ();
484         void button_scale_press ();
485         void button_mix_press ();
486
487         void button_upper (uint32_t n);
488         void button_lower (uint32_t n);
489
490         void button_upper_1 () { button_upper (0); }
491         void button_upper_2 () { button_upper (1); }
492         void button_upper_3 () { button_upper (2); }
493         void button_upper_4 () { button_upper (3); }
494         void button_upper_5 () { button_upper (4); }
495         void button_upper_6 () { button_upper (5); }
496         void button_upper_7 () { button_upper (6); }
497         void button_upper_8 () { button_upper (7); }
498         void button_lower_1 () { button_lower (0); }
499         void button_lower_2 () { button_lower (1); }
500         void button_lower_3 () { button_lower (2); }
501         void button_lower_4 () { button_lower (3); }
502         void button_lower_5 () { button_lower (4); }
503         void button_lower_6 () { button_lower (5); }
504         void button_lower_7 () { button_lower (6); }
505         void button_lower_8 () { button_lower (7); }
506
507         void start_shift ();
508         void end_shift ();
509
510         /* non-strip encoders */
511
512         void other_vpot (int, int);
513         void other_vpot_touch (int, bool);
514
515         /* special Stripables */
516
517         boost::shared_ptr<ARDOUR::Stripable> master;
518         boost::shared_ptr<ARDOUR::Stripable> monitor;
519
520         sigc::connection vblank_connection;
521         bool vblank ();
522
523         void splash ();
524         ARDOUR::microseconds_t splash_start;
525
526         /* the canvas */
527
528         Push2Canvas* _canvas;
529
530         /* Layouts */
531
532         mutable Glib::Threads::Mutex layout_lock;
533         Push2Layout* _current_layout;
534         Push2Layout* _previous_layout;
535         Push2Layout* mix_layout;
536         Push2Layout* scale_layout;
537         Push2Layout* track_mix_layout;
538         Push2Layout* splash_layout;
539         void set_current_layout (Push2Layout*);
540
541         bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
542
543         boost::weak_ptr<ARDOUR::MidiTrack> current_pad_target;
544
545         PBD::ScopedConnection port_reg_connection;
546         void port_registration_handler ();
547
548         enum ConnectionState {
549                 InputConnected = 0x1,
550                 OutputConnected = 0x2
551         };
552
553         int connection_state;
554         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
555         PBD::ScopedConnection port_connection;
556         void connected ();
557
558         /* GUI */
559
560         mutable P2GUI* gui;
561         void build_gui ();
562
563         /* pad mapping */
564
565         PBD::ScopedConnection selection_connection;
566         void stripable_selection_change (ARDOUR::StripableNotificationListPtr);
567
568         MusicalMode::Type _mode;
569         int _scale_root;
570         int _root_octave;
571         bool _in_key;
572
573         int octave_shift;
574
575         bool percussion;
576         void set_percussive_mode (bool);
577
578         /* color map (device side) */
579
580         typedef std::map<ArdourCanvas::Color,uint8_t> ColorMap;
581         typedef std::stack<uint8_t> ColorMapFreeList;
582         ColorMap color_map;
583         ColorMapFreeList color_map_free_list;
584         void build_color_map ();
585
586         /* our own colors */
587
588         typedef std::map<ColorName,ArdourCanvas::Color> Colors;
589         Colors colors;
590         void fill_color_table ();
591         void reset_pad_colors ();
592
593         PressureMode _pressure_mode;
594         void request_pressure_mode ();
595
596         uint8_t selection_color;
597         uint8_t contrast_color;
598 };
599
600 } /* namespace */
601
602 #endif /* __ardour_push2_h__ */