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