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;
89 static const int cols;
90 static const int rows;
91 static const int pixels_per_row;
93 void do_request (Push2Request*);
98 int bitblt_to_device_frame_buffer ();
104 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
118 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
185 LED (uint8_t e) : _extra (e), _color_index (0), _state (Off) {}
188 uint8_t extra () const { return _extra; }
189 uint8_t color_index () const { return _color_index; }
190 State state () const { return _state; }
192 void set_color (uint8_t color_index);
193 void set_state (State state);
195 virtual MidiByteArray state_msg() const = 0;
199 uint8_t _color_index;
203 struct Pad : public LED {
204 Pad (int xx, int yy, uint8_t ex)
209 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, (_state == Off) ? 0 : _color_index); }
211 int coord () const { return (y * 8) + x; }
212 int note_number() const { return extra(); }
218 struct Button : public LED {
219 Button (ButtonID bb, uint8_t ex)
222 , press_method (&Push2::relax)
223 , release_method (&Push2::relax)
226 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
229 , press_method (press)
230 , release_method (&Push2::relax)
233 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
236 , press_method (press)
237 , release_method (release)
240 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, (_state == Off) ? 0 : _color_index); }
241 int controller_number() const { return extra(); }
244 void (Push2::*press_method)();
245 void (Push2::*release_method)();
248 struct ColorButton : public Button {
249 ColorButton (ButtonID bb, uint8_t ex)
253 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
254 : Button (bb, ex, press) {}
256 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
257 : Button (bb, ex, press, release) {}
260 struct WhiteButton : public Button {
261 WhiteButton (ButtonID bb, uint8_t ex)
264 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
265 : Button (bb, ex, press) {}
267 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
268 : Button (bb, ex, press, release) {}
273 /* map of Buttons by CC */
274 typedef std::map<int,Button*> CCButtonMap;
275 CCButtonMap cc_button_map;
276 /* map of Buttons by ButtonID */
277 typedef std::map<ButtonID,Button*> IDButtonMap;
278 IDButtonMap id_button_map;
280 /* map of Pads by note number */
281 typedef std::map<int,Pad*> NNPadMap;
283 /* map of Pads by coordinate
285 * coord = row * 64 + column;
287 * rows start at top left
289 typedef std::map<int,Pad*> CoordPadMap;
290 CoordPadMap coord_pad_map;
292 void set_button_color (ButtonID, uint8_t color_index);
293 void set_button_state (ButtonID, LED::State);
294 void set_led_color (ButtonID, uint8_t color_index);
295 void set_led_state (ButtonID, LED::State);
299 MIDI::Port* _input_port;
300 MIDI::Port* _output_port;
301 boost::shared_ptr<ARDOUR::Port> _async_in;
302 boost::shared_ptr<ARDOUR::Port> _async_out;
304 void connect_to_parser ();
305 void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
306 void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
307 void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
308 void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
309 void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
311 void write (const MidiByteArray&);
312 bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
317 PBD::ScopedConnectionList session_connections;
318 void connect_session_signals ();
319 void notify_record_state_changed ();
320 void notify_transport_state_changed ();
321 void notify_loop_state_changed ();
322 void notify_parameter_changed (std::string);
323 void notify_solo_active_changed (bool);
327 void button_recenable ();
330 void button_right ();
332 void button_metronome ();
333 void button_repeat ();
338 Cairo::RefPtr<Cairo::Context> context;
339 Glib::RefPtr<Pango::Layout> tc_clock_layout;
340 Glib::RefPtr<Pango::Layout> bbt_clock_layout;
341 Glib::RefPtr<Pango::Layout> upper_layout[8];
342 Glib::RefPtr<Pango::Layout> mid_layout[8];
343 Glib::RefPtr<Pango::Layout> lower_layout[8];
349 #endif /* __ardour_push2_h__ */