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>
30 #include <glibmm/threads.h>
32 #define ABSTRACT_UI_EXPORTS
33 #include "pbd/abstract_ui.h"
34 #include "midi++/types.h"
35 #include "ardour/types.h"
36 #include "control_protocol/control_protocol.h"
38 #include "midi_byte_array.h"
54 namespace ArdourSurface {
56 struct Push2Request : public BaseUI::BaseRequestObject {
62 class Push2 : public ARDOUR::ControlProtocol
63 , public AbstractUI<Push2Request>
66 Push2 (ARDOUR::Session&);
70 static void* request_factory (uint32_t);
72 int set_active (bool yn);
74 int set_state (const XMLNode & node, int version);
77 libusb_device_handle *handle;
78 Glib::Threads::Mutex fb_lock;
79 uint8_t frame_header[16];
80 uint16_t* device_frame_buffer[2];
82 Cairo::RefPtr<Cairo::ImageSurface> frame_buffer;
83 sigc::connection vblank_connection;
84 sigc::connection periodic_connection;
86 static const int cols;
87 static const int rows;
88 static const int pixels_per_row;
90 void do_request (Push2Request*);
100 Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
114 Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8,
172 LED (uint8_t e) : _extra (e), _color_index (0), _state (Off) {}
175 uint8_t extra () const { return _extra; }
176 uint8_t color_index () const { return _color_index; }
177 State state () const { return _state; }
179 void set_color (uint8_t color_index);
180 void set_state (State state);
182 virtual MidiByteArray state_msg() const = 0;
186 uint8_t _color_index;
190 struct Pad : public LED {
191 Pad (int xx, int yy, uint8_t ex)
196 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, (_state == Off) ? 0 : _color_index); }
198 int coord () const { return (y * 8) + x; }
199 int note_number() const { return extra(); }
205 struct Button : public LED {
206 Button (ButtonID bb, uint8_t ex)
209 , press_method (&Push2::relax)
210 , release_method (&Push2::relax)
213 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
216 , press_method (press)
217 , release_method (&Push2::relax)
220 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
223 , press_method (press)
224 , release_method (release)
227 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, (_state == Off) ? 0 : _color_index); }
228 int controller_number() const { return extra(); }
231 void (Push2::*press_method)();
232 void (Push2::*release_method)();
235 struct ColorButton : public Button {
236 ColorButton (ButtonID bb, uint8_t ex)
240 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
241 : Button (bb, ex, press) {}
243 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
244 : Button (bb, ex, press, release) {}
247 struct WhiteButton : public Button {
248 WhiteButton (ButtonID bb, uint8_t ex)
251 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
252 : Button (bb, ex, press) {}
254 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
255 : Button (bb, ex, press, release) {}
260 /* map of Buttons by CC */
261 typedef std::map<int,Button*> CCButtonMap;
262 CCButtonMap cc_button_map;
263 /* map of Buttons by ButtonID */
264 typedef std::map<ButtonID,Button*> IDButtonMap;
265 IDButtonMap id_button_map;
267 /* map of Pads by note number */
268 typedef std::map<int,Pad*> NNPadMap;
270 /* map of Pads by coordinate
272 * coord = row * 64 + column;
274 * rows start at top left
276 typedef std::map<int,Pad*> CoordPadMap;
277 CoordPadMap coord_pad_map;
279 void set_button_color (ButtonID, uint8_t color_index);
280 void set_button_state (ButtonID, LED::State);
281 void set_led_color (ButtonID, uint8_t color_index);
282 void set_led_state (ButtonID, LED::State);
286 MIDI::Port* _input_port[2];
287 MIDI::Port* _output_port[2];
288 boost::shared_ptr<ARDOUR::Port> _async_in[2];
289 boost::shared_ptr<ARDOUR::Port> _async_out[2];
291 void connect_to_parser ();
292 void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
293 void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
294 void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
295 void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
296 void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
298 void write (int port, const MidiByteArray&);
299 bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
304 PBD::ScopedConnectionList session_connections;
305 void connect_session_signals ();
306 void notify_record_state_changed ();
307 void notify_transport_state_changed ();
308 void notify_loop_state_changed ();
309 void notify_parameter_changed (std::string);
310 void notify_solo_active_changed (bool);
314 void button_recenable ();
322 #endif /* __ardour_push2_h__ */