c92ab38c780738b88b4c8a01422dda636d92249c
[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         class ControllableDescriptor;
38 }
39
40 #include <midi++/types.h>
41
42 //#include "pbd/signals.h"
43
44
45 //#include "midi_byte_array.h"
46 #include "types.h"
47
48 #include "glibmm/main.h"
49
50 namespace MIDI {
51         class Parser;
52         class Port;
53 }
54
55
56 namespace ARDOUR {
57         class AsyncMIDIPort;
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
88         XMLNode& get_state ();
89         int set_state (const XMLNode&, int version);
90
91         bool has_editor () const { return true; }
92         void* get_gui () const;
93         void  tear_down_gui ();
94
95         /* Note: because the FaderPort speaks an inherently duplex protocol,
96            we do not implement get/set_feedback() since this aspect of
97            support for the protocol is not optional.
98         */
99
100         void do_request (FaderPortRequest*);
101         int stop ();
102
103         void thread_init ();
104
105         PBD::Signal0<void> ConnectionChange;
106
107         boost::shared_ptr<ARDOUR::Port> input_port();
108         boost::shared_ptr<ARDOUR::Port> output_port();
109
110         /* In a feat of engineering brilliance, the Presonus Faderport sends
111          * one button identifier when the button is pressed/released, but
112          * responds to another button identifier as a command to light the LED
113          * corresponding to the button. These ID's define what is sent
114          * for press/release; a separate data structure contains information
115          * on what to send to turn the LED on/off.
116          *
117          * One can only conclude that Presonus just didn't want to fix this
118          * issue because it contradicts their own documentation and is more or
119          * less the first thing you discover when programming the device.
120          */
121
122         enum ButtonID {
123                 Mute = 18,
124                 Solo = 17,
125                 Rec = 16,
126                 Left = 19,
127                 Bank = 20,
128                 Right = 21,
129                 Output = 22,
130                 FP_Read = 10,
131                 FP_Write = 9,
132                 FP_Touch = 8,
133                 FP_Off = 23,
134                 Mix = 11,
135                 Proj = 12,
136                 Trns = 13,
137                 Undo = 14,
138                 Shift = 2,
139                 Punch = 1,
140                 User = 0,
141                 Loop = 15,
142                 Rewind = 3,
143                 Ffwd = 4,
144                 Stop = 5,
145                 Play = 6,
146                 RecEnable = 7,
147                 FaderTouch = 127,
148         };
149
150         enum ButtonState {
151                 ShiftDown = 0x1,
152                 RewindDown = 0x2,
153                 StopDown = 0x4,
154                 UserDown = 0x8,
155                 LongPress = 0x10
156         };
157
158         void set_action (ButtonID, std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
159         std::string get_action (ButtonID, bool on_press, FaderPort::ButtonState = ButtonState (0));
160
161   private:
162         boost::shared_ptr<ARDOUR::Route> _current_route;
163         boost::weak_ptr<ARDOUR::Route> pre_master_route;
164         boost::weak_ptr<ARDOUR::Route> pre_monitor_route;
165
166         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
167         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
168
169         PBD::ScopedConnectionList midi_connections;
170
171         bool midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port);
172
173         mutable void *gui;
174         void build_gui ();
175
176         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
177         PBD::ScopedConnection port_connection;
178
179         enum ConnectionState {
180                 InputConnected = 0x1,
181                 OutputConnected = 0x2
182         };
183
184         int connection_state;
185         void connected ();
186         bool _device_active;
187         int fader_msb;
188         int fader_lsb;
189         bool fader_is_touched;
190
191         ARDOUR::microseconds_t last_encoder_time;
192         int last_good_encoder_delta;
193         int last_encoder_delta, last_last_encoder_delta;
194
195         void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
196         void button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
197         void encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb);
198         void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
199
200         ButtonState button_state;
201
202         friend class Button;
203
204         class Button {
205           public:
206
207                 enum ActionType {
208                         NamedAction,
209                         InternalFunction,
210                 };
211
212                 Button (FaderPort& f, std::string const& str, ButtonID i, int o)
213                         : fp (f)
214                         , name (str)
215                         , id (i)
216                         , out (o)
217                         , led_on (false)
218                         , flash (false)
219                 {}
220
221                 void set_action (std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
222                 void set_action (boost::function<void()> function, bool on_press, FaderPort::ButtonState = ButtonState (0));
223                 std::string get_action (bool press, FaderPort::ButtonState bs = ButtonState (0));
224
225                 void set_led_state (boost::shared_ptr<MIDI::Port>, int onoff, bool force = false);
226                 void invoke (ButtonState bs, bool press);
227                 bool uses_flash () const { return flash; }
228                 void set_flash (bool yn) { flash = yn; }
229
230                 XMLNode& get_state () const;
231                 int set_state (XMLNode const&);
232
233                 sigc::connection timeout_connection;
234
235           private:
236                 FaderPort& fp;
237                 std::string name;
238                 ButtonID id;
239                 int out;
240                 bool led_on;
241                 bool flash;
242
243                 struct ToDo {
244                         ActionType type;
245                         /* could be a union if boost::function didn't require a
246                          * constructor
247                          */
248                         std::string action_name;
249                         boost::function<void()> function;
250                 };
251
252                 typedef std::map<FaderPort::ButtonState,ToDo> ToDoMap;
253                 ToDoMap on_press;
254                 ToDoMap on_release;
255         };
256
257         typedef std::map<ButtonID,Button> ButtonMap;
258
259         ButtonMap buttons;
260         Button& get_button (ButtonID) const;
261
262         std::set<ButtonID> buttons_down;
263
264         bool button_long_press_timeout (ButtonID id);
265         void start_press_timeout (Button&, ButtonID);
266
267         void all_lights_out ();
268         void close ();
269         void start_midi_handling ();
270         void stop_midi_handling ();
271
272         PBD::ScopedConnectionList session_connections;
273         void connect_session_signals ();
274         void notify_record_state_changed ();
275         void notify_transport_state_changed ();
276
277         sigc::connection blink_connection;
278         typedef std::list<ButtonID> Blinkers;
279         Blinkers blinkers;
280         bool blink_state;
281         bool blink ();
282
283         void set_current_route (boost::shared_ptr<ARDOUR::Route>);
284         void drop_current_route ();
285         void use_master ();
286         void use_monitor ();
287         void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr);
288         PBD::ScopedConnection selection_connection;
289         PBD::ScopedConnectionList route_connections;
290
291         void map_route_state ();
292         void map_solo (bool,void*,bool);
293         void map_listen (void*,bool);
294         void map_mute (void*);
295         void map_recenable ();
296         void map_gain ();
297         void map_cut ();
298         void parameter_changed (std::string);
299
300         /* operations (defined in operations.cc) */
301
302         void read ();
303         void write ();
304
305         void left ();
306         void right ();
307
308         void touch ();
309         void off ();
310
311         void undo ();
312         void redo ();
313         void solo ();
314         void mute ();
315         void rec_enable ();
316
317         void ardour_pan_azimuth (int);
318         void ardour_pan_width (int);
319         void mixbus_pan (int);
320
321         void punch ();
322 };
323
324 }
325
326 #endif /* ardour_surface_faderport_h */