Ardour  9.2-129-gdf5e1050bd
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 #ifdef COMPILER_MSVC
29 #define _WINSOCKAPI_
30 #endif
31 
32 #include <libusb.h>
33 
34 #define ABSTRACT_UI_EXPORTS
35 #include "pbd/abstract_ui.h"
36 
37 #include "midi++/types.h"
38 
39 #include "ardour/mode.h"
40 #include "ardour/types.h"
41 
43 #include "control_protocol/types.h"
44 
45 #include "gtkmm2ext/colors.h"
46 
49 
50 namespace MIDI {
51  class Parser;
52  class Port;
53 }
54 
55 namespace ARDOUR {
56  class Port;
57  class MidiBuffer;
58  class MidiTrack;
59 }
60 
61 namespace ArdourSurface {
62 
63 class P2GUI;
64 class Push2Layout;
65 class Push2Canvas;
66 
67 class Push2 : public MIDISurface
68 {
69  public:
70  enum ButtonID {
79  Mix,
93  New,
106  Up,
121  Select
122  };
123 
124  struct LED
125  {
126  enum State {
143  };
144 
145  enum Colors {
146  Black = 0,
147  Red = 127,
148  Green = 126,
149  Blue = 125,
150  DarkGray = 124,
151  LightGray = 123,
152  White = 122
153  };
154 
155  LED (uint8_t e) : _extra (e), _color_index (Black), _state (NoTransition) {}
156  virtual ~LED() {}
157 
158  uint8_t extra () const { return _extra; }
159  uint8_t color_index () const { return _color_index; }
160  State state () const { return _state; }
161 
162  void set_color (uint8_t color_index);
164 
165  virtual MidiByteArray state_msg() const = 0;
166 
167  protected:
168  uint8_t _extra;
169  uint8_t _color_index;
171  };
172 
173  struct Pad : public LED {
174  enum WhenPressed {
178  };
179 
180  Pad (int xx, int yy, uint8_t ex)
181  : LED (ex)
182  , x (xx)
183  , y (yy)
185  , filtered (ex)
186  , perma_color (LED::Black)
187  {}
188 
190 
191  int coord () const { return (y * 8) + x; }
192  int note_number() const { return extra(); }
193 
194  int x;
195  int y;
197  int filtered;
199  };
200 
201  struct Button : public LED {
202  Button (ButtonID bb, uint8_t ex)
203  : LED (ex)
204  , id (bb)
205  , press_method (&Push2::relax)
208  {}
209 
210  Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
211  : LED (ex)
212  , id (bb)
213  , press_method (press)
216  {}
217 
218  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
219  : LED (ex)
220  , id (bb)
221  , press_method (press)
224  {}
225 
226  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
227  : LED (ex)
228  , id (bb)
229  , press_method (press)
231  , long_press_method (long_press)
232  {}
233 
235  int controller_number() const { return extra(); }
236 
238  void (Push2::*press_method)();
239  void (Push2::*release_method)();
241  sigc::connection timeout_connection;
242  };
243 
244  struct ColorButton : public Button {
245  ColorButton (ButtonID bb, uint8_t ex)
246  : Button (bb, ex) {}
247 
248 
249  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
250  : Button (bb, ex, press) {}
251 
252  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
253  : Button (bb, ex, press, release) {}
254 
255  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
256  : Button (bb, ex, press, release, long_press) {}
257  };
258 
259  struct WhiteButton : public Button {
260  WhiteButton (ButtonID bb, uint8_t ex)
261  : Button (bb, ex) {}
262 
263  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
264  : Button (bb, ex, press) {}
265 
266  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
267  : Button (bb, ex, press, release) {}
268 
269  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
270  : Button (bb, ex, press, release, long_press) {}
271  };
272 
273  enum ColorName {
276 
280 
284 
287 
292  };
293 
297  };
298 
299  public:
301  ~Push2 ();
302 
303  static bool available ();
304  static bool match_usb (uint16_t, uint16_t);
305  static bool probe (std::string&, std::string&);
306 
307  std::string input_port_name () const;
308  std::string output_port_name () const;
309 
310  bool has_editor () const { return true; }
311  void* get_gui () const;
312  void tear_down_gui ();
313 
314  int set_active (bool yn);
315  XMLNode& get_state() const;
316  int set_state (const XMLNode & node, int version);
317 
318  int pad_note (int row, int col) const;
320 
322 
332  };
333 
340  enum RowInterval {
345  };
346 
349 
352 
375  void set_pad_scale_in_key (int root,
376  int octave,
378  NoteGridOrigin origin,
379  int ideal_vertical_semitones);
380 
400  void set_pad_scale_chromatic (int root,
401  int octave,
403  NoteGridOrigin origin,
404  int vertical_semitones);
405 
406  void set_pad_scale (int root,
407  int octave,
409  NoteGridOrigin origin,
411  bool inkey);
412 
414 
415  MusicalMode::Type mode() const { return _mode; }
418  int scale_root() const { return _scale_root; }
419  int root_octave() const { return _root_octave; }
420  bool in_key() const { return _in_key; }
421 
424 
425  Push2Canvas* canvas() const { return _canvas; }
426 
428  None = 0,
429  ModShift = 0x1,
430  ModSelect = 0x2,
431  };
432 
434 
435  std::shared_ptr<Button> button_by_id (ButtonID);
436  static std::string button_name_by_id (ButtonID);
437 
439 
442 
446 
447  libusb_device_handle* usb_handle() const { return _handle; }
448 
449  bool stop_down () const { return _stop_down; }
450 
451  typedef std::map<int,std::shared_ptr<Pad> > PadMap;
452  PadMap const & nn_pad_map() const { return _nn_pad_map; }
453 
454  std::shared_ptr<Pad> pad_by_xy (int x, int y);
455  std::shared_ptr<Button> lower_button_by_column (uint32_t col);
456 
457  private:
458  libusb_device_handle* _handle;
460 
464  void device_release ();
465  void run_event_loop ();
467 
468  void relax () {}
469 
470  /* map of Buttons by CC */
471  typedef std::map<int,std::shared_ptr<Button> > CCButtonMap;
473  /* map of Buttons by ButtonID */
474  typedef std::map<ButtonID,std::shared_ptr<Button> > IDButtonMap;
476  std::set<ButtonID> _buttons_down;
477  std::set<ButtonID> _consumed;
478 
480  void start_press_timeout (std::shared_ptr<Button>, ButtonID);
481 
482  void init_buttons (bool startup);
483  void init_touch_strip (bool with_shift);
484 
485  /* map of Pads by note number (the "fixed" note number sent by the
486  * hardware, not the note number generated if the pad is touched)
487  */
489 
490  /* array of Pads by x,y duple (indexed as (x*8) + y */
491 
492  std::vector<std::shared_ptr<Pad> > _xy_pad_map;
493 
494  /* map of Pads by note number they generate (their "filtered" value)
495  */
496  typedef std::multimap<int,std::shared_ptr<Pad> > FNPadMap;
498 
499  void set_button_color (ButtonID, uint8_t color_index);
501  void set_led_color (ButtonID, uint8_t color_index);
503 
504  void build_maps ();
505 
510  void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
511 
515  void notify_parameter_changed (std::string);
517 
518  /* Button methods */
519  void button_play ();
521  void button_up ();
522  void button_down ();
523  void button_right ();
524  void button_left ();
526  void button_repeat ();
527  void button_mute ();
528  void button_solo ();
531  void button_new ();
532  void button_browse ();
533  void button_clip ();
534  void button_session ();
535  void button_undo ();
536  void button_fwd32t ();
537  void button_fwd32 ();
538  void button_fwd16t ();
539  void button_fwd16 ();
540  void button_fwd8t ();
541  void button_fwd8 ();
542  void button_fwd4t ();
543  void button_fwd4 ();
548  void button_master ();
564 
565  void button_upper (uint32_t n);
566  void button_lower (uint32_t n);
567 
568  void button_upper_1 () { button_upper (0); }
569  void button_upper_2 () { button_upper (1); }
570  void button_upper_3 () { button_upper (2); }
571  void button_upper_4 () { button_upper (3); }
572  void button_upper_5 () { button_upper (4); }
573  void button_upper_6 () { button_upper (5); }
574  void button_upper_7 () { button_upper (6); }
575  void button_upper_8 () { button_upper (7); }
576  void button_lower_1 () { button_lower (0); }
577  void button_lower_2 () { button_lower (1); }
578  void button_lower_3 () { button_lower (2); }
579  void button_lower_4 () { button_lower (3); }
580  void button_lower_5 () { button_lower (4); }
581  void button_lower_6 () { button_lower (5); }
582  void button_lower_7 () { button_lower (6); }
583  void button_lower_8 () { button_lower (7); }
584 
585  void start_shift ();
586  void end_shift ();
587 
588  /* non-strip encoders */
589 
590  void other_vpot (int, int);
591  void other_vpot_touch (int, bool);
592 
593  /* special Stripable */
594 
595  std::shared_ptr<ARDOUR::Stripable> _master;
596 
597  sigc::connection _vblank_connection;
598  bool vblank ();
599 
600  void splash ();
602 
603  /* the canvas */
604 
606 
607  /* Layouts */
608 
618 
620 
621  std::weak_ptr<ARDOUR::MidiTrack> _current_pad_target;
622 
623  /* GUI */
624 
625  mutable P2GUI* _gui;
626  void build_gui ();
627 
628  /* pad mapping */
629 
631 
637  bool _in_key;
640 
642 
643  void set_percussive_mode (bool);
644 
645  /* color map (device side) */
646 
647  typedef std::map<Gtkmm2ext::Color,uint8_t> ColorMap;
648  typedef std::stack<uint8_t> ColorMapFreeList;
652 
653  /* our own colors */
654 
655  typedef std::map<ColorName,Gtkmm2ext::Color> Colors;
659 
662 
665 
668 };
669 
670 } /* namespace */
671 
672 #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:319
int set_active(bool yn)
void set_pad_scale_chromatic(int root, int octave, MusicalMode::Type mode, NoteGridOrigin origin, int vertical_semitones)
PressureMode _pressure_mode
Definition: push2.h:660
void button_lower_8()
Definition: push2.h:583
uint8_t _selection_color
Definition: push2.h:663
Push2Canvas * _canvas
Definition: push2.h:605
libusb_device_handle * _handle
Definition: push2.h:458
void button_upper_1()
Definition: push2.h:568
void other_vpot_touch(int, bool)
NoteGridOrigin note_grid_origin()
Definition: push2.h:416
MusicalMode::Type mode() const
Definition: push2.h:415
Push2Layout * _splash_layout
Definition: push2.h:615
PBD::Signal< void(PressureMode)> PressureModeChange
Definition: push2.h:445
void notify_record_state_changed()
void notify_parameter_changed(std::string)
Push2Layout * _track_mix_layout
Definition: push2.h:614
void init_touch_strip(bool with_shift)
CCButtonMap _cc_button_map
Definition: push2.h:472
std::set< ButtonID > _buttons_down
Definition: push2.h:476
void button_upper_6()
Definition: push2.h:573
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:572
int root_octave() const
Definition: push2.h:419
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:343
@ Fourth
Major third or 4 semitones.
Definition: push2.h:342
@ Sequential
Perfect fifth or 7 semitones.
Definition: push2.h:344
void button_upper_4()
Definition: push2.h:571
void button_upper(uint32_t n)
std::vector< std::shared_ptr< Pad > > _xy_pad_map
Definition: push2.h:492
void notify_solo_active_changed(bool)
ModifierState _modifier_state
Definition: push2.h:459
PadMap _nn_pad_map
Definition: push2.h:488
std::shared_ptr< Pad > pad_by_xy(int x, int y)
void set_pressure_mode(PressureMode)
NoteGridOrigin _note_grid_origin
Definition: push2.h:633
void button_upper_2()
Definition: push2.h:569
void button_upper_8()
Definition: push2.h:575
void button_lower_2()
Definition: push2.h:577
static bool match_usb(uint16_t, uint16_t)
std::map< int, std::shared_ptr< Button > > CCButtonMap
Definition: push2.h:471
void * get_gui() const
static bool available()
bool button_long_press_timeout(ButtonID id)
RowInterval row_interval() const
Definition: push2.h:417
void button_lower_5()
Definition: push2.h:580
void set_pad_scale(int root, int octave, MusicalMode::Type mode, NoteGridOrigin origin, RowInterval row_interval, bool inkey)
libusb_device_handle * usb_handle() const
Definition: push2.h:447
bool has_editor() const
Definition: push2.h:310
PBD::microseconds_t _splash_start
Definition: push2.h:601
std::stack< uint8_t > ColorMapFreeList
Definition: push2.h:648
Push2Layout * _scale_layout
Definition: push2.h:613
void set_led_state(ButtonID, LED::State)
Push2Layout * current_layout() const
bool stop_down() const
Definition: push2.h:449
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:452
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:413
std::weak_ptr< ARDOUR::MidiTrack > _current_pad_target
Definition: push2.h:621
PBD::Mutex layout_lock
Definition: push2.h:609
static bool probe(std::string &, std::string &)
RowInterval _row_interval
Definition: push2.h:634
sigc::connection _vblank_connection
Definition: push2.h:597
int set_state(const XMLNode &node, int version)
IDButtonMap _id_button_map
Definition: push2.h:475
bool _in_range_select
Definition: push2.h:666
std::set< ButtonID > _consumed
Definition: push2.h:477
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:649
Push2Layout * _current_layout
Definition: push2.h:610
int pad_note(int row, int col) const
Push2Layout * _previous_layout
Definition: push2.h:611
FNPadMap _fn_pad_map
Definition: push2.h:497
uint8_t _contrast_color
Definition: push2.h:664
void stripable_selection_changed()
bool in_key() const
Definition: push2.h:420
std::map< ButtonID, std::shared_ptr< Button > > IDButtonMap
Definition: push2.h:474
void set_percussive_mode(bool)
Push2Canvas * canvas() const
Definition: push2.h:425
void button_lower_3()
Definition: push2.h:578
void button_upper_3()
Definition: push2.h:570
std::string input_port_name() const
int scale_root() const
Definition: push2.h:418
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)
void set_pad_scale_in_key(int root, int octave, MusicalMode::Type mode, NoteGridOrigin origin, int ideal_vertical_semitones)
std::map< Gtkmm2ext::Color, uint8_t > ColorMap
Definition: push2.h:647
void button_lower_6()
Definition: push2.h:581
MusicalMode::Type _mode
Definition: push2.h:632
void button_lower(uint32_t n)
std::multimap< int, std::shared_ptr< Pad > > FNPadMap
Definition: push2.h:496
void button_lower_7()
Definition: push2.h:582
bool pad_filter(ARDOUR::MidiBuffer &in, ARDOUR::MidiBuffer &out) const
std::shared_ptr< ARDOUR::Stripable > _master
Definition: push2.h:595
std::shared_ptr< Button > button_by_id(ButtonID)
PressureMode pressure_mode() const
Definition: push2.h:443
std::map< int, std::shared_ptr< Pad > > PadMap
Definition: push2.h:451
Push2Layout * _cue_layout
Definition: push2.h:616
@ Fixed
Bottom left pad is always C, or as close as possible.
Definition: push2.h:330
@ Rooted
Bottom left pad is the scale root.
Definition: push2.h:331
void handle_midi_sysex(MIDI::Parser &, MIDI::byte *, size_t count)
void notify_transport_state_changed()
std::map< ColorName, Gtkmm2ext::Color > Colors
Definition: push2.h:655
ColorMapFreeList _color_map_free_list
Definition: push2.h:650
ModifierState modifier_state() const
Definition: push2.h:433
void button_lower_1()
Definition: push2.h:576
void button_lower_4()
Definition: push2.h:579
void button_upper_7()
Definition: push2.h:574
Push2(ARDOUR::Session &)
PadNoteKind
"Kind" of pad that plays a note
Definition: push2.h:348
uint8_t get_color_index(Gtkmm2ext::Color rgba)
void init_buttons(bool startup)
Push2Layout * _mix_layout
Definition: push2.h:612
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:238
void(Push2::* release_method)()
Definition: push2.h:239
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:226
Button(ButtonID bb, uint8_t ex)
Definition: push2.h:202
sigc::connection timeout_connection
Definition: push2.h:241
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:218
void(Push2::* long_press_method)()
Definition: push2.h:240
Button(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:210
int controller_number() const
Definition: push2.h:235
MidiByteArray state_msg() const
Definition: push2.h:234
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:252
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:249
ColorButton(ButtonID bb, uint8_t ex)
Definition: push2.h:245
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:255
void set_state(State state)
virtual MidiByteArray state_msg() const =0
uint8_t color_index() const
Definition: push2.h:159
State state() const
Definition: push2.h:160
void set_color(uint8_t color_index)
uint8_t extra() const
Definition: push2.h:158
int note_number() const
Definition: push2.h:192
MidiByteArray state_msg() const
Definition: push2.h:189
Pad(int xx, int yy, uint8_t ex)
Definition: push2.h:180
int coord() const
Definition: push2.h:191
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:269
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:266
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:263
WhiteButton(ButtonID bb, uint8_t ex)
Definition: push2.h:260