summaryrefslogtreecommitdiff
path: root/libs/surfaces/mackie/mackie_control_protocol.h
blob: 3b0337e49a84d9c764fa4109a59737091a92cf79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
/*
    Copyright (C) 2006,2007 John Anderson

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef ardour_mackie_control_protocol_h
#define ardour_mackie_control_protocol_h

#include <vector>
#include <map>
#include <list>
#include <set>

#include <sys/time.h>
#include <pthread.h>
#include <boost/smart_ptr.hpp>

#define ABSTRACT_UI_EXPORTS
#include "pbd/abstract_ui.h"
#include "midi++/types.h"
#include "ardour/types.h"
#include "control_protocol/control_protocol.h"

#include "types.h"
#include "midi_byte_array.h"
#include "controls.h"
#include "jog_wheel.h"
#include "timer.h"
#include "device_info.h"
#include "device_profile.h"

namespace ARDOUR {
	class AutomationControl;
	class Port;
}

namespace MIDI {
	class Port;
}

namespace ArdourSurface {

namespace Mackie {
	class Surface;
	class Control;
	class SurfacePort;
	class Button;
	class Strip;
}

gboolean ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data);

/**
	This handles the plugin duties, and the midi encoding and decoding,
	and the signal callbacks, mostly from ARDOUR::Route.

	The model of the control surface is handled by classes in controls.h

	What happens is that each strip on the control surface has
	a corresponding route in ControlProtocol::route_table. When
	an incoming midi message is signaled, the correct route
	is looked up, and the relevant changes made to it.

	For each route currently in route_table, there's a RouteSignal object
	which encapsulates the signals that indicate that there are changes
	to be sent to the surface. The signals are handled by this class.

	Calls to signal handlers pass a Route object which is used to look
	up the relevant Strip in Surface. Then the state is retrieved from
	the Route and encoded as the correct midi message.
*/

struct MackieControlUIRequest : public BaseUI::BaseRequestObject {
public:
	MackieControlUIRequest () {}
	~MackieControlUIRequest () {}
};

class MackieControlProtocol
	: public ARDOUR::ControlProtocol
	, public AbstractUI<MackieControlUIRequest>
{
  public:
	static const int MODIFIER_OPTION;
	static const int MODIFIER_CONTROL;
	static const int MODIFIER_SHIFT;
	static const int MODIFIER_CMDALT;
	static const int MODIFIER_ZOOM;
	static const int MODIFIER_SCRUB;
	static const int MODIFIER_MARKER;
	static const int MODIFIER_NUDGE;
	static const int MAIN_MODIFIER_MASK;

	enum ViewMode {
		Mixer,
		AudioTracks,
		MidiTracks,
		Busses,
		Auxes,
		Selected,
		Hidden,
		Plugins,
	};

	enum SubViewMode {
		None,
		EQ,
		Dynamics,
		Sends,
		TrackView,
	};

	enum PotMode {
		Pan,
	};

	enum FlipMode {
		Normal, /* fader controls primary, vpot controls secondary */
		Mirror, /* fader + vpot control secondary */
		Swap,   /* fader controls secondary, vpot controls primary */
		Zero,   /* fader controls primary, but doesn't move, vpot controls secondary */
	};

	MackieControlProtocol(ARDOUR::Session &);
	virtual ~MackieControlProtocol();

	static MackieControlProtocol* instance() { return _instance; }

	const Mackie::DeviceInfo& device_info() const { return _device_info; }
	Mackie::DeviceProfile& device_profile() { return _device_profile; }

	PBD::Signal0<void> DeviceChanged;
	PBD::Signal1<void,boost::shared_ptr<Mackie::Surface> > ConnectionChange;

        void device_ready ();

	int set_active (bool yn);
	int  set_device (const std::string&, bool force);
        void set_profile (const std::string&);

	FlipMode flip_mode () const { return _flip_mode; }
	ViewMode view_mode () const { return _view_mode; }
	SubViewMode subview_mode () const { return _subview_mode; }
	static bool subview_mode_would_be_ok (SubViewMode, boost::shared_ptr<ARDOUR::Route>);
	boost::shared_ptr<ARDOUR::Route> subview_route() const;
	PotMode pot_mode () const { return _pot_mode; }
	bool zoom_mode () const { return modifier_state() & MODIFIER_ZOOM; }
	bool     metering_active () const { return _metering_active; }

	bool is_track (boost::shared_ptr<ARDOUR::Route>) const;
	bool is_audio_track (boost::shared_ptr<ARDOUR::Route>) const;
	bool is_midi_track (boost::shared_ptr<ARDOUR::Route>) const;
	bool selected (boost::shared_ptr<ARDOUR::Route>) const;
	bool is_hidden (boost::shared_ptr<ARDOUR::Route>) const;
	bool is_mapped (boost::shared_ptr<ARDOUR::Route>) const;
	boost::shared_ptr<ARDOUR::Route> first_selected_route () const;

	void check_fader_automation_state ();
	void update_fader_automation_state ();
	void set_automation_state (ARDOUR::AutoState);

	void set_view_mode (ViewMode);
	int set_subview_mode (SubViewMode, boost::shared_ptr<ARDOUR::Route>);
	void set_flip_mode (FlipMode);
	void set_pot_mode (PotMode);
	void pot_mode_globals ();
	void display_view_mode ();

	XMLNode& get_state ();
	int set_state (const XMLNode&, int version);

	/* Note: because Mackie control is inherently a duplex protocol,
	   we do not implement get/set_feedback() since this aspect of
	   support for the protocol is not optional.
	*/

	static bool probe();
	static void* request_factory (uint32_t);

	mutable Glib::Threads::Mutex surfaces_lock;
	typedef std::list<boost::shared_ptr<Mackie::Surface> > Surfaces;
	Surfaces surfaces;

	boost::shared_ptr<Mackie::Surface> get_surface_by_raw_pointer (void*) const;
	boost::shared_ptr<Mackie::Surface> nth_surface (uint32_t) const;

	uint32_t global_index (Mackie::Strip&);

	std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();

	void set_master_on_surface_strip (uint32_t surface, uint32_t strip);
	void set_monitor_on_surface_strip (uint32_t surface, uint32_t strip);

	uint32_t n_strips (bool with_locked_strips = true) const;

	bool has_editor () const { return true; }
	void* get_gui () const;
	void tear_down_gui ();

	void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);

	void notify_subview_route_deleted ();
	void notify_route_added_or_removed ();
	void notify_route_added (ARDOUR::RouteList &);
	void notify_remote_id_changed();

	void recalibrate_faders ();
	void toggle_backlight ();
	void set_touch_sensitivity (int);

	/// rebuild the current bank. Called on route added/removed and
	/// remote id changed.
	void refresh_current_bank();

	// button-related signals
	void notify_record_state_changed();
	void notify_transport_state_changed();
	void notify_loop_state_changed();
	void notify_metering_state_changed();
	// mainly to pick up punch-in and punch-out
	void notify_parameter_changed(std::string const &);
	void notify_solo_active_changed(bool);

	/// Turn timecode on and beats off, or vice versa, depending
	/// on state of _timecode_type
	void update_timecode_beats_led();

	/// this is called to generate the midi to send in response to a button press.
	void update_led(Mackie::Surface&, Mackie::Button & button, Mackie::LedState);

	void update_global_button (int id, Mackie::LedState);
	void update_global_led (int id, Mackie::LedState);

	ARDOUR::Session & get_session() { return *session; }
	framepos_t transport_frame() const;

	int modifier_state() const { return _modifier_state; }
	int main_modifier_state() const { return _modifier_state & MAIN_MODIFIER_MASK; }

	typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > ControlList;

	void add_down_button (ARDOUR::AutomationType, int surface, int strip);
	void remove_down_button (ARDOUR::AutomationType, int surface, int strip);
	ControlList down_controls (ARDOUR::AutomationType);

	void add_down_select_button (int surface, int strip);
	void remove_down_select_button (int surface, int strip);
	void select_range ();

	int16_t ipmidi_base() const { return _ipmidi_base; }
	void    set_ipmidi_base (int16_t);

	void ping_devices ();

  protected:
	// shut down the surface
	void close();

	// This sets up the notifications and sets the
	// controls to the correct values
	void update_surfaces();

	// connects global (not strip) signals from the Session to here
	// so the surface can be notified of changes from the other UIs.
	void connect_session_signals();

	// set all controls to their zero position
	void zero_all();

	/**
	   Fetch the set of routes to be considered for control by the
	   surface. Excluding master, hidden and control routes, and inactive routes
	*/
	typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
	Sorted get_sorted_routes();

	// bank switching
	int switch_banks (uint32_t first_remote_id, bool force = false);
	void prev_track ();
	void next_track ();

	// also called from poll_automation to update timecode display
	void update_timecode_display();

	std::string format_bbt_timecode (ARDOUR::framepos_t now_frame);
	std::string format_timecode_timecode (ARDOUR::framepos_t now_frame);

	void do_request (MackieControlUIRequest*);
	int stop ();

	void thread_init ();

	bool route_is_locked_to_strip (boost::shared_ptr<ARDOUR::Route>) const;

  private:

	struct ButtonHandlers {
	    Mackie::LedState (MackieControlProtocol::*press) (Mackie::Button&);
	    Mackie::LedState (MackieControlProtocol::*release) (Mackie::Button&);

	    ButtonHandlers (Mackie::LedState (MackieControlProtocol::*p) (Mackie::Button&),
			    Mackie::LedState (MackieControlProtocol::*r) (Mackie::Button&))
	    : press (p)
	    , release (r) {}
	};

	typedef std::map<Mackie::Button::ID,ButtonHandlers> ButtonMap;

	static MackieControlProtocol* _instance;

	Mackie::DeviceInfo       _device_info;
	Mackie::DeviceProfile    _device_profile;
	sigc::connection          periodic_connection;
	sigc::connection          redisplay_connection;
	sigc::connection          hui_connection;
	uint32_t                 _current_initial_bank;
	PBD::ScopedConnectionList audio_engine_connections;
	PBD::ScopedConnectionList session_connections;
	PBD::ScopedConnectionList route_connections;
	PBD::ScopedConnectionList subview_route_connections;
	PBD::ScopedConnectionList gui_connections;
	PBD::ScopedConnectionList fader_automation_connections;
	// timer for two quick marker left presses
	Mackie::Timer            _frm_left_last;
	// last written timecode string
	std::string              _timecode_last;
	framepos_t				 _frame_last;
	// Which timecode are we displaying? BBT or Timecode
	ARDOUR::AnyTime::Type    _timecode_type;
	// Bundle to represent our input ports
	boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
	// Bundle to represent our output ports
	boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
	void*                    _gui;
	bool                     _scrub_mode;
	FlipMode                 _flip_mode;
	ViewMode                 _view_mode;
	SubViewMode              _subview_mode;
	boost::shared_ptr<ARDOUR::Route> _subview_route;
	PotMode                  _pot_mode;
	int                      _current_selected_track;
	int                      _modifier_state;
	ButtonMap                 button_map;
	int16_t                  _ipmidi_base;
	bool                      needs_ipmidi_restart;
	bool                     _metering_active;
	bool                     _initialized;
	ARDOUR::RouteNotificationList _last_selected_routes;
	XMLNode*                 configuration_state;
	int                      state_version;
	int                      _last_bank[9];
	bool                     marker_modifier_consumed_by_button;
	bool                     nudge_modifier_consumed_by_button;

	boost::shared_ptr<ArdourSurface::Mackie::Surface>	_master_surface;

        struct ipMIDIHandler {
                MackieControlProtocol* mcp;
                MIDI::Port* port;
        };
        friend struct ipMIDIHandler; /* is this necessary */
	friend gboolean ArdourSurface::ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data);

	int create_surfaces ();
	bool periodic();
	bool redisplay();
	bool redisplay_subview_mode ();
	bool hui_heartbeat ();
	void build_gui ();
	bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
	void clear_ports ();
	void clear_surfaces ();
	void force_special_route_to_strip (boost::shared_ptr<ARDOUR::Route> r, uint32_t surface, uint32_t strip_number);
	void build_button_map ();
	void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr, bool save_list);
	void _gui_track_selection_changed (ARDOUR::RouteNotificationList*, bool save_list, bool gui_did_change);
	int ipmidi_restart ();
        void initialize ();
        int set_device_info (const std::string& device_name);
	void update_configuration_state ();

	/* accepts an Action name from the application GUI definitions, and
	   invokes it
	*/
	void gui_invoke (std::string const &);

	/* MIDI port connection management */

	PBD::ScopedConnection port_connection;
	void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool);

	/* BUTTON HANDLING */

	typedef std::set<uint32_t> DownButtonList;
	typedef std::map<ARDOUR::AutomationType,DownButtonList> DownButtonMap;
	DownButtonMap  _down_buttons;
	DownButtonList _down_select_buttons;

	void pull_route_range (DownButtonList&, ARDOUR::RouteList&);

	/* implemented button handlers */
	Mackie::LedState stop_press(Mackie::Button &);
	Mackie::LedState stop_release(Mackie::Button &);
	Mackie::LedState play_press(Mackie::Button &);
	Mackie::LedState play_release(Mackie::Button &);
	Mackie::LedState record_press(Mackie::Button &);
	Mackie::LedState record_release(Mackie::Button &);
	Mackie::LedState loop_press(Mackie::Button &);
	Mackie::LedState loop_release(Mackie::Button &);
	Mackie::LedState rewind_press(Mackie::Button & button);
	Mackie::LedState rewind_release(Mackie::Button & button);
	Mackie::LedState ffwd_press(Mackie::Button & button);
	Mackie::LedState ffwd_release(Mackie::Button & button);
	Mackie::LedState cursor_up_press (Mackie::Button &);
	Mackie::LedState cursor_up_release (Mackie::Button &);
	Mackie::LedState cursor_down_press (Mackie::Button &);
	Mackie::LedState cursor_down_release (Mackie::Button &);
	Mackie::LedState cursor_left_press (Mackie::Button &);
	Mackie::LedState cursor_left_release (Mackie::Button &);
	Mackie::LedState cursor_right_press (Mackie::Button &);
	Mackie::LedState cursor_right_release (Mackie::Button &);
	Mackie::LedState left_press(Mackie::Button &);
	Mackie::LedState left_release(Mackie::Button &);
	Mackie::LedState right_press(Mackie::Button &);
	Mackie::LedState right_release(Mackie::Button &);
	Mackie::LedState channel_left_press(Mackie::Button &);
	Mackie::LedState channel_left_release(Mackie::Button &);
	Mackie::LedState channel_right_press(Mackie::Button &);
	Mackie::LedState channel_right_release(Mackie::Button &);
	Mackie::LedState clicking_press(Mackie::Button &);
	Mackie::LedState clicking_release(Mackie::Button &);
	Mackie::LedState marker_press(Mackie::Button &);
	Mackie::LedState marker_release(Mackie::Button &);
	Mackie::LedState save_press(Mackie::Button &);
	Mackie::LedState save_release(Mackie::Button &);
	Mackie::LedState timecode_beats_press(Mackie::Button &);
	Mackie::LedState timecode_beats_release(Mackie::Button &);
	Mackie::LedState zoom_press(Mackie::Button &);
	Mackie::LedState zoom_release(Mackie::Button &);
	Mackie::LedState scrub_press(Mackie::Button &);
	Mackie::LedState scrub_release(Mackie::Button &);
	Mackie::LedState undo_press (Mackie::Button &);
	Mackie::LedState undo_release (Mackie::Button &);
	Mackie::LedState shift_press (Mackie::Button &);
	Mackie::LedState shift_release (Mackie::Button &);
	Mackie::LedState option_press (Mackie::Button &);
	Mackie::LedState option_release (Mackie::Button &);
	Mackie::LedState control_press (Mackie::Button &);
	Mackie::LedState control_release (Mackie::Button &);
	Mackie::LedState cmd_alt_press (Mackie::Button &);
	Mackie::LedState cmd_alt_release (Mackie::Button &);

	Mackie::LedState pan_press (Mackie::Button &);
	Mackie::LedState pan_release (Mackie::Button &);
	Mackie::LedState plugin_press (Mackie::Button &);
	Mackie::LedState plugin_release (Mackie::Button &);
	Mackie::LedState eq_press (Mackie::Button &);
	Mackie::LedState eq_release (Mackie::Button &);
	Mackie::LedState dyn_press (Mackie::Button &);
	Mackie::LedState dyn_release (Mackie::Button &);
	Mackie::LedState flip_press (Mackie::Button &);
	Mackie::LedState flip_release (Mackie::Button &);
	Mackie::LedState name_value_press (Mackie::Button &);
	Mackie::LedState name_value_release (Mackie::Button &);
	Mackie::LedState F1_press (Mackie::Button &);
	Mackie::LedState F1_release (Mackie::Button &);
	Mackie::LedState F2_press (Mackie::Button &);
	Mackie::LedState F2_release (Mackie::Button &);
	Mackie::LedState F3_press (Mackie::Button &);
	Mackie::LedState F3_release (Mackie::Button &);
	Mackie::LedState F4_press (Mackie::Button &);
	Mackie::LedState F4_release (Mackie::Button &);
	Mackie::LedState F5_press (Mackie::Button &);
	Mackie::LedState F5_release (Mackie::Button &);
	Mackie::LedState F6_press (Mackie::Button &);
	Mackie::LedState F6_release (Mackie::Button &);
	Mackie::LedState F7_press (Mackie::Button &);
	Mackie::LedState F7_release (Mackie::Button &);
	Mackie::LedState F8_press (Mackie::Button &);
	Mackie::LedState F8_release (Mackie::Button &);
	Mackie::LedState touch_press (Mackie::Button &);
	Mackie::LedState touch_release (Mackie::Button &);
	Mackie::LedState enter_press (Mackie::Button &);
	Mackie::LedState enter_release (Mackie::Button &);
	Mackie::LedState cancel_press (Mackie::Button &);
	Mackie::LedState cancel_release (Mackie::Button &);
	Mackie::LedState user_a_press (Mackie::Button &);
	Mackie::LedState user_a_release (Mackie::Button &);
	Mackie::LedState user_b_press (Mackie::Button &);
	Mackie::LedState user_b_release (Mackie::Button &);
	Mackie::LedState fader_touch_press (Mackie::Button &);
	Mackie::LedState fader_touch_release (Mackie::Button &);
	Mackie::LedState master_fader_touch_press (Mackie::Button &);
	Mackie::LedState master_fader_touch_release (Mackie::Button &);

	Mackie::LedState read_press (Mackie::Button&);
	Mackie::LedState read_release (Mackie::Button&);
	Mackie::LedState write_press (Mackie::Button&);
	Mackie::LedState write_release (Mackie::Button&);
	Mackie::LedState clearsolo_press (Mackie::Button&);
	Mackie::LedState clearsolo_release (Mackie::Button&);
	Mackie::LedState track_press (Mackie::Button&);
	Mackie::LedState track_release (Mackie::Button&);
	Mackie::LedState send_press (Mackie::Button&);
	Mackie::LedState send_release (Mackie::Button&);
	Mackie::LedState miditracks_press (Mackie::Button&);
	Mackie::LedState miditracks_release (Mackie::Button&);
	Mackie::LedState inputs_press (Mackie::Button&);
	Mackie::LedState inputs_release (Mackie::Button&);
	Mackie::LedState audiotracks_press (Mackie::Button&);
	Mackie::LedState audiotracks_release (Mackie::Button&);
	Mackie::LedState audioinstruments_press (Mackie::Button&);
	Mackie::LedState audioinstruments_release (Mackie::Button&);
	Mackie::LedState aux_press (Mackie::Button&);
	Mackie::LedState aux_release (Mackie::Button&);
	Mackie::LedState busses_press (Mackie::Button&);
	Mackie::LedState busses_release (Mackie::Button&);
	Mackie::LedState outputs_press (Mackie::Button&);
	Mackie::LedState outputs_release (Mackie::Button&);
	Mackie::LedState user_press (Mackie::Button&);
	Mackie::LedState user_release (Mackie::Button&);
	Mackie::LedState trim_press (Mackie::Button&);
	Mackie::LedState trim_release (Mackie::Button&);
	Mackie::LedState latch_press (Mackie::Button&);
	Mackie::LedState latch_release (Mackie::Button&);
	Mackie::LedState grp_press (Mackie::Button&);
	Mackie::LedState grp_release (Mackie::Button&);
	Mackie::LedState nudge_press (Mackie::Button&);
	Mackie::LedState nudge_release (Mackie::Button&);
	Mackie::LedState drop_press (Mackie::Button&);
	Mackie::LedState drop_release (Mackie::Button&);
	Mackie::LedState replace_press (Mackie::Button&);
	Mackie::LedState replace_release (Mackie::Button&);
	Mackie::LedState click_press (Mackie::Button&);
	Mackie::LedState click_release (Mackie::Button&);
	Mackie::LedState view_press (Mackie::Button&);
	Mackie::LedState view_release (Mackie::Button&);

	Mackie::LedState bank_release (Mackie::Button&, uint32_t bank_num);
};

} // namespace

#endif // ardour_mackie_control_protocol_h