US2400: allow selecting the master bus. LED does not respond, though :(
[ardour.git] / libs / surfaces / us2400 / us2400_control_protocol.h
1 /*
2     Copyright (C) 2006,2007 John Anderson
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 #ifndef ardour_us2400_control_protocol_h
20 #define ardour_us2400_control_protocol_h
21
22 #include <vector>
23 #include <map>
24 #include <list>
25 #include <set>
26
27 #include <sys/time.h>
28 #include <pthread.h>
29 #include <boost/smart_ptr.hpp>
30
31 #define ABSTRACT_UI_EXPORTS
32 #include "pbd/abstract_ui.h"
33 #include "midi++/types.h"
34 #include "ardour/types.h"
35 #include "control_protocol/control_protocol.h"
36
37 #include "types.h"
38 #include "midi_byte_array.h"
39 #include "controls.h"
40 #include "jog_wheel.h"
41 #include "timer.h"
42 #include "device_info.h"
43 #include "device_profile.h"
44
45 namespace ARDOUR {
46         class AutomationControl;
47         class Port;
48 }
49
50 namespace MIDI {
51         class Port;
52 }
53
54 namespace ArdourSurface {
55
56 namespace US2400 {
57         class Surface;
58         class Control;
59         class SurfacePort;
60         class Button;
61         class Strip;
62 }
63
64 struct US2400ControlUIRequest : public BaseUI::BaseRequestObject {
65 public:
66         US2400ControlUIRequest () {}
67         ~US2400ControlUIRequest () {}
68 };
69
70 class US2400Protocol
71         : public ARDOUR::ControlProtocol
72         , public AbstractUI<US2400ControlUIRequest>
73 {
74   public:
75         static const int MODIFIER_OPTION;
76         static const int MODIFIER_CONTROL;
77         static const int MODIFIER_SHIFT;
78         static const int MODIFIER_CMDALT;
79         static const int MODIFIER_ZOOM;
80         static const int MODIFIER_SCRUB;
81         static const int MODIFIER_MARKER;
82         static const int MODIFIER_DROP;  //US2400 replaces MODIFIER_NUDGE which is unused
83         static const int MAIN_MODIFIER_MASK;
84
85         enum ViewMode {
86                 Mixer,
87                 Busses,
88         };
89
90         enum SubViewMode {
91                 None,
92                 TrackView,
93         };
94
95         US2400Protocol(ARDOUR::Session &);
96         virtual ~US2400Protocol();
97
98         static US2400Protocol* instance() { return _instance; }
99
100         const US2400::DeviceInfo& device_info() const { return _device_info; }
101         US2400::DeviceProfile& device_profile() { return _device_profile; }
102
103         PBD::Signal0<void> DeviceChanged;
104         PBD::Signal1<void,boost::shared_ptr<US2400::Surface> > ConnectionChange;
105
106         void device_ready ();
107
108         int set_active (bool yn);
109         int  set_device (const std::string&, bool force);
110         void set_profile (const std::string&);
111
112         ViewMode view_mode () const { return _view_mode; }
113         SubViewMode subview_mode () const { return _subview_mode; }
114         static bool subview_mode_would_be_ok (SubViewMode, boost::shared_ptr<ARDOUR::Stripable>);
115         boost::shared_ptr<ARDOUR::Stripable> subview_stripable() const;
116         bool zoom_mode () const { return modifier_state() & MODIFIER_ZOOM; }
117         bool     metering_active () const { return _metering_active; }
118
119         bool is_track (boost::shared_ptr<ARDOUR::Stripable>) const;
120         bool is_audio_track (boost::shared_ptr<ARDOUR::Stripable>) const;
121         bool is_midi_track (boost::shared_ptr<ARDOUR::Stripable>) const;
122         bool is_mapped (boost::shared_ptr<ARDOUR::Stripable>) const;
123         boost::shared_ptr<ARDOUR::Stripable> first_selected_stripable () const;
124
125         void check_fader_automation_state ();
126         void update_fader_automation_state ();
127         void set_automation_state (ARDOUR::AutoState);
128
129         void set_view_mode (ViewMode);
130         int set_subview_mode (SubViewMode, boost::shared_ptr<ARDOUR::Stripable>);
131         void display_view_mode ();
132
133         XMLNode& get_state ();
134         int set_state (const XMLNode&, int version);
135
136         /* Note: because Mackie control is inherently a duplex protocol,
137            we do not implement get/set_feedback() since this aspect of
138            support for the protocol is not optional.
139         */
140
141         static bool probe();
142         static void* request_factory (uint32_t);
143
144         mutable Glib::Threads::Mutex surfaces_lock;
145         typedef std::list<boost::shared_ptr<US2400::Surface> > Surfaces;
146         Surfaces surfaces;
147
148         boost::shared_ptr<US2400::Surface> get_surface_by_raw_pointer (void*) const;
149         boost::shared_ptr<US2400::Surface> nth_surface (uint32_t) const;
150
151         uint32_t global_index (US2400::Strip&);
152         uint32_t global_index_locked (US2400::Strip&);
153
154         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
155
156         void set_master_on_surface_strip (uint32_t surface, uint32_t strip);
157         void set_monitor_on_surface_strip (uint32_t surface, uint32_t strip);
158
159         uint32_t n_strips (bool with_locked_strips = true) const;
160
161         bool has_editor () const { return true; }
162         void* get_gui () const;
163         void tear_down_gui ();
164
165         void handle_button_event (US2400::Surface&, US2400::Button& button, US2400::ButtonState);
166
167         void notify_subview_stripable_deleted ();
168         void notify_stripable_removed ();
169         void notify_routes_added (ARDOUR::RouteList &);
170         void notify_vca_added (ARDOUR::VCAList &);
171
172         void notify_presentation_info_changed(PBD::PropertyChange const &);
173
174         void recalibrate_faders ();
175         void toggle_backlight ();
176         void set_touch_sensitivity (int);
177
178         /// rebuild the current bank. Called on route or vca added/removed and
179         /// presentation info changed.
180         void refresh_current_bank();
181
182         // button-related signals
183         void notify_record_state_changed();
184         void notify_transport_state_changed();
185         void notify_loop_state_changed();
186         void notify_metering_state_changed();
187         // mainly to pick up punch-in and punch-out
188         void notify_parameter_changed(std::string const &);
189         void notify_solo_active_changed(bool);
190
191         /// Turn timecode on and beats off, or vice versa, depending
192         /// on state of _timecode_type
193         void update_timecode_beats_led();
194
195         /// this is called to generate the midi to send in response to a button press.
196         void update_led(US2400::Surface&, US2400::Button & button, US2400::LedState);
197
198         void update_global_button (int id, US2400::LedState);
199         void update_global_led (int id, US2400::LedState);
200
201         ARDOUR::Session & get_session() { return *session; }
202         samplepos_t transport_frame() const;
203
204         int modifier_state() const { return _modifier_state; }
205         int main_modifier_state() const { return _modifier_state & MAIN_MODIFIER_MASK; }
206
207         typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > ControlList;
208
209         void add_down_button (ARDOUR::AutomationType, int surface, int strip);
210         void remove_down_button (ARDOUR::AutomationType, int surface, int strip);
211         ControlList down_controls (ARDOUR::AutomationType, uint32_t pressed);
212
213         void add_down_select_button (int surface, int strip);
214         void remove_down_select_button (int surface, int strip);
215         void select_range (uint32_t pressed);
216
217   protected:
218         // shut down the surface
219         void close();
220
221         // This sets up the notifications and sets the
222         // controls to the correct values
223         void update_surfaces();
224
225         // connects global (not strip) signals from the Session to here
226         // so the surface can be notified of changes from the other UIs.
227         void connect_session_signals();
228
229         // set all controls to their zero position
230         void zero_all();
231
232         /**
233            Fetch the set of Stripables to be considered for control by the
234            surface. Excluding master, hidden and control routes, and inactive routes
235         */
236         typedef std::vector<boost::shared_ptr<ARDOUR::Stripable> > Sorted;
237         Sorted get_sorted_stripables();
238
239         // bank switching
240         int switch_banks (uint32_t first_remote_id, bool force = false);
241         void prev_track ();
242         void next_track ();
243
244         void do_request (US2400ControlUIRequest*);
245         int stop ();
246
247         void thread_init ();
248
249         bool stripable_is_locked_to_strip (boost::shared_ptr<ARDOUR::Stripable>) const;
250
251   private:
252
253         struct ButtonHandlers {
254             US2400::LedState (US2400Protocol::*press) (US2400::Button&);
255             US2400::LedState (US2400Protocol::*release) (US2400::Button&);
256
257             ButtonHandlers (US2400::LedState (US2400Protocol::*p) (US2400::Button&),
258                             US2400::LedState (US2400Protocol::*r) (US2400::Button&))
259             : press (p)
260             , release (r) {}
261         };
262
263         typedef std::map<US2400::Button::ID,ButtonHandlers> ButtonMap;
264
265         static US2400Protocol* _instance;
266
267         bool profile_exists (std::string const&) const;
268
269         US2400::DeviceInfo       _device_info;
270         US2400::DeviceProfile    _device_profile;
271         sigc::connection          periodic_connection;
272         sigc::connection          redisplay_connection;
273         sigc::connection          hui_connection;
274         uint32_t                 _current_initial_bank;
275         PBD::ScopedConnectionList audio_engine_connections;
276         PBD::ScopedConnectionList session_connections;
277         PBD::ScopedConnectionList stripable_connections;
278         PBD::ScopedConnectionList subview_stripable_connections;
279         PBD::ScopedConnectionList gui_connections;
280         // timer for two quick marker left presses
281         US2400::Timer            _frm_left_last;
282         // last written timecode string
283         std::string              _timecode_last;
284         samplepos_t                              _frame_last;
285         // Which timecode are we displaying? BBT or Timecode
286         ARDOUR::AnyTime::Type    _timecode_type;
287         // Bundle to represent our input ports
288         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
289         // Bundle to represent our output ports
290         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
291         void*                    _gui;
292         bool                     _scrub_mode;
293         ViewMode                 _view_mode;
294         SubViewMode              _subview_mode;
295         boost::shared_ptr<ARDOUR::Stripable> _subview_stripable;
296         int                      _modifier_state;
297         ButtonMap                 button_map;
298         bool                     _metering_active;
299         bool                     _initialized;
300         XMLNode*                 configuration_state;
301         int                      state_version;
302         int                      _last_bank[9];
303         bool                     marker_modifier_consumed_by_button;
304         bool                     nudge_modifier_consumed_by_button;
305
306         boost::shared_ptr<ArdourSurface::US2400::Surface>       _master_surface;
307
308         int create_surfaces ();
309         bool periodic();
310         bool redisplay();
311         bool redisplay_subview_mode ();
312         bool hui_heartbeat ();
313         void build_gui ();
314         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
315         void clear_ports ();
316         void clear_surfaces ();
317         void force_special_stripable_to_strip (boost::shared_ptr<ARDOUR::Stripable> r, uint32_t surface, uint32_t strip_number);
318         void build_button_map ();
319         void stripable_selection_changed ();
320        void initialize ();
321         int set_device_info (const std::string& device_name);
322         void update_configuration_state ();
323
324         /* MIDI port connection management */
325
326         PBD::ScopedConnection port_connection;
327         void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool);
328
329         /* BUTTON HANDLING */
330
331         typedef std::set<uint32_t> DownButtonList;
332         typedef std::map<ARDOUR::AutomationType,DownButtonList> DownButtonMap;
333         DownButtonMap  _down_buttons;
334         DownButtonList _down_select_buttons;
335
336         void pull_stripable_range (DownButtonList&, ARDOUR::StripableList&, uint32_t pressed);
337
338         /* implemented button handlers */
339         US2400::LedState stop_press(US2400::Button &);
340         US2400::LedState stop_release(US2400::Button &);
341         US2400::LedState play_press(US2400::Button &);
342         US2400::LedState play_release(US2400::Button &);
343         US2400::LedState record_press(US2400::Button &);
344         US2400::LedState record_release(US2400::Button &);
345         US2400::LedState loop_press(US2400::Button &);
346         US2400::LedState loop_release(US2400::Button &);
347         US2400::LedState rewind_press(US2400::Button & button);
348         US2400::LedState rewind_release(US2400::Button & button);
349         US2400::LedState ffwd_press(US2400::Button & button);
350         US2400::LedState ffwd_release(US2400::Button & button);
351         US2400::LedState cursor_up_press (US2400::Button &);
352         US2400::LedState cursor_up_release (US2400::Button &);
353         US2400::LedState cursor_down_press (US2400::Button &);
354         US2400::LedState cursor_down_release (US2400::Button &);
355         US2400::LedState cursor_left_press (US2400::Button &);
356         US2400::LedState cursor_left_release (US2400::Button &);
357         US2400::LedState cursor_right_press (US2400::Button &);
358         US2400::LedState cursor_right_release (US2400::Button &);
359         US2400::LedState left_press(US2400::Button &);
360         US2400::LedState left_release(US2400::Button &);
361         US2400::LedState right_press(US2400::Button &);
362         US2400::LedState right_release(US2400::Button &);
363         US2400::LedState channel_left_press(US2400::Button &);
364         US2400::LedState channel_left_release(US2400::Button &);
365         US2400::LedState channel_right_press(US2400::Button &);
366         US2400::LedState channel_right_release(US2400::Button &);
367         US2400::LedState marker_press(US2400::Button &);
368         US2400::LedState marker_release(US2400::Button &);
369         US2400::LedState save_press(US2400::Button &);
370         US2400::LedState save_release(US2400::Button &);
371         US2400::LedState timecode_beats_press(US2400::Button &);
372         US2400::LedState timecode_beats_release(US2400::Button &);
373         US2400::LedState zoom_press(US2400::Button &);
374         US2400::LedState zoom_release(US2400::Button &);
375         US2400::LedState scrub_press(US2400::Button &);
376         US2400::LedState scrub_release(US2400::Button &);
377         US2400::LedState undo_press (US2400::Button &);
378         US2400::LedState undo_release (US2400::Button &);
379         US2400::LedState shift_press (US2400::Button &);
380         US2400::LedState shift_release (US2400::Button &);
381         US2400::LedState option_press (US2400::Button &);
382         US2400::LedState option_release (US2400::Button &);
383         US2400::LedState control_press (US2400::Button &);
384         US2400::LedState control_release (US2400::Button &);
385         US2400::LedState cmd_alt_press (US2400::Button &);
386         US2400::LedState cmd_alt_release (US2400::Button &);
387
388         US2400::LedState pan_press (US2400::Button &);
389         US2400::LedState pan_release (US2400::Button &);
390         US2400::LedState plugin_press (US2400::Button &);
391         US2400::LedState plugin_release (US2400::Button &);
392         US2400::LedState eq_press (US2400::Button &);
393         US2400::LedState eq_release (US2400::Button &);
394         US2400::LedState dyn_press (US2400::Button &);
395         US2400::LedState dyn_release (US2400::Button &);
396         US2400::LedState flip_press (US2400::Button &);
397         US2400::LedState flip_release (US2400::Button &);
398         US2400::LedState mstr_press (US2400::Button &);
399         US2400::LedState mstr_release (US2400::Button &);
400         US2400::LedState name_value_press (US2400::Button &);
401         US2400::LedState name_value_release (US2400::Button &);
402 //      US2400::LedState F1_press (US2400::Button &);
403 //      US2400::LedState F1_release (US2400::Button &);
404 //      US2400::LedState F2_press (US2400::Button &);
405 //      US2400::LedState F2_release (US2400::Button &);
406 //      US2400::LedState F3_press (US2400::Button &);
407 //      US2400::LedState F3_release (US2400::Button &);
408 //      US2400::LedState F4_press (US2400::Button &);
409 //      US2400::LedState F4_release (US2400::Button &);
410 //      US2400::LedState F5_press (US2400::Button &);
411 //      US2400::LedState F5_release (US2400::Button &);
412 //      US2400::LedState F6_press (US2400::Button &);
413 //      US2400::LedState F6_release (US2400::Button &);
414 //      US2400::LedState F7_press (US2400::Button &);
415 //      US2400::LedState F7_release (US2400::Button &);
416 //      US2400::LedState F8_press (US2400::Button &);
417 //      US2400::LedState F8_release (US2400::Button &);
418         US2400::LedState touch_press (US2400::Button &);
419         US2400::LedState touch_release (US2400::Button &);
420         US2400::LedState enter_press (US2400::Button &);
421         US2400::LedState enter_release (US2400::Button &);
422         US2400::LedState cancel_press (US2400::Button &);
423         US2400::LedState cancel_release (US2400::Button &);
424         US2400::LedState user_a_press (US2400::Button &);
425         US2400::LedState user_a_release (US2400::Button &);
426         US2400::LedState user_b_press (US2400::Button &);
427         US2400::LedState user_b_release (US2400::Button &);
428         US2400::LedState fader_touch_press (US2400::Button &);
429         US2400::LedState fader_touch_release (US2400::Button &);
430         US2400::LedState master_fader_touch_press (US2400::Button &);
431         US2400::LedState master_fader_touch_release (US2400::Button &);
432
433         US2400::LedState read_press (US2400::Button&);
434         US2400::LedState read_release (US2400::Button&);
435         US2400::LedState write_press (US2400::Button&);
436         US2400::LedState write_release (US2400::Button&);
437         US2400::LedState clearsolo_press (US2400::Button&);
438         US2400::LedState clearsolo_release (US2400::Button&);
439         US2400::LedState track_press (US2400::Button&);
440         US2400::LedState track_release (US2400::Button&);
441         US2400::LedState send_press (US2400::Button&);
442         US2400::LedState send_release (US2400::Button&);
443         US2400::LedState miditracks_press (US2400::Button&);
444         US2400::LedState miditracks_release (US2400::Button&);
445         US2400::LedState inputs_press (US2400::Button&);
446         US2400::LedState inputs_release (US2400::Button&);
447         US2400::LedState audiotracks_press (US2400::Button&);
448         US2400::LedState audiotracks_release (US2400::Button&);
449         US2400::LedState audioinstruments_press (US2400::Button&);
450         US2400::LedState audioinstruments_release (US2400::Button&);
451         US2400::LedState aux_press (US2400::Button&);
452         US2400::LedState aux_release (US2400::Button&);
453         US2400::LedState busses_press (US2400::Button&);
454         US2400::LedState busses_release (US2400::Button&);
455         US2400::LedState outputs_press (US2400::Button&);
456         US2400::LedState outputs_release (US2400::Button&);
457         US2400::LedState user_press (US2400::Button&);
458         US2400::LedState user_release (US2400::Button&);
459         US2400::LedState trim_press (US2400::Button&);
460         US2400::LedState trim_release (US2400::Button&);
461         US2400::LedState latch_press (US2400::Button&);
462         US2400::LedState latch_release (US2400::Button&);
463         US2400::LedState grp_press (US2400::Button&);
464         US2400::LedState grp_release (US2400::Button&);
465         US2400::LedState nudge_press (US2400::Button&);
466         US2400::LedState nudge_release (US2400::Button&);
467         US2400::LedState drop_press (US2400::Button&);
468         US2400::LedState drop_release (US2400::Button&);
469         US2400::LedState replace_press (US2400::Button&);
470         US2400::LedState replace_release (US2400::Button&);
471         US2400::LedState click_press (US2400::Button&);
472         US2400::LedState click_release (US2400::Button&);
473         US2400::LedState view_press (US2400::Button&);
474         US2400::LedState view_release (US2400::Button&);
475
476         US2400::LedState bank_release (US2400::Button&, uint32_t bank_num);
477 };
478
479 } // namespace
480
481 #endif // ardour_us2400_control_protocol_h