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