Ardour  8.7-14-g57a6773833
cc121.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 W.P. van Paass
3  * Copyright (C) 2017-2018 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2018 Robin Gareus <robin@gareus.org>
5  *
6  * Thanks to Rolf Meyerhoff for reverse engineering the CC121 protocol.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef ardour_surface_cc121_h
24 #define ardour_surface_cc121_h
25 
26 #include <list>
27 #include <map>
28 #include <set>
29 #include <glibmm/threads.h>
30 
31 #define ABSTRACT_UI_EXPORTS
32 #include "pbd/abstract_ui.h"
33 
34 #include "ardour/types.h"
35 
37 
38 namespace PBD {
39  class Controllable;
40 }
41 
42 #include <midi++/types.h>
43 
44 //#include "pbd/signals.h"
45 
46 
47 //#include "midi_byte_array.h"
48 #include "control_protocol/types.h"
49 
50 #include "glibmm/main.h"
51 
52 namespace MIDI {
53  class Parser;
54  class Port;
55 }
56 
57 
58 namespace ARDOUR {
59  class AsyncMIDIPort;
60  class Bundle;
61  class Port;
62  class Session;
63  class MidiPort;
64 }
65 
66 
67 class MIDIControllable;
68 class MIDIFunction;
69 class MIDIAction;
70 
71 namespace ArdourSurface {
72 
73 struct CC121Request : public BaseUI::BaseRequestObject {
74 public:
77 };
78 
79 class CC121 : public ARDOUR::ControlProtocol, public AbstractUI<CC121Request> {
80  public:
82  virtual ~CC121();
83 
84  int set_active (bool yn);
85 
86  XMLNode& get_state () const;
87  int set_state (const XMLNode&, int version);
88 
89  bool has_editor () const { return true; }
90  void* get_gui () const;
91  void tear_down_gui ();
92 
93 
94  /* Note: because the CC121 speaks an inherently duplex protocol,
95  we do not implement get/set_feedback() since this aspect of
96  support for the protocol is not optional.
97  */
98 
100  int stop ();
101 
102  void thread_init ();
103 
104  PBD::Signal0<void> ConnectionChange;
105 
106  std::shared_ptr<ARDOUR::Port> input_port();
107  std::shared_ptr<ARDOUR::Port> output_port();
108 
109  enum ButtonID {
110  Rec = 0x00,
111  Solo = 0x08,
112  Mute = 0x10,
113  Left = 0x30,
114  Right = 0x31,
115  EButton = 0x33,
116  Function1 = 0x36,
117  Function2 = 0x37,
118  Function3 = 0x38,
119  Function4 = 0x39,
120  Value = 0x3A,
121  Footswitch = 0x3B,
122  FP_Read = 0x4A,
123  FP_Write = 0x4B,
124  Loop = 0x56,
125  ToStart = 0x58,
126  ToEnd = 0x5A,
127  Rewind = 0x5B,
128  Ffwd = 0x5C,
129  Stop = 0x5D,
130  Play = 0x5E,
131  RecEnable = 0x5F,
132  FaderTouch = 0x68,
133  EQ1Enable = 0x70,
134  EQ2Enable = 0x71,
135  EQ3Enable = 0x72,
136  EQ4Enable = 0x73,
137  EQType = 0x74,
138  AllBypass = 0x75,
139  Jog = 0x76,
140  Lock = 0x77,
141  InputMonitor = 0x78,
142  OpenVST = 0x79,
143  Output = 22
144  };
145 
146  enum ButtonState {
147  ShiftDown = 0x1,
148  RewindDown = 0x2,
149  StopDown = 0x4,
150  UserDown = 0x8,
151  LongPress = 0x10
152  };
153 
154  void set_action (ButtonID, std::string const& action_name, bool on_press, CC121::ButtonState = ButtonState (0));
155  std::string get_action (ButtonID, bool on_press, CC121::ButtonState = ButtonState (0));
156 
157  std::list<std::shared_ptr<ARDOUR::Bundle> > bundles ();
158 
160 
161  private:
162  std::shared_ptr<ARDOUR::Stripable> _current_stripable;
163  std::weak_ptr<ARDOUR::Stripable> pre_master_stripable;
164  std::weak_ptr<ARDOUR::Stripable> pre_monitor_stripable;
165 
166  std::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
167  std::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
168 
169  // Bundle to represent our input ports
170  std::shared_ptr<ARDOUR::Bundle> _input_bundle;
171  // Bundle to represent our output ports
172  std::shared_ptr<ARDOUR::Bundle> _output_bundle;
173 
175 
176  bool midi_input_handler (Glib::IOCondition ioc, std::shared_ptr<ARDOUR::AsyncMIDIPort> port);
177 
178  mutable void *gui;
179  void build_gui ();
180 
181  bool connection_handler (std::weak_ptr<ARDOUR::Port>, std::string name1, std::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
183 
186  OutputConnected = 0x2
187  };
188 
190  void connected ();
195  enum JogMode { scroll=1, zoom=2 };
197 
201 
206  /* void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);*/
207 
209 
210  friend class Button;
211 
212  class Button {
213  public:
214 
215  enum ActionType {
218  };
219 
220  Button (CC121& f, std::string const& str, ButtonID i)
221  : fp (f)
222  , name (str)
223  , id (i)
224  , flash (false)
225  {}
226 
227  void set_action (std::string const& action_name, bool on_press, CC121::ButtonState = ButtonState (0));
228  void set_action (boost::function<void()> function, bool on_press, CC121::ButtonState = ButtonState (0));
229  std::string get_action (bool press, CC121::ButtonState bs = ButtonState (0));
230 
231  void set_led_state (std::shared_ptr<MIDI::Port>, bool onoff);
232  void invoke (ButtonState bs, bool press);
233  bool uses_flash () const { return flash; }
234  void set_flash (bool yn) { flash = yn; }
235 
236  XMLNode& get_state () const;
237  int set_state (XMLNode const&);
238 
239  sigc::connection timeout_connection;
240 
241  private:
243  std::string name;
245  bool flash;
246 
247  struct ToDo {
249  /* could be a union if boost::function didn't require a
250  * constructor
251  */
252  std::string action_name;
253  boost::function<void()> function;
254  };
255 
256  typedef std::map<CC121::ButtonState,ToDo> ToDoMap;
259  };
260 
261  typedef std::map<ButtonID,Button> ButtonMap;
262 
265 
266  std::set<ButtonID> buttons_down;
267  std::set<ButtonID> consumed;
268 
269  void all_lights_out ();
270  void close ();
273 
278 
279  sigc::connection periodic_connection;
280  bool periodic ();
281 
282  sigc::connection heartbeat_connection;
283  sigc::connection blink_connection;
284  typedef std::list<ButtonID> Blinkers;
287  bool blink ();
288  bool beat ();
291 
292  void set_current_stripable (std::shared_ptr<ARDOUR::Stripable>);
294  void use_master ();
295  void use_monitor ();
299 
301  void map_solo ();
302  void map_mute ();
304  void map_recenable ();
305  void map_gain ();
306  void map_cut ();
307  void map_auto ();
308  void map_monitoring ();
309 
310  /* operations (defined in operations.cc) */
311 
312  void read ();
313  void write ();
314 
315  void input_monitor ();
316  void left ();
317  void right ();
318 
319  void touch ();
320  void off ();
321 
322  void undo ();
323  void redo ();
324  void solo ();
325  void mute ();
326  void jog ();
327  void rec_enable ();
328 
329  void set_controllable (std::shared_ptr<ARDOUR::AutomationControl>, float);
330 
331  void punch ();
332 };
333 
334 }
335 
336 #endif /* ardour_surface_cc121_h */
Button(CC121 &f, std::string const &str, ButtonID i)
Definition: cc121.h:220
void set_action(boost::function< void()> function, bool on_press, CC121::ButtonState=ButtonState(0))
sigc::connection timeout_connection
Definition: cc121.h:239
XMLNode & get_state() const
bool uses_flash() const
Definition: cc121.h:233
void set_led_state(std::shared_ptr< MIDI::Port >, bool onoff)
void invoke(ButtonState bs, bool press)
int set_state(XMLNode const &)
std::string get_action(bool press, CC121::ButtonState bs=ButtonState(0))
void set_action(std::string const &action_name, bool on_press, CC121::ButtonState=ButtonState(0))
std::map< CC121::ButtonState, ToDo > ToDoMap
Definition: cc121.h:256
void set_flash(bool yn)
Definition: cc121.h:234
std::list< std::shared_ptr< ARDOUR::Bundle > > bundles()
std::shared_ptr< ARDOUR::AsyncMIDIPort > _input_port
Definition: cc121.h:166
bool midi_input_handler(Glib::IOCondition ioc, std::shared_ptr< ARDOUR::AsyncMIDIPort > port)
sigc::connection blink_connection
Definition: cc121.h:283
CONTROL_PROTOCOL_THREADS_NEED_TEMPO_MAP_DECL()
std::shared_ptr< ARDOUR::AsyncMIDIPort > _output_port
Definition: cc121.h:167
void encoder_handler(MIDI::Parser &, MIDI::EventTwoBytes *tb)
void stop_blinking(ButtonID)
std::string get_action(ButtonID, bool on_press, CC121::ButtonState=ButtonState(0))
std::set< ButtonID > consumed
Definition: cc121.h:267
PBD::ScopedConnectionList session_connections
Definition: cc121.h:274
Button & get_button(ButtonID) const
void connect_session_signals()
void button_press_handler(MIDI::Parser &, MIDI::EventTwoBytes *tb)
std::shared_ptr< ARDOUR::Port > output_port()
int last_encoder_delta
Definition: cc121.h:200
PBD::ScopedConnectionList midi_connections
Definition: cc121.h:174
CC121(ARDOUR::Session &)
void stripable_selection_changed()
PBD::Signal0< void > ConnectionChange
Definition: cc121.h:104
sigc::connection heartbeat_connection
Definition: cc121.h:282
XMLNode & get_state() const
JogMode _jogmode
Definition: cc121.h:196
bool has_editor() const
Definition: cc121.h:89
std::shared_ptr< ARDOUR::Port > input_port()
std::shared_ptr< ARDOUR::Bundle > _input_bundle
Definition: cc121.h:170
std::map< ButtonID, Button > ButtonMap
Definition: cc121.h:261
PBD::microseconds_t last_encoder_time
Definition: cc121.h:198
void set_current_stripable(std::shared_ptr< ARDOUR::Stripable >)
bool connection_handler(std::weak_ptr< ARDOUR::Port >, std::string name1, std::weak_ptr< ARDOUR::Port >, std::string name2, bool yn)
void set_controllable(std::shared_ptr< ARDOUR::AutomationControl >, float)
bool fader_is_touched
Definition: cc121.h:194
ButtonMap buttons
Definition: cc121.h:263
void set_action(ButtonID, std::string const &action_name, bool on_press, CC121::ButtonState=ButtonState(0))
std::shared_ptr< ARDOUR::Stripable > _current_stripable
Definition: cc121.h:162
std::weak_ptr< ARDOUR::Stripable > pre_monitor_stripable
Definition: cc121.h:164
Blinkers blinkers
Definition: cc121.h:285
int set_active(bool yn)
int set_state(const XMLNode &, int version)
int last_good_encoder_delta
Definition: cc121.h:199
ButtonState button_state
Definition: cc121.h:208
std::set< ButtonID > buttons_down
Definition: cc121.h:266
sigc::connection periodic_connection
Definition: cc121.h:279
void start_blinking(ButtonID)
void do_request(CC121Request *)
std::shared_ptr< ARDOUR::Bundle > _output_bundle
Definition: cc121.h:172
int last_last_encoder_delta
Definition: cc121.h:200
void button_release_handler(MIDI::Parser &, MIDI::EventTwoBytes *tb)
PBD::ScopedConnection selection_connection
Definition: cc121.h:297
PBD::ScopedConnectionList stripable_connections
Definition: cc121.h:298
void * get_gui() const
std::list< ButtonID > Blinkers
Definition: cc121.h:284
PBD::ScopedConnection port_connection
Definition: cc121.h:182
bool rec_enable_state
Definition: cc121.h:303
std::weak_ptr< ARDOUR::Stripable > pre_master_stripable
Definition: cc121.h:163
void fader_handler(MIDI::Parser &, MIDI::pitchbend_t pb)
Definition: xml++.h:114
std::shared_ptr< PBD::Controllable > Controllable
Definition: console1.h:80
unsigned short pitchbend_t
Definition: axis_view.h:42
int64_t microseconds_t
Definition: microseconds.h:29
Definition: lobject.h:100