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