use right-side buttons to goto_nth_marker()
[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 }
57
58 namespace ArdourSurface {
59
60 struct Push2Request : public BaseUI::BaseRequestObject {
61 public:
62         Push2Request () {}
63         ~Push2Request () {}
64 };
65
66 class Push2 : public ARDOUR::ControlProtocol
67             , public AbstractUI<Push2Request>
68 {
69    public:
70         Push2 (ARDOUR::Session&);
71         ~Push2 ();
72
73         static bool probe ();
74         static void* request_factory (uint32_t);
75
76         int set_active (bool yn);
77         XMLNode& get_state();
78         int set_state (const XMLNode & node, int version);
79
80    private:
81         libusb_device_handle *handle;
82         uint8_t   frame_header[16];
83         uint16_t* device_frame_buffer;
84         int  device_buffer;
85         Cairo::RefPtr<Cairo::ImageSurface> frame_buffer;
86         sigc::connection vblank_connection;
87         sigc::connection periodic_connection;
88
89         enum ModifierState {
90                 None = 0,
91                 ModShift = 0x1,
92         };
93
94         ModifierState modifier_state;
95
96         static const int cols;
97         static const int rows;
98         static const int pixels_per_row;
99
100         void do_request (Push2Request*);
101         int stop ();
102         int open ();
103         int close ();
104         bool redraw ();
105         int bitblt_to_device_frame_buffer ();
106         bool vblank ();
107
108         enum ButtonID {
109                 TapTempo,
110                 Metronome,
111                 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
112                 Setup,
113                 User,
114                 Delete,
115                 AddDevice,
116                 Device,
117                 Mix,
118                 Undo,
119                 AddTrack,
120                 Browse,
121                 Clip,
122                 Mute,
123                 Solo,
124                 Stop,
125                 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
126                 Master,
127                 Convert,
128                 DoubleLoop,
129                 Quantize,
130                 Duplicate,
131                 New,
132                 FixedLength,
133                 Automate,
134                 RecordEnable,
135                 Play,
136                 Fwd32ndT,
137                 Fwd32nd,
138                 Fwd16thT,
139                 Fwd16th,
140                 Fwd8thT,
141                 Fwd8th,
142                 Fwd4trT,
143                 Fwd4tr,
144                 Up,
145                 Right,
146                 Down,
147                 Left,
148                 Repeat,
149                 Accent,
150                 Scale,
151                 Layout,
152                 Note,
153                 Session,
154                 OctaveUp,
155                 PageRight,
156                 OctaveDown,
157                 PageLeft,
158                 Shift,
159                 Select
160         };
161
162         struct LED
163         {
164                 enum State {
165                         NoTransition,
166                         OneShot24th,
167                         OneShot16th,
168                         OneShot8th,
169                         OneShot4th,
170                         OneShot2th,
171                         Pulsing24th,
172                         Pulsing16th,
173                         Pulsing8th,
174                         Pulsing4th,
175                         Pulsing2th,
176                         Blinking24th,
177                         Blinking16th,
178                         Blinking8th,
179                         Blinking4th,
180                         Blinking2th
181                 };
182
183                 enum Colors {
184                         Black = 0,
185                         Red = 127,
186                         Green = 126,
187                         Blue = 125,
188                         DarkGray = 124,
189                         LightGray = 123,
190                         White = 122
191                 };
192
193                 LED (uint8_t e) : _extra (e), _color_index (0), _state (NoTransition) {}
194                 virtual ~LED() {}
195
196                 uint8_t extra () const { return _extra; }
197                 uint8_t color_index () const { return _color_index; }
198                 State   state () const { return _state; }
199
200                 void set_color (uint8_t color_index);
201                 void set_state (State state);
202
203                 virtual MidiByteArray state_msg() const = 0;
204
205              protected:
206                 uint8_t _extra;
207                 uint8_t _color_index;
208                 State   _state;
209         };
210
211         struct Pad : public LED {
212                 Pad (int xx, int yy, uint8_t ex)
213                         : LED (ex)
214                         , x (xx)
215                         , y (yy) {}
216
217                 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, _color_index); }
218
219                 int coord () const { return (y * 8) + x; }
220                 int note_number() const { return extra(); }
221
222                 int x;
223                 int y;
224         };
225
226         struct Button : public LED {
227                 Button (ButtonID bb, uint8_t ex)
228                         : LED (ex)
229                         , id (bb)
230                         , press_method (&Push2::relax)
231                         , release_method (&Push2::relax)
232                 {}
233
234                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
235                         : LED (ex)
236                         , id (bb)
237                         , press_method (press)
238                         , release_method (&Push2::relax)
239                 {}
240
241                 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
242                         : LED (ex)
243                         , id (bb)
244                         , press_method (press)
245                         , release_method (release)
246                 {}
247
248                 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, _color_index); }
249                 int controller_number() const { return extra(); }
250
251                 ButtonID id;
252                 void (Push2::*press_method)();
253                 void (Push2::*release_method)();
254         };
255
256         struct ColorButton : public Button {
257                 ColorButton (ButtonID bb, uint8_t ex)
258                         : Button (bb, ex) {}
259
260
261                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
262                         : Button (bb, ex, press) {}
263
264                 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
265                         : Button (bb, ex, press, release) {}
266         };
267
268         struct WhiteButton : public Button {
269                 WhiteButton (ButtonID bb, uint8_t ex)
270                         : Button (bb, ex) {}
271
272                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
273                         : Button (bb, ex, press) {}
274
275                 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
276                         : Button (bb, ex, press, release) {}
277         };
278
279         void relax () {}
280
281         /* map of Buttons by CC */
282         typedef std::map<int,Button*> CCButtonMap;
283         CCButtonMap cc_button_map;
284         /* map of Buttons by ButtonID */
285         typedef std::map<ButtonID,Button*> IDButtonMap;
286         IDButtonMap id_button_map;
287
288         void init_buttons ();
289
290         /* map of Pads by note number */
291         typedef std::map<int,Pad*> NNPadMap;
292         NNPadMap nn_pad_map;
293         /* map of Pads by coordinate
294          *
295          * coord = row * 64 + column;
296          *
297          * rows start at top left
298          */
299         typedef std::map<int,Pad*> CoordPadMap;
300         CoordPadMap coord_pad_map;
301
302         void set_button_color (ButtonID, uint8_t color_index);
303         void set_button_state (ButtonID, LED::State);
304         void set_led_color (ButtonID, uint8_t color_index);
305         void set_led_state (ButtonID, LED::State);
306
307         void build_maps ();
308
309         MIDI::Port* _input_port;
310         MIDI::Port* _output_port;
311         boost::shared_ptr<ARDOUR::Port> _async_in;
312         boost::shared_ptr<ARDOUR::Port> _async_out;
313
314         void connect_to_parser ();
315         void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
316         void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
317         void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
318         void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
319         void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
320
321         void write (const MidiByteArray&);
322         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
323         bool periodic ();
324
325         void thread_init ();
326
327         PBD::ScopedConnectionList session_connections;
328         void connect_session_signals ();
329         void notify_record_state_changed ();
330         void notify_transport_state_changed ();
331         void notify_loop_state_changed ();
332         void notify_parameter_changed (std::string);
333         void notify_solo_active_changed (bool);
334
335         /* Button methods */
336         void button_play ();
337         void button_recenable ();
338         void button_up ();
339         void button_down ();
340         void button_right ();
341         void button_left ();
342         void button_metronome ();
343         void button_repeat ();
344         void button_solo ();
345         void button_fixed_length ();
346         void button_new ();
347         void button_shift_press ();
348         void button_shift_release ();
349         void button_browse ();
350         void button_clip ();
351         void button_upper (uint32_t n);
352         void button_lower (uint32_t n);
353         void button_upper_1 () { button_upper (0); }
354         void button_upper_2 () { button_upper (1); }
355         void button_upper_3 () { button_upper (2); }
356         void button_upper_4 () { button_upper (3); }
357         void button_upper_5 () { button_upper (4); }
358         void button_upper_6 () { button_upper (5); }
359         void button_upper_7 () { button_upper (6); }
360         void button_upper_8 () { button_upper (7); }
361         void button_lower_1 () { button_lower (0); }
362         void button_lower_2 () { button_lower (1); }
363         void button_lower_3 () { button_lower (2); }
364         void button_lower_4 () { button_lower (3); }
365         void button_lower_5 () { button_lower (4); }
366         void button_lower_6 () { button_lower (5); }
367         void button_lower_7 () { button_lower (6); }
368         void button_lower_8 () { button_lower (7); }
369         void button_undo ();
370         void button_fwd32t ();
371         void button_fwd32 ();
372         void button_fwd16t ();
373         void button_fwd16 ();
374         void button_fwd8t ();
375         void button_fwd8 ();
376         void button_fwd4t ();
377         void button_fwd4 ();
378
379         /* widgets */
380
381         Cairo::RefPtr<Cairo::Context> context;
382         Glib::RefPtr<Pango::Layout> tc_clock_layout;
383         Glib::RefPtr<Pango::Layout> bbt_clock_layout;
384         Glib::RefPtr<Pango::Layout> upper_layout[8];
385         Glib::RefPtr<Pango::Layout> mid_layout[8];
386         Glib::RefPtr<Pango::Layout> lower_layout[8];
387
388         /* stripables */
389
390         int32_t bank_start;
391         PBD::ScopedConnectionList stripable_connections;
392         boost::shared_ptr<ARDOUR::Stripable> stripable[8];
393         boost::shared_ptr<ARDOUR::Stripable> master;
394         boost::shared_ptr<ARDOUR::Stripable> monitor;
395
396         void solo_change (int);
397         void mute_change (int);
398
399         void switch_bank (uint32_t base);
400 };
401
402
403 } /* namespace */
404
405 #endif /* __ardour_push2_h__ */