Ardour  8.7-14-g57a6773833
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 #include <libusb.h>
29 
30 #define ABSTRACT_UI_EXPORTS
31 #include "pbd/abstract_ui.h"
32 
33 #include "midi++/types.h"
34 
35 #include "ardour/mode.h"
36 #include "ardour/types.h"
37 
39 #include "control_protocol/types.h"
40 
41 #include "gtkmm2ext/colors.h"
42 
45 
46 namespace MIDI {
47  class Parser;
48  class Port;
49 }
50 
51 namespace ARDOUR {
52  class Port;
53  class MidiBuffer;
54  class MidiTrack;
55 }
56 
57 namespace ArdourSurface {
58 
59 class P2GUI;
60 class Push2Layout;
61 class Push2Canvas;
62 
63 class Push2 : public MIDISurface
64 {
65  public:
66  enum ButtonID {
75  Mix,
89  New,
102  Up,
117  Select
118  };
119 
120  struct LED
121  {
122  enum State {
139  };
140 
141  enum Colors {
142  Black = 0,
143  Red = 127,
144  Green = 126,
145  Blue = 125,
146  DarkGray = 124,
147  LightGray = 123,
148  White = 122
149  };
150 
151  LED (uint8_t e) : _extra (e), _color_index (Black), _state (NoTransition) {}
152  virtual ~LED() {}
153 
154  uint8_t extra () const { return _extra; }
155  uint8_t color_index () const { return _color_index; }
156  State state () const { return _state; }
157 
158  void set_color (uint8_t color_index);
160 
161  virtual MidiByteArray state_msg() const = 0;
162 
163  protected:
164  uint8_t _extra;
165  uint8_t _color_index;
167  };
168 
169  struct Pad : public LED {
170  enum WhenPressed {
174  };
175 
176  Pad (int xx, int yy, uint8_t ex)
177  : LED (ex)
178  , x (xx)
179  , y (yy)
181  , filtered (ex)
182  , perma_color (LED::Black)
183  {}
184 
186 
187  int coord () const { return (y * 8) + x; }
188  int note_number() const { return extra(); }
189 
190  int x;
191  int y;
193  int filtered;
195  };
196 
197  struct Button : public LED {
198  Button (ButtonID bb, uint8_t ex)
199  : LED (ex)
200  , id (bb)
201  , press_method (&Push2::relax)
204  {}
205 
206  Button (ButtonID bb, uint8_t ex, void (Push2::*press)())
207  : LED (ex)
208  , id (bb)
209  , press_method (press)
212  {}
213 
214  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
215  : LED (ex)
216  , id (bb)
217  , press_method (press)
220  {}
221 
222  Button (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
223  : LED (ex)
224  , id (bb)
225  , press_method (press)
227  , long_press_method (long_press)
228  {}
229 
231  int controller_number() const { return extra(); }
232 
234  void (Push2::*press_method)();
235  void (Push2::*release_method)();
237  sigc::connection timeout_connection;
238  };
239 
240  struct ColorButton : public Button {
241  ColorButton (ButtonID bb, uint8_t ex)
242  : Button (bb, ex) {}
243 
244 
245  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
246  : Button (bb, ex, press) {}
247 
248  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
249  : Button (bb, ex, press, release) {}
250 
251  ColorButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
252  : Button (bb, ex, press, release, long_press) {}
253  };
254 
255  struct WhiteButton : public Button {
256  WhiteButton (ButtonID bb, uint8_t ex)
257  : Button (bb, ex) {}
258 
259  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)())
260  : Button (bb, ex, press) {}
261 
262  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)())
263  : Button (bb, ex, press, release) {}
264 
265  WhiteButton (ButtonID bb, uint8_t ex, void (Push2::*press)(), void (Push2::*release)(), void (Push2::*long_press)())
266  : Button (bb, ex, press, release, long_press) {}
267  };
268 
269  enum ColorName {
272 
276 
280 
283 
288  };
289 
293  };
294 
295  public:
297  ~Push2 ();
298 
299  static bool available ();
300  static bool match_usb (uint16_t, uint16_t);
301  static bool probe (std::string&, std::string&);
302 
303  std::string input_port_name () const;
304  std::string output_port_name () const;
305 
306  bool has_editor () const { return true; }
307  void* get_gui () const;
308  void tear_down_gui ();
309 
310  int set_active (bool yn);
311  XMLNode& get_state() const;
312  int set_state (const XMLNode & node, int version);
313 
314  int pad_note (int row, int col) const;
315  PBD::Signal0<void> PadChange;
316 
318 
328  };
329 
336  enum RowInterval {
341  };
342 
345 
348 
371  void set_pad_scale_in_key (int root,
372  int octave,
374  NoteGridOrigin origin,
375  int ideal_vertical_semitones);
376 
396  void set_pad_scale_chromatic (int root,
397  int octave,
399  NoteGridOrigin origin,
400  int vertical_semitones);
401 
402  void set_pad_scale (int root,
403  int octave,
405  NoteGridOrigin origin,
407  bool inkey);
408 
409  PBD::Signal0<void> ScaleChange;
410 
411  MusicalMode::Type mode() const { return _mode; }
414  int scale_root() const { return _scale_root; }
415  int root_octave() const { return _root_octave; }
416  bool in_key() const { return _in_key; }
417 
420 
421  Push2Canvas* canvas() const { return _canvas; }
422 
424  None = 0,
425  ModShift = 0x1,
426  ModSelect = 0x2,
427  };
428 
430 
431  std::shared_ptr<Button> button_by_id (ButtonID);
432  static std::string button_name_by_id (ButtonID);
433 
435 
438 
441  PBD::Signal1<void,PressureMode> PressureModeChange;
442 
443  libusb_device_handle* usb_handle() const { return _handle; }
444 
445  bool stop_down () const { return _stop_down; }
446 
447  typedef std::map<int,std::shared_ptr<Pad> > PadMap;
448  PadMap const & nn_pad_map() const { return _nn_pad_map; }
449 
450  std::shared_ptr<Pad> pad_by_xy (int x, int y);
451  std::shared_ptr<Button> lower_button_by_column (uint32_t col);
452 
453  private:
454  libusb_device_handle* _handle;
456 
460  void device_release ();
461  void run_event_loop ();
463 
464  void relax () {}
465 
466  /* map of Buttons by CC */
467  typedef std::map<int,std::shared_ptr<Button> > CCButtonMap;
469  /* map of Buttons by ButtonID */
470  typedef std::map<ButtonID,std::shared_ptr<Button> > IDButtonMap;
472  std::set<ButtonID> _buttons_down;
473  std::set<ButtonID> _consumed;
474 
476  void start_press_timeout (std::shared_ptr<Button>, ButtonID);
477 
478  void init_buttons (bool startup);
479  void init_touch_strip (bool with_shift);
480 
481  /* map of Pads by note number (the "fixed" note number sent by the
482  * hardware, not the note number generated if the pad is touched)
483  */
485 
486  /* array of Pads by x,y duple (indexed as (x*8) + y */
487 
488  std::vector<std::shared_ptr<Pad> > _xy_pad_map;
489 
490  /* map of Pads by note number they generate (their "filtered" value)
491  */
492  typedef std::multimap<int,std::shared_ptr<Pad> > FNPadMap;
494 
495  void set_button_color (ButtonID, uint8_t color_index);
497  void set_led_color (ButtonID, uint8_t color_index);
499 
500  void build_maps ();
501 
506  void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
507 
511  void notify_parameter_changed (std::string);
513 
514  /* Button methods */
515  void button_play ();
517  void button_up ();
518  void button_down ();
519  void button_right ();
520  void button_left ();
522  void button_repeat ();
523  void button_mute ();
524  void button_solo ();
527  void button_new ();
528  void button_browse ();
529  void button_clip ();
530  void button_session ();
531  void button_undo ();
532  void button_fwd32t ();
533  void button_fwd32 ();
534  void button_fwd16t ();
535  void button_fwd16 ();
536  void button_fwd8t ();
537  void button_fwd8 ();
538  void button_fwd4t ();
539  void button_fwd4 ();
544  void button_master ();
560 
561  void button_upper (uint32_t n);
562  void button_lower (uint32_t n);
563 
564  void button_upper_1 () { button_upper (0); }
565  void button_upper_2 () { button_upper (1); }
566  void button_upper_3 () { button_upper (2); }
567  void button_upper_4 () { button_upper (3); }
568  void button_upper_5 () { button_upper (4); }
569  void button_upper_6 () { button_upper (5); }
570  void button_upper_7 () { button_upper (6); }
571  void button_upper_8 () { button_upper (7); }
572  void button_lower_1 () { button_lower (0); }
573  void button_lower_2 () { button_lower (1); }
574  void button_lower_3 () { button_lower (2); }
575  void button_lower_4 () { button_lower (3); }
576  void button_lower_5 () { button_lower (4); }
577  void button_lower_6 () { button_lower (5); }
578  void button_lower_7 () { button_lower (6); }
579  void button_lower_8 () { button_lower (7); }
580 
581  void start_shift ();
582  void end_shift ();
583 
584  /* non-strip encoders */
585 
586  void other_vpot (int, int);
587  void other_vpot_touch (int, bool);
588 
589  /* special Stripable */
590 
591  std::shared_ptr<ARDOUR::Stripable> _master;
592 
593  sigc::connection _vblank_connection;
594  bool vblank ();
595 
596  void splash ();
598 
599  /* the canvas */
600 
602 
603  /* Layouts */
604 
605  mutable Glib::Threads::Mutex layout_lock;
614 
616 
617  std::weak_ptr<ARDOUR::MidiTrack> _current_pad_target;
618 
619  /* GUI */
620 
621  mutable P2GUI* _gui;
622  void build_gui ();
623 
624  /* pad mapping */
625 
627 
633  bool _in_key;
636 
638 
639  void set_percussive_mode (bool);
640 
641  /* color map (device side) */
642 
643  typedef std::map<Gtkmm2ext::Color,uint8_t> ColorMap;
644  typedef std::stack<uint8_t> ColorMapFreeList;
648 
649  /* our own colors */
650 
651  typedef std::map<ColorName,Gtkmm2ext::Color> Colors;
655 
658 
661 
664 };
665 
666 } /* namespace */
667 
668 #endif /* __ardour_push2_h__ */
void None
Definition: TypeList.h:49
void handle_midi_note_off_message(MIDI::Parser &, MIDI::EventTwoBytes *)
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:656
void button_lower_8()
Definition: push2.h:579
uint8_t _selection_color
Definition: push2.h:659
Push2Canvas * _canvas
Definition: push2.h:601
libusb_device_handle * _handle
Definition: push2.h:454
void button_upper_1()
Definition: push2.h:564
void other_vpot_touch(int, bool)
NoteGridOrigin note_grid_origin()
Definition: push2.h:412
MusicalMode::Type mode() const
Definition: push2.h:411
Push2Layout * _splash_layout
Definition: push2.h:611
void notify_record_state_changed()
void notify_parameter_changed(std::string)
Push2Layout * _track_mix_layout
Definition: push2.h:610
void init_touch_strip(bool with_shift)
CCButtonMap _cc_button_map
Definition: push2.h:468
std::set< ButtonID > _buttons_down
Definition: push2.h:472
void button_upper_6()
Definition: push2.h:569
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:568
int root_octave() const
Definition: push2.h:415
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:339
@ Fourth
Major third or 4 semitones.
Definition: push2.h:338
@ Sequential
Perfect fifth or 7 semitones.
Definition: push2.h:340
void button_upper_4()
Definition: push2.h:567
void button_upper(uint32_t n)
std::vector< std::shared_ptr< Pad > > _xy_pad_map
Definition: push2.h:488
void notify_solo_active_changed(bool)
ModifierState _modifier_state
Definition: push2.h:455
PBD::Signal0< void > PadChange
Definition: push2.h:315
PadMap _nn_pad_map
Definition: push2.h:484
std::shared_ptr< Pad > pad_by_xy(int x, int y)
void set_pressure_mode(PressureMode)
NoteGridOrigin _note_grid_origin
Definition: push2.h:629
void button_upper_2()
Definition: push2.h:565
void button_upper_8()
Definition: push2.h:571
void button_lower_2()
Definition: push2.h:573
static bool match_usb(uint16_t, uint16_t)
std::map< int, std::shared_ptr< Button > > CCButtonMap
Definition: push2.h:467
void * get_gui() const
static bool available()
bool button_long_press_timeout(ButtonID id)
RowInterval row_interval() const
Definition: push2.h:413
void button_lower_5()
Definition: push2.h:576
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:443
bool has_editor() const
Definition: push2.h:306
PBD::microseconds_t _splash_start
Definition: push2.h:597
std::stack< uint8_t > ColorMapFreeList
Definition: push2.h:644
Push2Layout * _scale_layout
Definition: push2.h:609
void set_led_state(ButtonID, LED::State)
Push2Layout * current_layout() const
PBD::Signal1< void, PressureMode > PressureModeChange
Definition: push2.h:441
bool stop_down() const
Definition: push2.h:445
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:448
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
std::weak_ptr< ARDOUR::MidiTrack > _current_pad_target
Definition: push2.h:617
static bool probe(std::string &, std::string &)
RowInterval _row_interval
Definition: push2.h:630
sigc::connection _vblank_connection
Definition: push2.h:593
int set_state(const XMLNode &node, int version)
IDButtonMap _id_button_map
Definition: push2.h:471
bool _in_range_select
Definition: push2.h:662
std::set< ButtonID > _consumed
Definition: push2.h:473
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:645
Push2Layout * _current_layout
Definition: push2.h:606
int pad_note(int row, int col) const
Push2Layout * _previous_layout
Definition: push2.h:607
FNPadMap _fn_pad_map
Definition: push2.h:493
uint8_t _contrast_color
Definition: push2.h:660
void stripable_selection_changed()
bool in_key() const
Definition: push2.h:416
std::map< ButtonID, std::shared_ptr< Button > > IDButtonMap
Definition: push2.h:470
void set_percussive_mode(bool)
Push2Canvas * canvas() const
Definition: push2.h:421
void button_lower_3()
Definition: push2.h:574
void button_upper_3()
Definition: push2.h:566
std::string input_port_name() const
int scale_root() const
Definition: push2.h:414
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:643
void button_lower_6()
Definition: push2.h:577
MusicalMode::Type _mode
Definition: push2.h:628
void button_lower(uint32_t n)
std::multimap< int, std::shared_ptr< Pad > > FNPadMap
Definition: push2.h:492
PBD::Signal0< void > ScaleChange
Definition: push2.h:409
void button_lower_7()
Definition: push2.h:578
bool pad_filter(ARDOUR::MidiBuffer &in, ARDOUR::MidiBuffer &out) const
std::shared_ptr< ARDOUR::Stripable > _master
Definition: push2.h:591
std::shared_ptr< Button > button_by_id(ButtonID)
PressureMode pressure_mode() const
Definition: push2.h:439
std::map< int, std::shared_ptr< Pad > > PadMap
Definition: push2.h:447
Push2Layout * _cue_layout
Definition: push2.h:612
@ Fixed
Bottom left pad is always C, or as close as possible.
Definition: push2.h:326
@ Rooted
Bottom left pad is the scale root.
Definition: push2.h:327
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:651
ColorMapFreeList _color_map_free_list
Definition: push2.h:646
ModifierState modifier_state() const
Definition: push2.h:429
void button_lower_1()
Definition: push2.h:572
void button_lower_4()
Definition: push2.h:575
Glib::Threads::Mutex layout_lock
Definition: push2.h:605
void button_upper_7()
Definition: push2.h:570
Push2(ARDOUR::Session &)
PadNoteKind
"Kind" of pad that plays a note
Definition: push2.h:344
uint8_t get_color_index(Gtkmm2ext::Color rgba)
void init_buttons(bool startup)
Push2Layout * _mix_layout
Definition: push2.h:608
Definition: xml++.h:114
uint32_t Color
Definition: colors.h:33
unsigned short pitchbend_t
int64_t microseconds_t
Definition: microseconds.h:29
void(Push2::* press_method)()
Definition: push2.h:234
void(Push2::* release_method)()
Definition: push2.h:235
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:222
Button(ButtonID bb, uint8_t ex)
Definition: push2.h:198
sigc::connection timeout_connection
Definition: push2.h:237
Button(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:214
void(Push2::* long_press_method)()
Definition: push2.h:236
Button(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:206
int controller_number() const
Definition: push2.h:231
MidiByteArray state_msg() const
Definition: push2.h:230
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:248
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:245
ColorButton(ButtonID bb, uint8_t ex)
Definition: push2.h:241
ColorButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:251
void set_state(State state)
virtual MidiByteArray state_msg() const =0
uint8_t color_index() const
Definition: push2.h:155
State state() const
Definition: push2.h:156
void set_color(uint8_t color_index)
uint8_t extra() const
Definition: push2.h:154
int note_number() const
Definition: push2.h:188
MidiByteArray state_msg() const
Definition: push2.h:185
Pad(int xx, int yy, uint8_t ex)
Definition: push2.h:176
int coord() const
Definition: push2.h:187
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)(), void(Push2::*long_press)())
Definition: push2.h:265
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)(), void(Push2::*release)())
Definition: push2.h:262
WhiteButton(ButtonID bb, uint8_t ex, void(Push2::*press)())
Definition: push2.h:259
WhiteButton(ButtonID bb, uint8_t ex)
Definition: push2.h:256