2 Copyright (C) 2016 Paul Davis
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.
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.
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.
19 #ifndef __ardour_push2_h__
20 #define __ardour_push2_h__
29 #include <cairomm/refptr.h>
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"
37 #include "midi_byte_array.h"
58 namespace ArdourSurface {
60 struct Push2Request : public BaseUI::BaseRequestObject {
66 class Push2 : public ARDOUR::ControlProtocol
67 , public AbstractUI<Push2Request>
70 Push2 (ARDOUR::Session&);
74 static void* request_factory (uint32_t);
76 int set_active (bool yn);
78 int set_state (const XMLNode & node, int version);
81 libusb_device_handle *handle;
82 uint8_t frame_header[16];
83 uint16_t* device_frame_buffer;
85 Cairo::RefPtr<Cairo::ImageSurface> frame_buffer;
86 sigc::connection vblank_connection;
87 sigc::connection periodic_connection;
94 ModifierState modifier_state;
96 static const int cols;
97 static const int rows;
98 static const int pixels_per_row;
100 void do_request (Push2Request*);
105 int bitblt_to_device_frame_buffer ();
111 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
125 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
193 LED (uint8_t e) : _extra (e), _color_index (0), _state (NoTransition) {}
196 uint8_t extra () const { return _extra; }
197 uint8_t color_index () const { return _color_index; }
198 State state () const { return _state; }
200 void set_color (uint8_t color_index);
201 void set_state (State state);
203 virtual MidiByteArray state_msg() const = 0;
207 uint8_t _color_index;
211 struct Pad : public LED {
212 Pad (int xx, int yy, uint8_t ex)
217 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, _color_index); }
219 int coord () const { return (y * 8) + x; }
220 int note_number() const { return extra(); }
226 struct Button : public LED {
227 Button (ButtonID bb, uint8_t ex)
230 , press_method (&Push2::relax)
231 , release_method (&Push2::relax)
234 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
237 , press_method (press)
238 , release_method (&Push2::relax)
241 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
244 , press_method (press)
245 , release_method (release)
248 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, _color_index); }
249 int controller_number() const { return extra(); }
252 void (Push2::*press_method)();
253 void (Push2::*release_method)();
256 struct ColorButton : public Button {
257 ColorButton (ButtonID bb, uint8_t ex)
261 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
262 : Button (bb, ex, press) {}
264 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
265 : Button (bb, ex, press, release) {}
268 struct WhiteButton : public Button {
269 WhiteButton (ButtonID bb, uint8_t ex)
272 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
273 : Button (bb, ex, press) {}
275 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
276 : Button (bb, ex, press, release) {}
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;
288 void init_buttons ();
290 /* map of Pads by note number */
291 typedef std::map<int,Pad*> NNPadMap;
293 /* map of Pads by coordinate
295 * coord = row * 64 + column;
297 * rows start at top left
299 typedef std::map<int,Pad*> CoordPadMap;
300 CoordPadMap coord_pad_map;
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);
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;
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);
321 void write (const MidiByteArray&);
322 bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
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);
337 void button_recenable ();
340 void button_right ();
342 void button_metronome ();
343 void button_repeat ();
345 void button_fixed_length ();
347 void button_shift_press ();
348 void button_shift_release ();
349 void button_browse ();
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); }
370 void button_fwd32t ();
371 void button_fwd32 ();
372 void button_fwd16t ();
373 void button_fwd16 ();
374 void button_fwd8t ();
376 void button_fwd4t ();
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];
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;
396 void solo_change (int);
397 void mute_change (int);
399 void switch_bank (uint32_t base);
405 #endif /* __ardour_push2_h__ */