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,
186 LED (uint8_t e) : _extra (e), _color_index (0), _state (NoTransition) {}
189 uint8_t extra () const { return _extra; }
190 uint8_t color_index () const { return _color_index; }
191 State state () const { return _state; }
193 void set_color (uint8_t color_index);
194 void set_state (State state);
196 virtual MidiByteArray state_msg() const = 0;
200 uint8_t _color_index;
204 struct Pad : public LED {
205 Pad (int xx, int yy, uint8_t ex)
210 MidiByteArray state_msg () const { return MidiByteArray (3, 0x90|_state, _extra, _color_index); }
212 int coord () const { return (y * 8) + x; }
213 int note_number() const { return extra(); }
219 struct Button : public LED {
220 Button (ButtonID bb, uint8_t ex)
223 , press_method (&Push2::relax)
224 , release_method (&Push2::relax)
227 Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
230 , press_method (press)
231 , release_method (&Push2::relax)
234 Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
237 , press_method (press)
238 , release_method (release)
241 MidiByteArray state_msg () const { return MidiByteArray (3, 0xb0|_state, _extra, _color_index); }
242 int controller_number() const { return extra(); }
245 void (Push2::*press_method)();
246 void (Push2::*release_method)();
249 struct ColorButton : public Button {
250 ColorButton (ButtonID bb, uint8_t ex)
254 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
255 : Button (bb, ex, press) {}
257 ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
258 : Button (bb, ex, press, release) {}
261 struct WhiteButton : public Button {
262 WhiteButton (ButtonID bb, uint8_t ex)
265 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
266 : Button (bb, ex, press) {}
268 WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
269 : Button (bb, ex, press, release) {}
274 /* map of Buttons by CC */
275 typedef std::map<int,Button*> CCButtonMap;
276 CCButtonMap cc_button_map;
277 /* map of Buttons by ButtonID */
278 typedef std::map<ButtonID,Button*> IDButtonMap;
279 IDButtonMap id_button_map;
281 void init_buttons ();
283 /* map of Pads by note number */
284 typedef std::map<int,Pad*> NNPadMap;
286 /* map of Pads by coordinate
288 * coord = row * 64 + column;
290 * rows start at top left
292 typedef std::map<int,Pad*> CoordPadMap;
293 CoordPadMap coord_pad_map;
295 void set_button_color (ButtonID, uint8_t color_index);
296 void set_button_state (ButtonID, LED::State);
297 void set_led_color (ButtonID, uint8_t color_index);
298 void set_led_state (ButtonID, LED::State);
302 MIDI::Port* _input_port;
303 MIDI::Port* _output_port;
304 boost::shared_ptr<ARDOUR::Port> _async_in;
305 boost::shared_ptr<ARDOUR::Port> _async_out;
307 void connect_to_parser ();
308 void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t);
309 void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);
310 void handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes*);
311 void handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes*);
312 void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
314 void write (const MidiByteArray&);
315 bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
320 PBD::ScopedConnectionList session_connections;
321 void connect_session_signals ();
322 void notify_record_state_changed ();
323 void notify_transport_state_changed ();
324 void notify_loop_state_changed ();
325 void notify_parameter_changed (std::string);
326 void notify_solo_active_changed (bool);
330 void button_recenable ();
333 void button_right ();
335 void button_metronome ();
336 void button_repeat ();
338 void button_fixed_length ();
343 Cairo::RefPtr<Cairo::Context> context;
344 Glib::RefPtr<Pango::Layout> tc_clock_layout;
345 Glib::RefPtr<Pango::Layout> bbt_clock_layout;
346 Glib::RefPtr<Pango::Layout> upper_layout[8];
347 Glib::RefPtr<Pango::Layout> mid_layout[8];
348 Glib::RefPtr<Pango::Layout> lower_layout[8];
354 #endif /* __ardour_push2_h__ */