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