Ardour  9.2-654-gd2ed0bd940
push2.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2018 Paul Davis <paul@linuxaudiosystems.com>
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 along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __ardour_push2_h__
20 #define __ardour_push2_h__
21 
22 #include <vector>
23 #include <map>
24 #include <stack>
25 #include <list>
26 #include <set>
27 
28 #if defined COMPILER_MSVC && defined WAF_BUILD
29 #define NOMINMAX
30 #define _WINSOCKAPI_
31 #endif
32 
33 #include <libusb.h>
34 
35 #define ABSTRACT_UI_EXPORTS
36 #include "pbd/abstract_ui.h"
37 
38 #include "midi++/types.h"
39 
40 #include "ardour/scale.h"
41 #include "ardour/types.h"
42 
44 #include "control_protocol/types.h"
45 
46 #include "gtkmm2ext/colors.h"
47 
50 
51 namespace MIDI {
52  class Parser;
53  class Port;
54 }
55 
56 namespace ARDOUR {
57  class Port;
58  class MidiBuffer;
59  class MidiTrack;
60 }
61 
62 namespace ArdourSurface {
63 
64 class P2GUI;
65 class Push2Layout;
66 class Push2Canvas;
67 
68 class Push2 : public MIDISurface
69 {
70  public:
71  enum ButtonID {
80  Mix,
94  New,
107  Up,
122  Select
123  };
124 
125  struct LED
126  {
127  enum State {
144  };
145 
146  enum Colors {
147  Black = 0,
148  Red = 127,
149  Green = 126,
150  Blue = 125,
151  DarkGray = 124,
152  LightGray = 123,
153  White = 122
154  };
155 
156  LED (uint8_t e) : _extra (e), _color_index (Black), _state (NoTransition) {}
157  virtual ~LED() {}
158 
159  uint8_t extra () const { return _extra; }
160  uint8_t color_index () const { return _color_index; }
161  State state () const { return _state; }
162 
163  void set_color (uint8_t color_index);
165 
166  virtual MidiByteArray state_msg() const = 0;
167 
168  protected:
169  uint8_t _extra;
170  uint8_t _color_index;
172  };
173 
174  struct Pad : public LED {
175  enum WhenPressed {
179  };
180 
181  Pad (int xx, int yy, uint8_t ex)
182  : LED (ex)
183  , x (xx)
184  , y (yy)
186  , filtered (ex)
187  , perma_color (LED::Black)
188  {}
189 
191 
192  int coord () const { return (y * 8) + x; }
193  int note_number() const { return extra(); }
194 
195  int x;
196  int y;
198  int filtered;
200  };
201 
202  struct Button : public LED {
203  Button (ButtonID bb, uint8_t ex)
204  : LED (ex)
205  , id (bb)
206  , press_method (&Push2::relax)
209  {}
210 
211  Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
212  : LED (ex)
213  , id (bb)
214  , press_method (press)
217  {}
218 
219  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
220  : LED (ex)
221  , id (bb)
222  , press_method (press)
225  {}
226 
227  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
228  : LED (ex)
229  , id (bb)
230  , press_method (press)
232  , long_press_method (long_press)
233  {}
234 
236  int controller_number() const { return extra(); }
237 
239  void (Push2::*press_method)();
240  void (Push2::*release_method)();
242  sigc::connection timeout_connection;
243  };
244 
245  struct ColorButton : public Button {
246  ColorButton (ButtonID bb, uint8_t ex)
247  : Button (bb, ex) {}
248 
249 
250  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
251  : Button (bb, ex, press) {}
252 
253  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
254  : Button (bb, ex, press, release) {}
255 
256  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
257  : Button (bb, ex, press, release, long_press) {}
258  };
259 
260  struct WhiteButton : public Button {
261  WhiteButton (ButtonID bb, uint8_t ex)
262  : Button (bb, ex) {}
263 
264  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
265  : Button (bb, ex, press) {}
266 
267  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
268  : Button (bb, ex, press, release) {}
269 
270  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
271  : Button (bb, ex, press, release, long_press) {}
272  };
273 
274  enum ColorName {
277 
281 
285 
288 
293  };
294 
298  };
299 
300  public:
302  ~Push2 ();
303 
304  static bool available ();
305  static bool match_usb (uint16_t, uint16_t);
306  static bool probe (std::string&, std::string&);
307 
308  std::string input_port_name () const;
309  std::string output_port_name () const;
310 
311  bool has_editor () const { return true; }
312  void* get_gui () const;
313  void tear_down_gui ();
314 
315  int set_active (bool yn);
316  XMLNode& get_state() const;
317  int set_state (const XMLNode & node, int version);
318 
319  int pad_note (int row, int col) const;
321 
323 
333  };
334 
341  enum RowInterval {
346  };
347 
350 
353 
376  void set_pad_scale_in_key (int root,
377  int octave,
379  NoteGridOrigin origin,
380  int ideal_vertical_semitones);
381 
401  void set_pad_scale_chromatic (int root,
402  int octave,
404  NoteGridOrigin origin,
405  int vertical_semitones);
406 
407  void set_pad_scale (int root,
408  int octave,
410  NoteGridOrigin origin,
412  bool inkey);
413 
415 
419  int scale_root() const { return _scale_root; }
420  int root_octave() const { return _root_octave; }
421  bool in_key() const { return _in_key; }
422 
425 
426  Push2Canvas* canvas() const { return _canvas; }
427 
429  None = 0,
430  ModShift = 0x1,
431  ModSelect = 0x2,
432  };
433 
435 
436  std::shared_ptr<Button> button_by_id (ButtonID);
437  static std::string button_name_by_id (ButtonID);
438 
440 
443 
447 
448  libusb_device_handle* usb_handle() const { return _handle; }
449 
450  bool stop_down () const { return _stop_down; }
451 
452  typedef std::map<int,std::shared_ptr<Pad> > PadMap;
453  PadMap const & nn_pad_map() const { return _nn_pad_map; }
454 
455  std::shared_ptr<Pad> pad_by_xy (int x, int y);
456  std::shared_ptr<Button> lower_button_by_column (uint32_t col);
457 
458  private:
459  libusb_device_handle* _handle;
461 
465  void device_release ();
466  void run_event_loop ();
468 
469  void relax () {}
470 
471  /* map of Buttons by CC */
472  typedef std::map<int,std::shared_ptr<Button> > CCButtonMap;
474  /* map of Buttons by ButtonID */
475  typedef std::map<ButtonID,std::shared_ptr<Button> > IDButtonMap;
477  std::set<ButtonID> _buttons_down;
478  std::set<ButtonID> _consumed;
479 
481  void start_press_timeout (std::shared_ptr<Button>, ButtonID);
482 
483  void init_buttons (bool startup);
484  void init_touch_strip (bool with_shift);
485 
486  /* map of Pads by note number (the "fixed" note number sent by the
487  * hardware, not the note number generated if the pad is touched)
488  */
490 
491  /* array of Pads by x,y duple (indexed as (x*8) + y */
492 
493  std::vector<std::shared_ptr<Pad> > _xy_pad_map;
494 
495  /* map of Pads by note number they generate (their "filtered" value)
496  */
497  typedef std::multimap<int,std::shared_ptr<Pad> > FNPadMap;
499 
500  void set_button_color (ButtonID, uint8_t color_index);
502  void set_led_color (ButtonID, uint8_t color_index);
504 
505  void build_maps ();
506 
511  void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
512 
516  void notify_parameter_changed (std::string);
518 
519  /* Button methods */
520  void button_play ();
522  void button_up ();
523  void button_down ();
524  void button_right ();
525  void button_left ();
527  void button_repeat ();
528  void button_mute ();
529  void button_solo ();
532  void button_new ();
533  void button_browse ();
534  void button_clip ();
535  void button_session ();
536  void button_undo ();
537  void button_fwd32t ();
538  void button_fwd32 ();
539  void button_fwd16t ();
540  void button_fwd16 ();
541  void button_fwd8t ();
542  void button_fwd8 ();
543  void button_fwd4t ();
544  void button_fwd4 ();
549  void button_master ();
565 
566  void button_upper (uint32_t n);
567  void button_lower (uint32_t n);
568 
569  void button_upper_1 () { button_upper (0); }
570  void button_upper_2 () { button_upper (1); }
571  void button_upper_3 () { button_upper (2); }
572  void button_upper_4 () { button_upper (3); }
573  void button_upper_5 () { button_upper (4); }
574  void button_upper_6 () { button_upper (5); }
575  void button_upper_7 () { button_upper (6); }
576  void button_upper_8 () { button_upper (7); }
577  void button_lower_1 () { button_lower (0); }
578  void button_lower_2 () { button_lower (1); }
579  void button_lower_3 () { button_lower (2); }
580  void button_lower_4 () { button_lower (3); }
581  void button_lower_5 () { button_lower (4); }
582  void button_lower_6 () { button_lower (5); }
583  void button_lower_7 () { button_lower (6); }
584  void button_lower_8 () { button_lower (7); }
585 
586  void start_shift ();
587  void end_shift ();
588 
589  /* non-strip encoders */
590 
591  void other_vpot (int, int);
592  void other_vpot_touch (int, bool);
593 
594  /* special Stripable */
595 
596  std::shared_ptr<ARDOUR::Stripable> _master;
597 
598  sigc::connection _vblank_connection;
599  bool vblank ();
600 
601  void splash ();
603 
604  /* the canvas */
605 
607 
608  /* Layouts */
609 
619 
621 
622  std::weak_ptr<ARDOUR::MidiTrack> _current_pad_target;
623 
624  /* GUI */
625 
626  mutable P2GUI* _gui;
627  void build_gui ();
628 
629  /* pad mapping */
630 
632 
638  bool _in_key;
641 
643 
644  void set_percussive_mode (bool);
645 
646  /* color map (device side) */
647 
648  typedef std::map<Gtkmm2ext::Color,uint8_t> ColorMap;
649  typedef std::stack<uint8_t> ColorMapFreeList;
653 
654  /* our own colors */
655 
656  typedef std::map<ColorName,Gtkmm2ext::Color> Colors;
660 
663 
666 
669 };
670 
671 } /* namespace */
672 
673 #endif /* __ardour_push2_h__ */
void None
Definition: TypeList.h:49
void handle_midi_note_off_message(MIDI::Parser &, MIDI::EventTwoBytes *)
PBD::Signal< void()> PadChange
Definition: push2.h:320
int set_active(bool yn)
PressureMode _pressure_mode
Definition: push2.h:661
void button_lower_8()
Definition: push2.h:584
uint8_t _selection_color
Definition: push2.h:664
Push2Canvas * _canvas
Definition: push2.h:606
libusb_device_handle * _handle
Definition: push2.h:459
void button_upper_1()
Definition: push2.h:569
void other_vpot_touch(int, bool)
NoteGridOrigin note_grid_origin()
Definition: push2.h:417
Push2Layout * _splash_layout
Definition: push2.h:616
PBD::Signal< void(PressureMode)> PressureModeChange
Definition: push2.h:446
void notify_record_state_changed()
void notify_parameter_changed(std::string)
Push2Layout * _track_mix_layout
Definition: push2.h:615
void init_touch_strip(bool with_shift)
CCButtonMap _cc_button_map
Definition: push2.h:473
std::set< ButtonID > _buttons_down
Definition: push2.h:477
void button_upper_6()
Definition: push2.h:574
void set_button_color(ButtonID, uint8_t color_index)
void handle_midi_pitchbend_message(MIDI::Parser &, MIDI::pitchbend_t)
void set_current_layout(Push2Layout *)
void start_press_timeout(std::shared_ptr< Button >, ButtonID)
void button_upper_5()
Definition: push2.h:573
int root_octave() const
Definition: push2.h:420
void set_led_color(ButtonID, uint8_t color_index)
void handle_midi_note_on_message(MIDI::Parser &, MIDI::EventTwoBytes *)
@ Fifth
Perfect fourth or 5 semitones.
Definition: push2.h:344
@ Fourth
Major third or 4 semitones.
Definition: push2.h:343
@ Sequential
Perfect fifth or 7 semitones.
Definition: push2.h:345
void button_upper_4()
Definition: push2.h:572
void button_upper(uint32_t n)
std::vector< std::shared_ptr< Pad > > _xy_pad_map
Definition: push2.h:493
void notify_solo_active_changed(bool)
ModifierState _modifier_state
Definition: push2.h:460
PadMap _nn_pad_map
Definition: push2.h:489
std::shared_ptr< Pad > pad_by_xy(int x, int y)
void set_pressure_mode(PressureMode)
NoteGridOrigin _note_grid_origin
Definition: push2.h:634
void button_upper_2()
Definition: push2.h:570
void button_upper_8()
Definition: push2.h:576
void button_lower_2()
Definition: push2.h:578
static bool match_usb(uint16_t, uint16_t)
std::map< int, std::shared_ptr< Button > > CCButtonMap
Definition: push2.h:472
void * get_gui() const
static bool available()
bool button_long_press_timeout(ButtonID id)
RowInterval row_interval() const
Definition: push2.h:418
void button_lower_5()
Definition: push2.h:581
libusb_device_handle * usb_handle() const
Definition: push2.h:448
bool has_editor() const
Definition: push2.h:311
PBD::microseconds_t _splash_start
Definition: push2.h:602
std::stack< uint8_t > ColorMapFreeList
Definition: push2.h:649
Push2Layout * _scale_layout
Definition: push2.h:614
void set_led_state(ButtonID, LED::State)
Push2Layout * current_layout() const
void set_pad_scale_in_key(int root, int octave, ARDOUR::MusicalMode::Name mode, NoteGridOrigin origin, int ideal_vertical_semitones)
bool stop_down() const
Definition: push2.h:450
void set_pad_note_kind(Pad &pad, PadNoteKind kind)
Set up a pad to represent a "kind" of note.
PadMap const & nn_pad_map() const
Definition: push2.h:453
std::shared_ptr< Button > lower_button_by_column(uint32_t col)
void handle_midi_controller_message(MIDI::Parser &, MIDI::EventTwoBytes *)
std::string output_port_name() const
PBD::Signal< void()> ScaleChange
Definition: push2.h:414
std::weak_ptr< ARDOUR::MidiTrack > _current_pad_target
Definition: push2.h:622
PBD::Mutex layout_lock
Definition: push2.h:610
static bool probe(std::string &, std::string &)
RowInterval _row_interval
Definition: push2.h:635
sigc::connection _vblank_connection
Definition: push2.h:598
int set_state(const XMLNode &node, int version)
IDButtonMap _id_button_map
Definition: push2.h:476
bool _in_range_select
Definition: push2.h:667
std::set< ButtonID > _consumed
Definition: push2.h:478
Gtkmm2ext::Color get_color(ColorName)
XMLNode & get_state() const
void button_select_long_press()
void other_vpot(int, int)
ColorMap _color_map
Definition: push2.h:650
Push2Layout * _current_layout
Definition: push2.h:611
int pad_note(int row, int col) const
Push2Layout * _previous_layout
Definition: push2.h:612
FNPadMap _fn_pad_map
Definition: push2.h:498
uint8_t _contrast_color
Definition: push2.h:665
void stripable_selection_changed()
bool in_key() const
Definition: push2.h:421
std::map< ButtonID, std::shared_ptr< Button > > IDButtonMap
Definition: push2.h:475
void set_percussive_mode(bool)
Push2Canvas * canvas() const
Definition: push2.h:426
void button_lower_3()
Definition: push2.h:579
void button_upper_3()
Definition: push2.h:571
std::string input_port_name() const
int scale_root() const
Definition: push2.h:419
void notify_loop_state_changed()
void set_button_state(ButtonID, LED::State)
void button_shift_long_press()
static std::string button_name_by_id(ButtonID)
std::map< Gtkmm2ext::Color, uint8_t > ColorMap
Definition: push2.h:648
void set_pad_scale_chromatic(int root, int octave, ARDOUR::MusicalMode::Name mode, NoteGridOrigin origin, int vertical_semitones)
void button_lower_6()
Definition: push2.h:582
void button_lower(uint32_t n)
std::multimap< int, std::shared_ptr< Pad > > FNPadMap
Definition: push2.h:497
ARDOUR::MusicalMode::Name _mode
Definition: push2.h:633
void button_lower_7()
Definition: push2.h:583
bool pad_filter(ARDOUR::MidiBuffer &in, ARDOUR::MidiBuffer &out) const
std::shared_ptr< ARDOUR::Stripable > _master
Definition: push2.h:596
std::shared_ptr< Button > button_by_id(ButtonID)
PressureMode pressure_mode() const
Definition: push2.h:444
std::map< int, std::shared_ptr< Pad > > PadMap
Definition: push2.h:452
Push2Layout * _cue_layout
Definition: push2.h:617
@ Fixed
Bottom left pad is always C, or as close as possible.
Definition: push2.h:331
@ Rooted
Bottom left pad is the scale root.
Definition: push2.h:332
void handle_midi_sysex(MIDI::Parser &, MIDI::byte *, size_t count)
ARDOUR::MusicalMode::Name mode() const
Definition: push2.h:416
void notify_transport_state_changed()
std::map< ColorName, Gtkmm2ext::Color > Colors
Definition: push2.h:656
ColorMapFreeList _color_map_free_list
Definition: push2.h:651
ModifierState modifier_state() const
Definition: push2.h:434
void button_lower_1()
Definition: push2.h:577
void set_pad_scale(int root, int octave, ARDOUR::MusicalMode::Name mode, NoteGridOrigin origin, RowInterval row_interval, bool inkey)
void button_lower_4()
Definition: push2.h:580
void button_upper_7()
Definition: push2.h:575
Push2(ARDOUR::Session &)
PadNoteKind
"Kind" of pad that plays a note
Definition: push2.h:349
uint8_t get_color_index(Gtkmm2ext::Color rgba)
void init_buttons(bool startup)
Push2Layout * _mix_layout
Definition: push2.h:613
Definition: xml++.h:114
uint32_t Color
Definition: colors.h:33
unsigned short pitchbend_t
int64_t microseconds_t
Definition: microseconds.h:28
void(Push2::* press_method)()
Definition: push2.h:239
void(Push2::* release_method)()
Definition: push2.h:240
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:227
Button(ButtonID bb, uint8_t ex)
Definition: push2.h:203
sigc::connection timeout_connection
Definition: push2.h:242
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:219
void(Push2::* long_press_method)()
Definition: push2.h:241
Button(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:211
int controller_number() const
Definition: push2.h:236
MidiByteArray state_msg() const
Definition: push2.h:235
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:253
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:250
ColorButton(ButtonID bb, uint8_t ex)
Definition: push2.h:246
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:256
void set_state(State state)
virtual MidiByteArray state_msg() const =0
uint8_t color_index() const
Definition: push2.h:160
State state() const
Definition: push2.h:161
void set_color(uint8_t color_index)
uint8_t extra() const
Definition: push2.h:159
int note_number() const
Definition: push2.h:193
MidiByteArray state_msg() const
Definition: push2.h:190
Pad(int xx, int yy, uint8_t ex)
Definition: push2.h:181
int coord() const
Definition: push2.h:192
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:270
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:267
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:264
WhiteButton(ButtonID bb, uint8_t ex)
Definition: push2.h:261