push2: update GUI pad display when octave shift is used, or pad map is changed
[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 <list>
25 #include <set>
26
27 #include <libusb.h>
28
29 #include <cairomm/refptr.h>
30
31 #define ABSTRACT_UI_EXPORTS
32 #include "pbd/abstract_ui.h"
33 #include "midi++/types.h"
34 #include "ardour/types.h"
35 #include "control_protocol/control_protocol.h"
36
37 #include "midi_byte_array.h"
38
39 namespace Cairo {
40         class ImageSurface;
41         class Context;
42 }
43
44 namespace Pango {
45         class Layout;
46 }
47
48 namespace MIDI {
49         class Parser;
50         class Port;
51 }
52
53 namespace ARDOUR {
54         class AsyncMIDIPort;
55         class Port;
56         class MidiBuffer;
57 }
58
59 namespace ArdourSurface {
60
61 struct Push2Request : public BaseUI::BaseRequestObject {
62 public:
63         Push2Request () {}
64         ~Push2Request () {}
65 };
66
67 class P2GUI;
68
69 class Push2 : public ARDOUR::ControlProtocol
70             , public AbstractUI<Push2Request>
71 {
72    public:
73         Push2 (ARDOUR::Session&);
74         ~Push2 ();
75
76         static bool probe ();
77         static void* request_factory (uint32_t);
78
79         bool has_editor () const { return true; }
80         void* get_gui () const;
81         void  tear_down_gui ();
82
83         int set_active (bool yn);
84         XMLNode& get_state();
85         int set_state (const XMLNode & node, int version);
86
87         PBD::Signal0<void> ConnectionChange;
88
89         boost::shared_ptr<ARDOUR::Port> input_port();
90         boost::shared_ptr<ARDOUR::Port> output_port();
91
92         uint8_t pad_note (int row, int col) const;
93         PBD::Signal0<void> PadChange;
94
95    private:
96         libusb_device_handle *handle;
97         uint8_t   frame_header[16];
98         uint16_t* device_frame_buffer;
99         int  device_buffer;
100         Cairo::RefPtr<Cairo::ImageSurface> frame_buffer;
101         sigc::connection vblank_connection;
102         sigc::connection periodic_connection;
103
104         enum ModifierState {
105                 None = 0,
106                 ModShift = 0x1,
107                 ModSelect = 0x2,
108         };
109
110         ModifierState modifier_state;
111
112         static const int cols;
113         static const int rows;
114         static const int pixels_per_row;
115
116         void do_request (Push2Request*);
117         int stop ();
118         int open ();
119         int close ();
120         bool redraw ();
121         int blit_to_device_frame_buffer ();
122         bool vblank ();
123
124         enum ButtonID {
125                 TapTempo,
126                 Metronome,
127                 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
128                 Setup,
129                 User,
130                 Delete,
131                 AddDevice,
132                 Device,
133                 Mix,
134                 Undo,
135                 AddTrack,
136                 Browse,
137                 Clip,
138                 Mute,
139                 Solo,
140                 Stop,
141                 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
142                 Master,
143                 Convert,
144                 DoubleLoop,
145                 Quantize,
146                 Duplicate,
147                 New,
148                 FixedLength,
149                 Automate,
150                 RecordEnable,
151                 Play,
152                 Fwd32ndT,
153                 Fwd32nd,
154                 Fwd16thT,
155                 Fwd16th,
156                 Fwd8thT,
157                 Fwd8th,
158                 Fwd4trT,
159                 Fwd4tr,
160                 Up,
161                 Right,
162                 Down,
163                 Left,
164                 Repeat,
165                 Accent,
166                 Scale,
167                 Layout,
168                 Note,
169                 Session,
170                 OctaveUp,
171                 PageRight,
172                 OctaveDown,
173                 PageLeft,
174                 Shift,
175                 Select
176         };
177
178         struct LED
179         {
180                 enum State {
181                         NoTransition,
182                         OneShot24th,
183                         OneShot16th,
184                         OneShot8th,
185                         OneShot4th,
186                         OneShot2th,
187                         Pulsing24th,
188                         Pulsing16th,
189                         Pulsing8th,
190                         Pulsing4th,
191                         Pulsing2th,
192                         Blinking24th,
193                         Blinking16th,
194                         Blinking8th,
195                         Blinking4th,
196                         Blinking2th
197                 };
198
199                 enum Colors {
200                         Black = 0,
201                         Red = 127,
202                         Green = 126,
203                         Blue = 125,
204                         DarkGray = 124,
205                         LightGray = 123,
206                         White = 122
207                 };
208
209                 LED (uint8_t e) : _extra (e), _color_index (0), _state (NoTransition) {}
210                 virtual ~LED() {}
211
212                 uint8_t extra () const { return _extra; }
213                 uint8_t color_index () const { return _color_index; }
214                 State   state () const { return _state; }
215
216                 void set_color (uint8_t color_index);
217                 void set_state (State state);
218
219                 virtual MidiByteArray state_msg() const = 0;
220
221              protected:
222                 uint8_t _extra;
223                 uint8_t _color_index;
224                 State   _state;
225         };
226
227         struct Pad : public LED {
228                 Pad (int xx, int yy, uint8_t ex)
229                         : LED (ex)
230                         , x (xx)
231                         , y (yy) {}
232
233                 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, _color_index); }
234
235                 int coord () const { return (y * 8) + x; }
236                 int note_number() const { return extra(); }
237
238                 int x;
239                 int y;
240         };
241
242         struct Button : public LED {
243                 Button (ButtonID bb, uint8_t ex)
244                         : LED (ex)
245                         , id (bb)
246                         , press_method (&Push2::relax)
247                         , release_method (&Push2::relax)
248                         , long_press_method (&Push2::relax)
249                 {}
250
251                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
252                         : LED (ex)
253                         , id (bb)
254                         , press_method (press)
255                         , release_method (&Push2::relax)
256                         , long_press_method (&Push2::relax)
257                 {}
258
259                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
260                         : LED (ex)
261                         , id (bb)
262                         , press_method (press)
263                         , release_method (release)
264                         , long_press_method (&Push2::relax)
265                 {}
266
267                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
268                         : LED (ex)
269                         , id (bb)
270                         , press_method (press)
271                         , release_method (release)
272                         , long_press_method (long_press)
273                 {}
274
275                 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, _color_index); }
276                 int controller_number() const { return extra(); }
277
278                 ButtonID id;
279                 void (Push2::*press_method)();
280                 void (Push2::*release_method)();
281                 void (Push2::*long_press_method)();
282                 sigc::connection timeout_connection;
283         };
284
285         struct ColorButton : public Button {
286                 ColorButton (ButtonID bb, uint8_t ex)
287                         : Button (bb, ex) {}
288
289
290                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
291                         : Button (bb, ex, press) {}
292
293                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
294                         : Button (bb, ex, press, release) {}
295
296                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
297                         : Button (bb, ex, press, release, long_press) {}
298         };
299
300         struct WhiteButton : public Button {
301                 WhiteButton (ButtonID bb, uint8_t ex)
302                         : Button (bb, ex) {}
303
304                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
305                         : Button (bb, ex, press) {}
306
307                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
308                         : Button (bb, ex, press, release) {}
309
310                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
311                         : Button (bb, ex, press, release, long_press) {}
312         };
313
314         void relax () {}
315
316         /* map of Buttons by CC */
317         typedef std::map<int,Button*> CCButtonMap;
318         CCButtonMap cc_button_map;
319         /* map of Buttons by ButtonID */
320         typedef std::map<ButtonID,Button*> IDButtonMap;
321         IDButtonMap id_button_map;
322         std::set<ButtonID> buttons_down;
323         std::set<ButtonID> consumed;
324
325         bool button_long_press_timeout (ButtonID id);
326         void start_press_timeout (Button&, ButtonID);
327
328         void init_buttons (bool startup);
329         void init_touch_strip ();
330
331         /* map of Pads by note number */
332         typedef std::map<int,Pad*> NNPadMap;
333         NNPadMap nn_pad_map;
334         /* map of Pads by coordinate
335          *
336          * coord = row * 64 + column;
337          *
338          * rows start at top left
339          */
340         typedef std::map<int,Pad*> CoordPadMap;
341         CoordPadMap coord_pad_map;
342
343         void set_button_color (ButtonID, uint8_t color_index);
344         void set_button_state (ButtonID, LED::State);
345         void set_led_color (ButtonID, uint8_t color_index);
346         void set_led_state (ButtonID, LED::State);
347
348         void build_maps ();
349
350         MIDI::Port* _input_port;
351         MIDI::Port* _output_port;
352         boost::shared_ptr<ARDOUR::Port> _async_in;
353         boost::shared_ptr<ARDOUR::Port> _async_out;
354
355         void connect_to_parser ();
356         void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
357         void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
358         void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
359         void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
360         void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
361
362         void write (const MidiByteArray&);
363         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
364         bool periodic ();
365
366         void thread_init ();
367
368         PBD::ScopedConnectionList session_connections;
369         void connect_session_signals ();
370         void notify_record_state_changed ();
371         void notify_transport_state_changed ();
372         void notify_loop_state_changed ();
373         void notify_parameter_changed (std::string);
374         void notify_solo_active_changed (bool);
375
376         /* Button methods */
377         void button_play ();
378         void button_recenable ();
379         void button_up ();
380         void button_down ();
381         void button_right ();
382         void button_left ();
383         void button_metronome ();
384         void button_repeat ();
385         void button_solo ();
386         void button_fixed_length ();
387         void button_new ();
388         void button_browse ();
389         void button_clip ();
390         void button_upper (uint32_t n);
391         void button_lower (uint32_t n);
392         void button_upper_1 () { button_upper (0); }
393         void button_upper_2 () { button_upper (1); }
394         void button_upper_3 () { button_upper (2); }
395         void button_upper_4 () { button_upper (3); }
396         void button_upper_5 () { button_upper (4); }
397         void button_upper_6 () { button_upper (5); }
398         void button_upper_7 () { button_upper (6); }
399         void button_upper_8 () { button_upper (7); }
400         void button_lower_1 () { button_lower (0); }
401         void button_lower_2 () { button_lower (1); }
402         void button_lower_3 () { button_lower (2); }
403         void button_lower_4 () { button_lower (3); }
404         void button_lower_5 () { button_lower (4); }
405         void button_lower_6 () { button_lower (5); }
406         void button_lower_7 () { button_lower (6); }
407         void button_lower_8 () { button_lower (7); }
408         void button_undo ();
409         void button_fwd32t ();
410         void button_fwd32 ();
411         void button_fwd16t ();
412         void button_fwd16 ();
413         void button_fwd8t ();
414         void button_fwd8 ();
415         void button_fwd4t ();
416         void button_fwd4 ();
417         void button_add_track ();
418         void button_stop ();
419         void button_shift_press ();
420         void button_shift_release ();
421         void button_shift_long_press ();
422         void button_select_press ();
423         void button_select_release ();
424         void button_select_long_press ();
425         void button_page_left ();
426         void button_page_right ();
427         void button_octave_up ();
428         void button_octave_down ();
429
430         void start_shift ();
431         void end_shift ();
432         void start_select ();
433         void end_select ();
434
435         /* encoders */
436
437         void strip_vpot (int, int);
438         void other_vpot (int, int);
439         void strip_vpot_touch (int, bool);
440         void other_vpot_touch (int, bool);
441
442         /* widgets */
443
444         Cairo::RefPtr<Cairo::Context> context;
445         Glib::RefPtr<Pango::Layout> tc_clock_layout;
446         Glib::RefPtr<Pango::Layout> bbt_clock_layout;
447         Glib::RefPtr<Pango::Layout> upper_layout[8];
448         Glib::RefPtr<Pango::Layout> mid_layout[8];
449         Glib::RefPtr<Pango::Layout> lower_layout[8];
450
451         void splash ();
452         ARDOUR::microseconds_t splash_start;
453
454         /* stripables */
455
456         int32_t bank_start;
457         PBD::ScopedConnectionList stripable_connections;
458         boost::shared_ptr<ARDOUR::Stripable> stripable[8];
459         boost::shared_ptr<ARDOUR::Stripable> master;
460         boost::shared_ptr<ARDOUR::Stripable> monitor;
461
462         void solo_change (int);
463         void mute_change (int);
464         void stripable_property_change (PBD::PropertyChange const& what_changed, int which);
465
466         void switch_bank (uint32_t base);
467
468         bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
469
470         boost::weak_ptr<ARDOUR::Stripable> first_selected_stripable;
471
472         PBD::ScopedConnection port_reg_connection;
473         void port_registration_handler ();
474
475         enum ConnectionState {
476                 InputConnected = 0x1,
477                 OutputConnected = 0x2
478         };
479
480         int connection_state;
481         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
482         PBD::ScopedConnection port_connection;
483
484         /* GUI */
485
486         mutable P2GUI* gui;
487         void build_gui ();
488
489         /* pad mapping */
490
491         uint8_t pad_table[8][8];
492         void build_pad_table();
493         int octave_shift;
494 };
495
496
497 } /* namespace */
498
499 #endif /* __ardour_push2_h__ */