8f920dfc4f0e04c829dfeebe5ea99cdd098aea02
[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 <glibmm/threads.h>
26
27 #define ABSTRACT_UI_EXPORTS
28 #include "pbd/abstract_ui.h"
29
30 #include "ardour/types.h"
31
32 #include "control_protocol/control_protocol.h"
33
34 namespace PBD {
35         class Controllable;
36         class ControllableDescriptor;
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 Port;
58         class Session;
59         class MidiPort;
60 }
61
62
63 class MIDIControllable;
64 class MIDIFunction;
65 class MIDIAction;
66
67 namespace ArdourSurface {
68
69 struct FaderPortRequest : public BaseUI::BaseRequestObject {
70 public:
71         FaderPortRequest () {}
72         ~FaderPortRequest () {}
73 };
74
75 class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortRequest> {
76   public:
77         FaderPort (ARDOUR::Session&);
78         virtual ~FaderPort();
79
80         int set_active (bool yn);
81
82         /* we probe for a device when our ports are connected. Before that,
83            there's no way to know if the device exists or not.
84          */
85         static bool probe() { return true; }
86
87         XMLNode& get_state ();
88         int set_state (const XMLNode&, int version);
89
90         bool has_editor () const { return true; }
91         void* get_gui () const;
92         void  tear_down_gui ();
93
94         /* Note: because the FaderPort 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
99         void do_request (FaderPortRequest*);
100         int stop ();
101
102         void thread_init ();
103
104         PBD::Signal0<void> ConnectionChange;
105
106         boost::shared_ptr<ARDOUR::Port> input_port();
107         boost::shared_ptr<ARDOUR::Port> output_port();
108
109         enum ButtonID {
110                 Mute = 18,
111                 Solo = 17,
112                 Rec = 16,
113                 Left = 19,
114                 Bank = 20,
115                 Right = 21,
116                 Output = 22,
117                 FP_Read = 10,
118                 FP_Write = 9,
119                 FP_Touch = 8,
120                 FP_Off = 23,
121                 Mix = 11,
122                 Proj = 12,
123                 Trns = 13,
124                 Undo = 14,
125                 Shift = 2,
126                 Punch = 1,
127                 User = 0,
128                 Loop = 15,
129                 Rewind = 3,
130                 Ffwd = 4,
131                 Stop = 5,
132                 Play = 6,
133                 RecEnable = 7,
134                 FaderTouch = 127,
135         };
136
137         enum ButtonState {
138                 ShiftDown = 0x1,
139                 RewindDown = 0x2,
140                 StopDown = 0x4,
141                 UserDown = 0x8,
142         };
143
144         void set_action (ButtonID, std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
145
146   private:
147         boost::shared_ptr<ARDOUR::Route> _current_route;
148         boost::weak_ptr<ARDOUR::Route> pre_master_route;
149         boost::weak_ptr<ARDOUR::Route> pre_monitor_route;
150
151         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
152         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
153
154         PBD::ScopedConnectionList midi_connections;
155
156         bool midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port);
157
158         mutable void *gui;
159         void build_gui ();
160
161         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
162         PBD::ScopedConnection port_connection;
163
164         enum ConnectionState {
165                 InputConnected = 0x1,
166                 OutputConnected = 0x2
167         };
168
169         int connection_state;
170         void connected ();
171         bool _device_active;
172         int fader_msb;
173         int fader_lsb;
174         bool fader_is_touched;
175
176         ARDOUR::microseconds_t last_encoder_time;
177         int last_good_encoder_delta;
178         int last_encoder_delta, last_last_encoder_delta;
179
180         void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
181         void switch_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
182         void encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb);
183         void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
184
185         ButtonState button_state;
186
187         friend class ButtonInfo;
188
189         class ButtonInfo {
190           public:
191
192                 enum ActionType {
193                         NamedAction,
194                         InternalFunction,
195                 };
196
197                 ButtonInfo (FaderPort& f, std::string const& str, ButtonID i, int o)
198                         : fp (f)
199                         , name (str)
200                         , id (i)
201                         , out (o)
202                         , type (NamedAction)
203                         , led_on (false)
204                         , flash (false)
205                 {}
206
207                 void set_action (std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
208                 void set_action (boost::function<void()> function, bool on_press, FaderPort::ButtonState = ButtonState (0));
209                 void set_led_state (boost::shared_ptr<MIDI::Port>, int onoff, bool force = false);
210                 void invoke (ButtonState bs, bool press);
211                 bool uses_flash () const { return flash; }
212                 void set_flash (bool yn) { flash = yn; }
213
214           private:
215                 FaderPort& fp;
216                 std::string name;
217                 ButtonID id;
218                 int out;
219                 ActionType type;
220                 bool led_on;
221                 bool flash;
222
223                 /* could be a union if boost::function didn't require a
224                  * constructor
225                  */
226                 struct ToDo {
227                         std::string action_name;
228                         boost::function<void()> function;
229                 };
230
231                 typedef std::map<FaderPort::ButtonState,ToDo> ToDoMap;
232                 ToDoMap on_press;
233                 ToDoMap on_release;
234         };
235
236         typedef std::map<ButtonID,ButtonInfo> ButtonMap;
237
238         ButtonMap buttons;
239         ButtonInfo& button_info (ButtonID) const;
240
241         void all_lights_out ();
242         void close ();
243         void start_midi_handling ();
244         void stop_midi_handling ();
245
246         PBD::ScopedConnectionList session_connections;
247         void connect_session_signals ();
248         void notify_record_state_changed ();
249         void notify_transport_state_changed ();
250
251         sigc::connection blink_connection;
252         typedef std::list<ButtonID> Blinkers;
253         Blinkers blinkers;
254         bool blink_state;
255         bool blink ();
256
257         void set_current_route (boost::shared_ptr<ARDOUR::Route>);
258         void drop_current_route ();
259         void use_master ();
260         void use_monitor ();
261         void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr);
262         PBD::ScopedConnection selection_connection;
263         PBD::ScopedConnectionList route_connections;
264
265         void map_route_state ();
266         void map_solo (bool,void*,bool);
267         void map_listen (void*,bool);
268         void map_mute (void*);
269         void map_recenable ();
270         void map_gain ();
271         void map_cut ();
272
273         /* operations (defined in operations.cc) */
274
275         void read ();
276         void write ();
277
278         void left ();
279         void right ();
280
281         void touch ();
282         void off ();
283
284         void undo ();
285         void redo ();
286         void solo ();
287         void mute ();
288         void rec_enable ();
289
290         void ardour_pan_azimuth (int);
291         void ardour_pan_width (int);
292         void mixbus_pan (int);
293 };
294
295 }
296
297 #endif /* ardour_surface_faderport_h */