Only show user-presets in favorite sidebar
[ardour.git] / libs / surfaces / faderport / faderport.h
1 /*
2     Copyright (C) 2006 Paul Davis
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
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef ardour_surface_faderport_h
21 #define ardour_surface_faderport_h
22
23 #include <list>
24 #include <map>
25 #include <set>
26 #include <glibmm/threads.h>
27
28 #define ABSTRACT_UI_EXPORTS
29 #include "pbd/abstract_ui.h"
30
31 #include "ardour/types.h"
32
33 #include "control_protocol/control_protocol.h"
34
35 namespace PBD {
36         class Controllable;
37 }
38
39 #include <midi++/types.h>
40
41 //#include "pbd/signals.h"
42
43
44 //#include "midi_byte_array.h"
45 #include "types.h"
46
47 #include "glibmm/main.h"
48
49 namespace MIDI {
50         class Parser;
51         class Port;
52 }
53
54
55 namespace ARDOUR {
56         class AsyncMIDIPort;
57         class Bundle;
58         class Port;
59         class Session;
60         class MidiPort;
61 }
62
63
64 class MIDIControllable;
65 class MIDIFunction;
66 class MIDIAction;
67
68 namespace ArdourSurface {
69
70 struct FaderPortRequest : public BaseUI::BaseRequestObject {
71 public:
72         FaderPortRequest () {}
73         ~FaderPortRequest () {}
74 };
75
76 class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortRequest> {
77   public:
78         FaderPort (ARDOUR::Session&);
79         virtual ~FaderPort();
80
81         int set_active (bool yn);
82
83         /* we probe for a device when our ports are connected. Before that,
84            there's no way to know if the device exists or not.
85          */
86         static bool probe() { return true; }
87         static void* request_factory (uint32_t);
88
89         XMLNode& get_state ();
90         int set_state (const XMLNode&, int version);
91
92         bool has_editor () const { return true; }
93         void* get_gui () const;
94         void  tear_down_gui ();
95
96         /* Note: because the FaderPort speaks an inherently duplex protocol,
97            we do not implement get/set_feedback() since this aspect of
98            support for the protocol is not optional.
99         */
100
101         void do_request (FaderPortRequest*);
102         int stop ();
103
104         void thread_init ();
105
106         PBD::Signal0<void> ConnectionChange;
107
108         boost::shared_ptr<ARDOUR::Port> input_port();
109         boost::shared_ptr<ARDOUR::Port> output_port();
110
111         /* In a feat of engineering brilliance, the Presonus Faderport sends
112          * one button identifier when the button is pressed/released, but
113          * responds to another button identifier as a command to light the LED
114          * corresponding to the button. These ID's define what is sent
115          * for press/release; a separate data structure contains information
116          * on what to send to turn the LED on/off.
117          *
118          * One can only conclude that Presonus just didn't want to fix this
119          * issue because it contradicts their own documentation and is more or
120          * less the first thing you discover when programming the device.
121          */
122
123         enum ButtonID {
124                 Mute = 18,
125                 Solo = 17,
126                 Rec = 16,
127                 Left = 19,
128                 Bank = 20,
129                 Right = 21,
130                 Output = 22,
131                 FP_Read = 10,
132                 FP_Write = 9,
133                 FP_Touch = 8,
134                 FP_Off = 23,
135                 Mix = 11,
136                 Proj = 12,
137                 Trns = 13,
138                 Undo = 14,
139                 Shift = 2,
140                 Punch = 1,
141                 User = 0,
142                 Loop = 15,
143                 Rewind = 3,
144                 Ffwd = 4,
145                 Stop = 5,
146                 Play = 6,
147                 RecEnable = 7,
148                 Footswitch = 126,
149                 FaderTouch = 127,
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, FaderPort::ButtonState = ButtonState (0));
161         std::string get_action (ButtonID, bool on_press, FaderPort::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::weak_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
200         ARDOUR::microseconds_t last_encoder_time;
201         int last_good_encoder_delta;
202         int last_encoder_delta, last_last_encoder_delta;
203
204         void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
205         void button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
206         void encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb);
207         void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
208
209         ButtonState button_state;
210
211         friend class Button;
212
213         class Button {
214           public:
215
216                 enum ActionType {
217                         NamedAction,
218                         InternalFunction,
219                 };
220
221                 Button (FaderPort& f, std::string const& str, ButtonID i, int o)
222                         : fp (f)
223                         , name (str)
224                         , id (i)
225                         , out (o)
226                         , flash (false)
227                 {}
228
229                 void set_action (std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
230                 void set_action (boost::function<void()> function, bool on_press, FaderPort::ButtonState = ButtonState (0));
231                 std::string get_action (bool press, FaderPort::ButtonState bs = ButtonState (0));
232
233                 void set_led_state (boost::shared_ptr<MIDI::Port>, bool onoff);
234                 bool invoke (ButtonState bs, bool press);
235                 bool uses_flash () const { return flash; }
236                 void set_flash (bool yn) { flash = yn; }
237
238                 XMLNode& get_state () const;
239                 int set_state (XMLNode const&);
240
241                 sigc::connection timeout_connection;
242
243           private:
244                 FaderPort& fp;
245                 std::string name;
246                 ButtonID id;
247                 int out;
248                 bool flash;
249
250                 struct ToDo {
251                         ActionType type;
252                         /* could be a union if boost::function didn't require a
253                          * constructor
254                          */
255                         std::string action_name;
256                         boost::function<void()> function;
257                 };
258
259                 typedef std::map<FaderPort::ButtonState,ToDo> ToDoMap;
260                 ToDoMap on_press;
261                 ToDoMap on_release;
262         };
263
264         typedef std::map<ButtonID,Button> ButtonMap;
265
266         ButtonMap buttons;
267         Button& get_button (ButtonID) const;
268
269         std::set<ButtonID> buttons_down;
270         std::set<ButtonID> consumed;
271
272         bool button_long_press_timeout (ButtonID id);
273         void start_press_timeout (Button&, ButtonID);
274
275         void all_lights_out ();
276         void close ();
277         void start_midi_handling ();
278         void stop_midi_handling ();
279
280         PBD::ScopedConnectionList session_connections;
281         void connect_session_signals ();
282         void map_recenable_state ();
283         void map_transport_state ();
284
285         sigc::connection periodic_connection;
286         bool periodic ();
287
288         sigc::connection blink_connection;
289         typedef std::list<ButtonID> Blinkers;
290         Blinkers blinkers;
291         bool blink_state;
292         bool blink ();
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 parameter_changed (std::string);
313
314         /* operations (defined in operations.cc) */
315
316         void read ();
317         void write ();
318
319         void left ();
320         void right ();
321
322         void touch ();
323         void off ();
324
325         void undo ();
326         void redo ();
327         void solo ();
328         void mute ();
329         void rec_enable ();
330
331         void ardour_pan_azimuth (int);
332         void ardour_pan_width (int);
333         void mixbus_pan (int);
334
335         void punch ();
336 };
337
338 }
339
340 #endif /* ardour_surface_faderport_h */