Update classkeys to match new total LuaSignal count (windows only)
[ardour.git] / libs / surfaces / cc121 / cc121.h
1 /*
2     Copyright (C) 2006 Paul Davis
3     Copyright (C) 2016 W.P. van Paassen
4
5     Thanks to Rolf Meyerhoff for reverse engineering the CC121 protocol.
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
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
36 #include "control_protocol/control_protocol.h"
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 "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:
75         CC121Request () {}
76         ~CC121Request () {}
77 };
78
79 class CC121 : public ARDOUR::ControlProtocol, public AbstractUI<CC121Request> {
80   public:
81         CC121 (ARDOUR::Session&);
82         virtual ~CC121();
83
84         int set_active (bool yn);
85
86         /* we probe for a device when our ports are connected. Before that,
87            there's no way to know if the device exists or not.
88          */
89         static bool probe() { return true; }
90         static void* request_factory (uint32_t);
91
92         XMLNode& get_state ();
93         int set_state (const XMLNode&, int version);
94
95         bool has_editor () const { return true; }
96         void* get_gui () const;
97         void  tear_down_gui ();
98
99
100         /* Note: because the CC121 speaks an inherently duplex protocol,
101            we do not implement get/set_feedback() since this aspect of
102            support for the protocol is not optional.
103         */
104
105         void do_request (CC121Request*);
106         int stop ();
107
108         void thread_init ();
109
110         PBD::Signal0<void> ConnectionChange;
111
112         boost::shared_ptr<ARDOUR::Port> input_port();
113         boost::shared_ptr<ARDOUR::Port> output_port();
114
115         enum ButtonID {
116                 Rec = 0x00,
117                 Solo = 0x08,
118                 Mute = 0x10,
119                 Left = 0x30,
120                 Right = 0x31,
121                 EButton = 0x33,
122                 Function1 = 0x36,
123                 Function2 = 0x37,
124                 Function3 = 0x38,
125                 Function4 = 0x39,
126                 Value = 0x3A,
127                 Footswitch = 0x3B,
128                 FP_Read = 0x4A,
129                 FP_Write = 0x4B,
130                 Loop = 0x56,
131                 ToStart = 0x58,
132                 ToEnd = 0x5A,
133                 Rewind = 0x5B,
134                 Ffwd = 0x5C,
135                 Stop = 0x5D,
136                 Play = 0x5E,
137                 RecEnable = 0x5F,
138                 FaderTouch = 0x68,
139                 EQ1Enable = 0x70,
140                 EQ2Enable = 0x71,
141                 EQ3Enable = 0x72,
142                 EQ4Enable = 0x73,
143                 EQType = 0x74,
144                 AllBypass = 0x75,
145                 Jog = 0x76,
146                 Lock = 0x77,
147                 InputMonitor = 0x78,
148                 OpenVST = 0x79,
149                 Output = 22
150         };
151
152         enum ButtonState {
153           ShiftDown = 0x1,
154                 RewindDown = 0x2,
155                 StopDown = 0x4,
156                 UserDown = 0x8,
157                 LongPress = 0x10
158         };
159
160         void set_action (ButtonID, std::string const& action_name, bool on_press, CC121::ButtonState = ButtonState (0));
161         std::string get_action (ButtonID, bool on_press, CC121::ButtonState = ButtonState (0));
162
163         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
164
165   private:
166         boost::shared_ptr<ARDOUR::Stripable> _current_stripable;
167         boost::weak_ptr<ARDOUR::Stripable> pre_master_stripable;
168         boost::weak_ptr<ARDOUR::Stripable> pre_monitor_stripable;
169
170         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
171         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
172
173         // Bundle to represent our input ports
174         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
175         // Bundle to represent our output ports
176         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
177
178         PBD::ScopedConnectionList midi_connections;
179
180         bool midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port);
181
182         mutable void *gui;
183         void build_gui ();
184
185         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
186         PBD::ScopedConnection port_connection;
187
188         enum ConnectionState {
189                 InputConnected = 0x1,
190                 OutputConnected = 0x2
191         };
192
193         int connection_state;
194         void connected ();
195         bool _device_active;
196         int fader_msb;
197         int fader_lsb;
198         bool fader_is_touched;
199         enum JogMode { scroll=1, zoom=2 };
200         JogMode _jogmode;
201
202         ARDOUR::microseconds_t last_encoder_time;
203         int last_good_encoder_delta;
204         int last_encoder_delta, last_last_encoder_delta;
205
206         void button_press_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
207         void button_release_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
208         void fader_handler (MIDI::Parser &, MIDI::pitchbend_t pb);
209         void encoder_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
210         /*      void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);*/
211
212         ButtonState button_state;
213
214         friend class Button;
215
216         class Button {
217           public:
218
219                 enum ActionType {
220                         NamedAction,
221                         InternalFunction,
222                 };
223
224                 Button (CC121& f, std::string const& str, ButtonID i)
225                         : fp (f)
226                         , name (str)
227                         , id (i)
228                         , flash (false)
229                 {}
230
231                 void set_action (std::string const& action_name, bool on_press, CC121::ButtonState = ButtonState (0));
232                 void set_action (boost::function<void()> function, bool on_press, CC121::ButtonState = ButtonState (0));
233                 std::string get_action (bool press, CC121::ButtonState bs = ButtonState (0));
234
235                 void set_led_state (boost::shared_ptr<MIDI::Port>, bool onoff);
236                 void invoke (ButtonState bs, bool press);
237                 bool uses_flash () const { return flash; }
238                 void set_flash (bool yn) { flash = yn; }
239
240                 XMLNode& get_state () const;
241                 int set_state (XMLNode const&);
242
243                 sigc::connection timeout_connection;
244
245           private:
246                 CC121& fp;
247                 std::string name;
248                 ButtonID id;
249                 bool flash;
250
251                 struct ToDo {
252                         ActionType type;
253                         /* could be a union if boost::function didn't require a
254                          * constructor
255                          */
256                         std::string action_name;
257                         boost::function<void()> function;
258                 };
259
260                 typedef std::map<CC121::ButtonState,ToDo> ToDoMap;
261                 ToDoMap on_press;
262                 ToDoMap on_release;
263         };
264
265         typedef std::map<ButtonID,Button> ButtonMap;
266
267         ButtonMap buttons;
268         Button& get_button (ButtonID) const;
269
270         std::set<ButtonID> buttons_down;
271         std::set<ButtonID> consumed;
272
273         void all_lights_out ();
274         void close ();
275         void start_midi_handling ();
276         void stop_midi_handling ();
277
278         PBD::ScopedConnectionList session_connections;
279         void connect_session_signals ();
280         void map_recenable_state ();
281         void map_transport_state ();
282
283         sigc::connection periodic_connection;
284         bool periodic ();
285
286         sigc::connection heartbeat_connection;
287         sigc::connection blink_connection;
288         typedef std::list<ButtonID> Blinkers;
289         Blinkers blinkers;
290         bool blink_state;
291         bool blink ();
292         bool beat ();
293         void start_blinking (ButtonID);
294         void stop_blinking (ButtonID);
295
296         void set_current_stripable (boost::shared_ptr<ARDOUR::Stripable>);
297         void drop_current_stripable ();
298         void use_master ();
299         void use_monitor ();
300         void stripable_selection_changed ();
301         PBD::ScopedConnection selection_connection;
302         PBD::ScopedConnectionList stripable_connections;
303
304         void map_stripable_state ();
305         void map_solo ();
306         void map_mute ();
307         bool rec_enable_state;
308         void map_recenable ();
309         void map_gain ();
310         void map_cut ();
311         void map_auto ();
312         void map_monitoring ();
313
314         /* operations (defined in operations.cc) */
315
316         void read ();
317         void write ();
318
319         void input_monitor ();
320         void left ();
321         void right ();
322
323         void touch ();
324         void off ();
325
326         void undo ();
327         void redo ();
328         void solo ();
329         void mute ();
330         void jog ();
331         void rec_enable ();
332
333         void set_controllable (boost::shared_ptr<ARDOUR::AutomationControl>, float);
334
335         void punch ();
336 };
337
338 }
339
340 #endif /* ardour_surface_cc121_h */