8d63162ffcea806fe8ac278dbe4993be51891111
[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         uint32_t global_index_locked (Mackie::Strip&);
174
175         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
176
177         void set_master_on_surface_strip (uint32_t surface, uint32_t strip);
178         void set_monitor_on_surface_strip (uint32_t surface, uint32_t strip);
179
180         uint32_t n_strips (bool with_locked_strips = true) const;
181
182         bool has_editor () const { return true; }
183         void* get_gui () const;
184         void tear_down_gui ();
185
186         void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
187
188         void notify_subview_stripable_deleted ();
189         void notify_stripable_removed ();
190         void notify_routes_added (ARDOUR::RouteList &);
191         void notify_vca_added (ARDOUR::VCAList &);
192
193         void notify_presentation_info_changed();
194
195         void recalibrate_faders ();
196         void toggle_backlight ();
197         void set_touch_sensitivity (int);
198
199         /// rebuild the current bank. Called on route or vca added/removed and
200         /// presentation info changed.
201         void refresh_current_bank();
202
203         // button-related signals
204         void notify_record_state_changed();
205         void notify_transport_state_changed();
206         void notify_loop_state_changed();
207         void notify_metering_state_changed();
208         // mainly to pick up punch-in and punch-out
209         void notify_parameter_changed(std::string const &);
210         void notify_solo_active_changed(bool);
211
212         /// Turn timecode on and beats off, or vice versa, depending
213         /// on state of _timecode_type
214         void update_timecode_beats_led();
215
216         /// this is called to generate the midi to send in response to a button press.
217         void update_led(Mackie::Surface&, Mackie::Button & button, Mackie::LedState);
218
219         void update_global_button (int id, Mackie::LedState);
220         void update_global_led (int id, Mackie::LedState);
221
222         ARDOUR::Session & get_session() { return *session; }
223         framepos_t transport_frame() const;
224
225         int modifier_state() const { return _modifier_state; }
226         int main_modifier_state() const { return _modifier_state & MAIN_MODIFIER_MASK; }
227
228         typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > ControlList;
229
230         void add_down_button (ARDOUR::AutomationType, int surface, int strip);
231         void remove_down_button (ARDOUR::AutomationType, int surface, int strip);
232         ControlList down_controls (ARDOUR::AutomationType, uint32_t pressed);
233
234         void add_down_select_button (int surface, int strip);
235         void remove_down_select_button (int surface, int strip);
236         void select_range (uint32_t pressed);
237
238         int16_t ipmidi_base() const { return _ipmidi_base; }
239         void    set_ipmidi_base (int16_t);
240
241         void ping_devices ();
242
243   protected:
244         // shut down the surface
245         void close();
246
247         // This sets up the notifications and sets the
248         // controls to the correct values
249         void update_surfaces();
250
251         // connects global (not strip) signals from the Session to here
252         // so the surface can be notified of changes from the other UIs.
253         void connect_session_signals();
254
255         // set all controls to their zero position
256         void zero_all();
257
258         /**
259            Fetch the set of Stripables to be considered for control by the
260            surface. Excluding master, hidden and control routes, and inactive routes
261         */
262         typedef std::vector<boost::shared_ptr<ARDOUR::Stripable> > Sorted;
263         Sorted get_sorted_stripables();
264
265         // bank switching
266         int switch_banks (uint32_t first_remote_id, bool force = false);
267         void prev_track ();
268         void next_track ();
269
270         // also called from poll_automation to update timecode display
271         void update_timecode_display();
272
273         std::string format_bbt_timecode (ARDOUR::framepos_t now_frame);
274         std::string format_timecode_timecode (ARDOUR::framepos_t now_frame);
275
276         void do_request (MackieControlUIRequest*);
277         int stop ();
278
279         void thread_init ();
280
281         bool stripable_is_locked_to_strip (boost::shared_ptr<ARDOUR::Stripable>) const;
282
283   private:
284
285         struct ButtonHandlers {
286             Mackie::LedState (MackieControlProtocol::*press) (Mackie::Button&);
287             Mackie::LedState (MackieControlProtocol::*release) (Mackie::Button&);
288
289             ButtonHandlers (Mackie::LedState (MackieControlProtocol::*p) (Mackie::Button&),
290                             Mackie::LedState (MackieControlProtocol::*r) (Mackie::Button&))
291             : press (p)
292             , release (r) {}
293         };
294
295         typedef std::map<Mackie::Button::ID,ButtonHandlers> ButtonMap;
296
297         static MackieControlProtocol* _instance;
298
299         bool profile_exists (std::string const&) const;
300
301         Mackie::DeviceInfo       _device_info;
302         Mackie::DeviceProfile    _device_profile;
303         sigc::connection          periodic_connection;
304         sigc::connection          redisplay_connection;
305         sigc::connection          hui_connection;
306         uint32_t                 _current_initial_bank;
307         PBD::ScopedConnectionList audio_engine_connections;
308         PBD::ScopedConnectionList session_connections;
309         PBD::ScopedConnectionList stripable_connections;
310         PBD::ScopedConnectionList subview_stripable_connections;
311         PBD::ScopedConnectionList gui_connections;
312         PBD::ScopedConnectionList fader_automation_connections;
313         // timer for two quick marker left presses
314         Mackie::Timer            _frm_left_last;
315         // last written timecode string
316         std::string              _timecode_last;
317         framepos_t                               _frame_last;
318         // Which timecode are we displaying? BBT or Timecode
319         ARDOUR::AnyTime::Type    _timecode_type;
320         // Bundle to represent our input ports
321         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
322         // Bundle to represent our output ports
323         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
324         void*                    _gui;
325         bool                     _scrub_mode;
326         FlipMode                 _flip_mode;
327         ViewMode                 _view_mode;
328         SubViewMode              _subview_mode;
329         boost::shared_ptr<ARDOUR::Stripable> _subview_stripable;
330         int                      _current_selected_track;
331         int                      _modifier_state;
332         ButtonMap                 button_map;
333         int16_t                  _ipmidi_base;
334         bool                      needs_ipmidi_restart;
335         bool                     _metering_active;
336         bool                     _initialized;
337         XMLNode*                 configuration_state;
338         int                      state_version;
339         int                      _last_bank[9];
340         bool                     marker_modifier_consumed_by_button;
341         bool                     nudge_modifier_consumed_by_button;
342
343         boost::shared_ptr<ArdourSurface::Mackie::Surface>       _master_surface;
344
345         struct ipMIDIHandler {
346                 MackieControlProtocol* mcp;
347                 MIDI::Port* port;
348         };
349         friend struct ipMIDIHandler; /* is this necessary */
350         friend gboolean ArdourSurface::ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data);
351
352         int create_surfaces ();
353         bool periodic();
354         bool redisplay();
355         bool redisplay_subview_mode ();
356         bool hui_heartbeat ();
357         void build_gui ();
358         bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
359         void clear_ports ();
360         void clear_surfaces ();
361         void force_special_stripable_to_strip (boost::shared_ptr<ARDOUR::Stripable> r, uint32_t surface, uint32_t strip_number);
362         void build_button_map ();
363         void gui_track_selection_changed (ARDOUR::StripableNotificationListPtr, bool save_list);
364         void _gui_track_selection_changed (ARDOUR::StripableNotificationList*, bool save_list, bool gui_did_change);
365         int ipmidi_restart ();
366         void initialize ();
367         int set_device_info (const std::string& device_name);
368         void update_configuration_state ();
369
370         /* MIDI port connection management */
371
372         PBD::ScopedConnection port_connection;
373         void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool);
374
375         /* BUTTON HANDLING */
376
377         typedef std::set<uint32_t> DownButtonList;
378         typedef std::map<ARDOUR::AutomationType,DownButtonList> DownButtonMap;
379         DownButtonMap  _down_buttons;
380         DownButtonList _down_select_buttons;
381
382         void pull_stripable_range (DownButtonList&, ARDOUR::StripableList&, uint32_t pressed);
383
384         /* implemented button handlers */
385         Mackie::LedState stop_press(Mackie::Button &);
386         Mackie::LedState stop_release(Mackie::Button &);
387         Mackie::LedState play_press(Mackie::Button &);
388         Mackie::LedState play_release(Mackie::Button &);
389         Mackie::LedState record_press(Mackie::Button &);
390         Mackie::LedState record_release(Mackie::Button &);
391         Mackie::LedState loop_press(Mackie::Button &);
392         Mackie::LedState loop_release(Mackie::Button &);
393         Mackie::LedState rewind_press(Mackie::Button & button);
394         Mackie::LedState rewind_release(Mackie::Button & button);
395         Mackie::LedState ffwd_press(Mackie::Button & button);
396         Mackie::LedState ffwd_release(Mackie::Button & button);
397         Mackie::LedState cursor_up_press (Mackie::Button &);
398         Mackie::LedState cursor_up_release (Mackie::Button &);
399         Mackie::LedState cursor_down_press (Mackie::Button &);
400         Mackie::LedState cursor_down_release (Mackie::Button &);
401         Mackie::LedState cursor_left_press (Mackie::Button &);
402         Mackie::LedState cursor_left_release (Mackie::Button &);
403         Mackie::LedState cursor_right_press (Mackie::Button &);
404         Mackie::LedState cursor_right_release (Mackie::Button &);
405         Mackie::LedState left_press(Mackie::Button &);
406         Mackie::LedState left_release(Mackie::Button &);
407         Mackie::LedState right_press(Mackie::Button &);
408         Mackie::LedState right_release(Mackie::Button &);
409         Mackie::LedState channel_left_press(Mackie::Button &);
410         Mackie::LedState channel_left_release(Mackie::Button &);
411         Mackie::LedState channel_right_press(Mackie::Button &);
412         Mackie::LedState channel_right_release(Mackie::Button &);
413         Mackie::LedState marker_press(Mackie::Button &);
414         Mackie::LedState marker_release(Mackie::Button &);
415         Mackie::LedState save_press(Mackie::Button &);
416         Mackie::LedState save_release(Mackie::Button &);
417         Mackie::LedState timecode_beats_press(Mackie::Button &);
418         Mackie::LedState timecode_beats_release(Mackie::Button &);
419         Mackie::LedState zoom_press(Mackie::Button &);
420         Mackie::LedState zoom_release(Mackie::Button &);
421         Mackie::LedState scrub_press(Mackie::Button &);
422         Mackie::LedState scrub_release(Mackie::Button &);
423         Mackie::LedState undo_press (Mackie::Button &);
424         Mackie::LedState undo_release (Mackie::Button &);
425         Mackie::LedState shift_press (Mackie::Button &);
426         Mackie::LedState shift_release (Mackie::Button &);
427         Mackie::LedState option_press (Mackie::Button &);
428         Mackie::LedState option_release (Mackie::Button &);
429         Mackie::LedState control_press (Mackie::Button &);
430         Mackie::LedState control_release (Mackie::Button &);
431         Mackie::LedState cmd_alt_press (Mackie::Button &);
432         Mackie::LedState cmd_alt_release (Mackie::Button &);
433
434         Mackie::LedState pan_press (Mackie::Button &);
435         Mackie::LedState pan_release (Mackie::Button &);
436         Mackie::LedState plugin_press (Mackie::Button &);
437         Mackie::LedState plugin_release (Mackie::Button &);
438         Mackie::LedState eq_press (Mackie::Button &);
439         Mackie::LedState eq_release (Mackie::Button &);
440         Mackie::LedState dyn_press (Mackie::Button &);
441         Mackie::LedState dyn_release (Mackie::Button &);
442         Mackie::LedState flip_press (Mackie::Button &);
443         Mackie::LedState flip_release (Mackie::Button &);
444         Mackie::LedState name_value_press (Mackie::Button &);
445         Mackie::LedState name_value_release (Mackie::Button &);
446         Mackie::LedState F1_press (Mackie::Button &);
447         Mackie::LedState F1_release (Mackie::Button &);
448         Mackie::LedState F2_press (Mackie::Button &);
449         Mackie::LedState F2_release (Mackie::Button &);
450         Mackie::LedState F3_press (Mackie::Button &);
451         Mackie::LedState F3_release (Mackie::Button &);
452         Mackie::LedState F4_press (Mackie::Button &);
453         Mackie::LedState F4_release (Mackie::Button &);
454         Mackie::LedState F5_press (Mackie::Button &);
455         Mackie::LedState F5_release (Mackie::Button &);
456         Mackie::LedState F6_press (Mackie::Button &);
457         Mackie::LedState F6_release (Mackie::Button &);
458         Mackie::LedState F7_press (Mackie::Button &);
459         Mackie::LedState F7_release (Mackie::Button &);
460         Mackie::LedState F8_press (Mackie::Button &);
461         Mackie::LedState F8_release (Mackie::Button &);
462         Mackie::LedState touch_press (Mackie::Button &);
463         Mackie::LedState touch_release (Mackie::Button &);
464         Mackie::LedState enter_press (Mackie::Button &);
465         Mackie::LedState enter_release (Mackie::Button &);
466         Mackie::LedState cancel_press (Mackie::Button &);
467         Mackie::LedState cancel_release (Mackie::Button &);
468         Mackie::LedState user_a_press (Mackie::Button &);
469         Mackie::LedState user_a_release (Mackie::Button &);
470         Mackie::LedState user_b_press (Mackie::Button &);
471         Mackie::LedState user_b_release (Mackie::Button &);
472         Mackie::LedState fader_touch_press (Mackie::Button &);
473         Mackie::LedState fader_touch_release (Mackie::Button &);
474         Mackie::LedState master_fader_touch_press (Mackie::Button &);
475         Mackie::LedState master_fader_touch_release (Mackie::Button &);
476
477         Mackie::LedState read_press (Mackie::Button&);
478         Mackie::LedState read_release (Mackie::Button&);
479         Mackie::LedState write_press (Mackie::Button&);
480         Mackie::LedState write_release (Mackie::Button&);
481         Mackie::LedState clearsolo_press (Mackie::Button&);
482         Mackie::LedState clearsolo_release (Mackie::Button&);
483         Mackie::LedState track_press (Mackie::Button&);
484         Mackie::LedState track_release (Mackie::Button&);
485         Mackie::LedState send_press (Mackie::Button&);
486         Mackie::LedState send_release (Mackie::Button&);
487         Mackie::LedState miditracks_press (Mackie::Button&);
488         Mackie::LedState miditracks_release (Mackie::Button&);
489         Mackie::LedState inputs_press (Mackie::Button&);
490         Mackie::LedState inputs_release (Mackie::Button&);
491         Mackie::LedState audiotracks_press (Mackie::Button&);
492         Mackie::LedState audiotracks_release (Mackie::Button&);
493         Mackie::LedState audioinstruments_press (Mackie::Button&);
494         Mackie::LedState audioinstruments_release (Mackie::Button&);
495         Mackie::LedState aux_press (Mackie::Button&);
496         Mackie::LedState aux_release (Mackie::Button&);
497         Mackie::LedState busses_press (Mackie::Button&);
498         Mackie::LedState busses_release (Mackie::Button&);
499         Mackie::LedState outputs_press (Mackie::Button&);
500         Mackie::LedState outputs_release (Mackie::Button&);
501         Mackie::LedState user_press (Mackie::Button&);
502         Mackie::LedState user_release (Mackie::Button&);
503         Mackie::LedState trim_press (Mackie::Button&);
504         Mackie::LedState trim_release (Mackie::Button&);
505         Mackie::LedState latch_press (Mackie::Button&);
506         Mackie::LedState latch_release (Mackie::Button&);
507         Mackie::LedState grp_press (Mackie::Button&);
508         Mackie::LedState grp_release (Mackie::Button&);
509         Mackie::LedState nudge_press (Mackie::Button&);
510         Mackie::LedState nudge_release (Mackie::Button&);
511         Mackie::LedState drop_press (Mackie::Button&);
512         Mackie::LedState drop_release (Mackie::Button&);
513         Mackie::LedState replace_press (Mackie::Button&);
514         Mackie::LedState replace_release (Mackie::Button&);
515         Mackie::LedState click_press (Mackie::Button&);
516         Mackie::LedState click_release (Mackie::Button&);
517         Mackie::LedState view_press (Mackie::Button&);
518         Mackie::LedState view_release (Mackie::Button&);
519
520         Mackie::LedState bank_release (Mackie::Button&, uint32_t bank_num);
521 };
522
523 } // namespace
524
525 #endif // ardour_mackie_control_protocol_h