2 Copyright (C) 2016 Paul Davis
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.
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.
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.
19 #ifndef __ardour_launch_control_h__
20 #define __ardour_launch_control_h__
28 #define ABSTRACT_UI_EXPORTS
29 #include "pbd/abstract_ui.h"
31 #include "midi++/types.h"
33 #include "ardour/mode.h"
34 #include "ardour/types.h"
36 #include "control_protocol/control_protocol.h"
37 #include "control_protocol/types.h"
39 #include "midi_byte_array.h"
53 namespace ArdourSurface {
56 struct LaunchControlRequest : public BaseUI::BaseRequestObject {
58 LaunchControlRequest() {}
59 ~LaunchControlRequest() {}
63 class LaunchControlMenu;
65 class LaunchControlXL : public ARDOUR::ControlProtocol,
66 public AbstractUI<LaunchControlRequest>
146 enum LEDFlag { Normal = 0xC, Blink = 0x8, DoubleBuffering = 0x0 };
147 enum LEDColor { Off=0, RedLow = 1, RedFull = 3, GreenLow = 16, GreenFull = 48, YellowLow = 34, YellowFull = 51, AmberLow = 18, AmberFull = 35};
159 Controller(uint8_t cn, uint8_t val, boost::function<void ()> action)
160 : _controller_number(cn)
162 , action_method(action) {}
164 uint8_t controller_number() const { return _controller_number; }
165 uint8_t value() const { return _value; }
166 void set_value(uint8_t val) { _value = val; }
169 uint8_t _controller_number;
173 boost::function<void ()> action_method;
177 LED(uint8_t i, LEDColor c, LaunchControlXL& l) : _index(i), _color(c), _flag(Normal), lcxl(&l) {}
178 LED(uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& lcxl) : _index(i), _color(c), _flag(f) {}
181 LEDColor color() const { return _color; }
182 LEDFlag flag() const { return _flag; }
183 uint8_t index() const { return _index; }
184 void set_flag(LEDFlag f) { _flag = f; }
186 virtual MidiByteArray state_msg(bool light) const = 0;
192 MidiByteArray _state_msg;
193 LaunchControlXL* lcxl;
196 struct MultiColorLED : public LED {
197 MultiColorLED (uint8_t i, LEDColor c, LaunchControlXL& l) : LED(i, c, l) {}
198 MultiColorLED (uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& l)
201 void set_color(LEDColor c) { _color = c; }
205 Button(ButtonID id, boost::function<void ()> press, boost::function<void ()> release,
206 boost::function<void ()> long_press)
207 : press_method(press)
208 , release_method(release)
209 , long_press_method(long_press),
214 ButtonID id() const { return _id; }
216 boost::function<void ()> press_method;
217 boost::function<void ()> release_method;
218 boost::function<void ()> long_press_method;
220 sigc::connection timeout_connection;
226 struct ControllerButton : public Button {
227 ControllerButton(ButtonID id, uint8_t cn,
228 boost::function<void ()> press,
229 boost::function<void ()> release,
230 boost::function<void ()> long_release)
231 : Button(id, press, release, long_release), _controller_number(cn) {}
235 uint8_t controller_number() const { return _controller_number; }
238 uint8_t _controller_number;
241 struct NoteButton : public Button {
242 NoteButton(ButtonID id, uint8_t cn,
243 boost::function<void ()> press,
244 boost::function<void ()> release,
245 boost::function<void ()> release_long)
246 : Button(id, press, release, release_long), _note_number(cn) {}
248 uint8_t note_number() const { return _note_number; }
251 uint8_t _note_number;
254 struct TrackButton : public NoteButton, public MultiColorLED {
255 TrackButton(ButtonID id, uint8_t nn, uint8_t index, LEDColor c_on, LEDColor c_off,
256 boost::function<void ()> press,
257 boost::function<void ()> release,
258 boost::function<void ()> release_long,
259 boost::function<uint8_t ()> check,
261 : NoteButton(id, nn, press, release, release_long)
262 , MultiColorLED(index, Off, l)
263 , check_method(check)
264 , _color_enabled (c_on)
265 , _color_disabled (c_off) {}
270 LEDColor color_enabled() const { return _color_enabled; }
271 LEDColor color_disabled() const { return _color_disabled; }
272 void set_color_enabled (LEDColor c_on) { _color_enabled = c_on; }
273 void set_color_disabled (LEDColor c_off) { _color_disabled = c_off; }
274 boost::function<uint8_t ()> check_method;
277 MidiByteArray state_msg(bool light = true) const;
280 LEDColor _color_enabled;
281 LEDColor _color_disabled;
284 struct SelectButton : public ControllerButton, public LED {
285 SelectButton(ButtonID id, uint8_t cn, uint8_t index,
286 boost::function<void ()> press,
287 boost::function<void ()> release,
288 boost::function<void ()> long_release,
290 : ControllerButton(id, cn, press, release, long_release), LED(index, RedFull, l) {}
293 MidiByteArray state_msg(bool light) const;
296 struct TrackStateButton : public NoteButton, public LED {
297 TrackStateButton(ButtonID id, uint8_t nn, uint8_t index,
298 boost::function<void ()> press,
299 boost::function<void ()> release,
300 boost::function<void ()> release_long,
302 : NoteButton(id, nn, press, release, release_long)
303 , LED(index, YellowLow, l) {}
305 MidiByteArray state_msg(bool light) const;
308 struct Fader : public Controller {
309 Fader(FaderID id, uint8_t cn, boost::function<void ()> action)
310 : Controller(cn, 0, action), _id(id) {} // minimal value
312 FaderID id() const { return _id; }
314 void controller_changed(Controller* controller);
320 struct Knob : public Controller, public MultiColorLED {
321 Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, boost::function<void ()> action,
323 : Controller(cn, 64, action)
324 , MultiColorLED(index, Off, l)
326 , _color_enabled (c_on)
327 , _color_disabled (c_off) {} // knob 50/50 value
329 Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, boost::function<void ()> action,
330 boost::function<uint8_t ()> check, LaunchControlXL &l)
331 : Controller(cn, 64, action)
332 , MultiColorLED(index, Off, l)
333 , check_method(check)
335 , _color_enabled (c_on)
336 , _color_disabled (c_off) {} // knob 50/50 value
340 KnobID id() const { return _id; }
341 LEDColor color_enabled() const { return _color_enabled; }
342 LEDColor color_disabled() const { return _color_disabled; }
343 boost::function<uint8_t ()> check_method;
345 MidiByteArray state_msg(bool light = true) const;
349 LEDColor _color_enabled;
350 LEDColor _color_disabled;
354 LaunchControlXL(ARDOUR::Session &);
359 static void *request_factory(uint32_t);
361 std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles();
363 bool has_editor() const { return true; }
364 void *get_gui() const;
365 void tear_down_gui();
367 int get_amount_of_tracks();
369 int set_active(bool yn);
370 XMLNode &get_state();
371 int set_state(const XMLNode &node, int version);
373 PBD::Signal0<void> ConnectionChange;
375 boost::shared_ptr<ARDOUR::Port> input_port();
376 boost::shared_ptr<ARDOUR::Port> output_port();
378 Button *button_by_id(ButtonID);
380 static std::string button_name_by_id(ButtonID);
381 static std::string knob_name_by_id(KnobID);
382 static std::string fader_name_by_id(FaderID);
384 void write(const MidiByteArray &);
385 void reset(uint8_t chan);
387 void set_fader8master (bool yn);
388 bool fader8master () const { return _fader8master; }
390 void set_refresh_leds_flag (bool yn);
391 bool refresh_leds_flag () const { return _refresh_leds_flag; }
393 void set_device_mode (bool yn);
394 bool device_mode () const { return _device_mode; }
397 void store_fss_type();
398 bool fss_is_mixbus() const { return _fss_is_mixbus; }
400 TrackMode track_mode() const { return _track_mode; }
401 void set_track_mode(TrackMode mode);
403 uint8_t template_number() const { return _template_number; }
405 void set_send_bank (int offset);
406 void send_bank_switch(bool up);
407 int send_bank_base () const { return _send_bank_base; }
411 TrackMode _track_mode;
412 uint8_t _template_number;
419 bool _refresh_leds_flag;
423 void do_request(LaunchControlRequest *);
425 int begin_using_device();
426 int stop_using_device();
428 void ports_release();
429 void run_event_loop();
430 void stop_event_loop();
434 /* map of NoteButtons by NoteNumber */
435 typedef std::map<int, boost::shared_ptr<NoteButton> > NNNoteButtonMap;
436 NNNoteButtonMap nn_note_button_map;
437 /* map of NoteButtons by ButtonID */
438 typedef std::map<ButtonID, boost::shared_ptr<NoteButton> > IDNoteButtonMap;
439 IDNoteButtonMap id_note_button_map;
440 /* map of ControllerNoteButtons by CC */
441 typedef std::map<int, boost::shared_ptr<ControllerButton> > CCControllerButtonMap;
442 CCControllerButtonMap cc_controller_button_map;
443 /* map of ControllerButtons by ButtonID */
444 typedef std::map<ButtonID, boost::shared_ptr<ControllerButton> > IDControllerButtonMap;
445 IDControllerButtonMap id_controller_button_map;
448 /* map of Fader by CC */
449 typedef std::map<int, boost::shared_ptr<Fader> > CCFaderMap;
450 CCFaderMap cc_fader_map;
451 /* map of Fader by FaderID */
452 typedef std::map<FaderID, boost::shared_ptr<Fader> > IDFaderMap;
453 IDFaderMap id_fader_map;
455 /* map of Knob by CC */
456 typedef std::map<int, boost::shared_ptr<Knob> > CCKnobMap;
457 CCKnobMap cc_knob_map;
458 /* map of Knob by KnobID */
459 typedef std::map<KnobID, boost::shared_ptr<Knob> > IDKnobMap;
460 IDKnobMap id_knob_map;
462 std::set<ButtonID> buttons_down;
463 std::set<ButtonID> consumed;
465 bool button_long_press_timeout(ButtonID id, boost::shared_ptr<Button> button);
466 void start_press_timeout(boost::shared_ptr<Button> , ButtonID);
469 void init_buttons(bool startup);
470 void init_buttons (ButtonID buttons[], uint8_t i);
472 void init_knobs(KnobID knobs[], uint8_t i);
473 void init_knobs_and_buttons();
475 void init_device_mode();
476 void init_dm_callbacks();
478 void switch_template(uint8_t t);
479 void filter_stripables (ARDOUR::StripableList& strips) const;
483 // Bundle to represent our input ports
484 boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
485 // Bundle to represent our output ports
486 boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
488 MIDI::Port *_input_port;
489 MIDI::Port *_output_port;
490 boost::shared_ptr<ARDOUR::Port> _async_in;
491 boost::shared_ptr<ARDOUR::Port> _async_out;
493 void connect_to_parser();
494 void handle_button_message(boost::shared_ptr<Button> button, MIDI::EventTwoBytes *);
496 bool check_pick_up(boost::shared_ptr<Controller> controller, boost::shared_ptr<ARDOUR::AutomationControl> ac);
498 void handle_midi_controller_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
499 void handle_midi_note_on_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
500 void handle_midi_note_off_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
501 void handle_midi_sysex(MIDI::Parser &, MIDI::byte *, size_t count);
503 bool midi_input_handler(Glib::IOCondition ioc, MIDI::Port *port);
507 PBD::ScopedConnectionList session_connections;
508 void connect_session_signals();
509 void notify_transport_state_changed();
510 void notify_loop_state_changed();
511 void notify_parameter_changed(std::string);
514 boost::shared_ptr<Knob> knob_by_id(KnobID id);
515 boost::shared_ptr<Knob>* knobs_by_column(uint8_t col, boost::shared_ptr<Knob>* knob_col);
516 void update_knob_led_by_strip(uint8_t n);
517 void update_knob_led_by_id(uint8_t id, LEDColor color);
519 void knob_sendA(uint8_t n);
520 void knob_sendB(uint8_t n);
521 void knob_pan(uint8_t n);
523 uint8_t dm_check_dummy(DeviceStatus ds);
525 void dm_fader(FaderID id);
526 uint8_t dm_check_pan_azi ();
527 void dm_pan_azi(KnobID k);
528 uint8_t dm_check_pan_width();
529 void dm_pan_width (KnobID k);
530 uint8_t dm_check_trim ();
531 void dm_trim(KnobID k);
532 uint8_t dm_mute_enabled();
533 void dm_mute_switch();
534 uint8_t dm_solo_enabled();
535 void dm_solo_switch();
536 uint8_t dm_recenable_enabled();
537 void dm_recenable_switch();
538 void dm_select_prev_strip();
539 void dm_select_next_strip();
542 void dm_mb_eq_switch();
543 void dm_mb_eq (KnobID k, bool gain, uint8_t band);
544 uint8_t dm_mb_eq_freq_enabled();
545 uint8_t dm_mb_eq_gain_enabled(uint8_t band);
546 void dm_mb_eq_shape_switch(uint8_t band);
547 uint8_t dm_mb_eq_shape_enabled(uint8_t band);
548 uint8_t dm_mb_flt_enabled();
549 void dm_mb_flt_frq (KnobID k, bool hpf);
550 void dm_mb_flt_switch();
551 void dm_mb_send_enabled(KnobID k);
552 uint8_t dm_mb_check_send_knob(KnobID k);
553 uint8_t dm_mb_check_send_button(uint8_t s);
554 void dm_mb_sends (KnobID k);
555 void dm_mb_send_switch (ButtonID b);
556 uint8_t dm_mb_comp_enabled();
557 void dm_mb_comp_switch();
558 void dm_mb_comp (KnobID k, CompParam c);
559 void dm_mb_comp_thresh (FaderID id);
560 uint8_t dm_mb_has_tapedrive();
561 void dm_mb_tapedrive (KnobID k);
562 uint8_t dm_mb_master_assign_enabled();
563 void dm_mb_master_assign_switch();
567 void fader(uint8_t n);
571 boost::shared_ptr<TrackButton> track_button_by_range(uint8_t n, uint8_t first, uint8_t middle);
572 boost::shared_ptr<TrackButton> focus_button_by_column(uint8_t col) { return track_button_by_range(col, 41, 57) ; }
573 boost::shared_ptr<TrackButton> control_button_by_column(uint8_t col) { return track_button_by_range(col, 73, 89) ; }
576 void button_device();
577 void button_device_long_press();
578 void button_track_mode(TrackMode state);
580 void button_mute_long_press();
582 void button_solo_long_press();
583 void button_record();
584 void button_select_up();
585 void button_select_down();
586 void button_select_left();
587 void button_select_right();
589 void button_track_focus(uint8_t n);
590 void button_press_track_control(uint8_t n);
591 void button_release_track_control(uint8_t n);
593 boost::shared_ptr<ARDOUR::AutomationControl> get_ac_by_state(uint8_t n);
594 void update_track_focus_led(uint8_t n);
595 void update_track_control_led(uint8_t n);
597 void send_bank_switch_0() { send_bank_switch(0); }
598 void send_bank_switch_1() { send_bank_switch(1); }
603 PBD::ScopedConnectionList stripable_connections;
604 boost::shared_ptr<ARDOUR::Stripable> stripable[8];
606 void stripables_added ();
608 void stripable_property_change (PBD::PropertyChange const& what_changed, uint32_t which);
610 void switch_bank (uint32_t base);
612 void solo_changed (uint32_t n) { solo_mute_rec_changed(n); }
613 void mute_changed (uint32_t n) { solo_mute_rec_changed(n); }
614 void rec_changed (uint32_t n) { solo_mute_rec_changed(n); }
615 void solo_iso_changed (uint32_t n);
616 void solo_iso_led_bank ();
618 void master_send_changed (uint32_t n);
619 void master_send_led_bank ();
622 void solo_mute_rec_changed (uint32_t n);
624 /* special Stripable */
626 boost::shared_ptr<ARDOUR::Stripable> master;
628 PBD::ScopedConnection port_reg_connection;
629 void port_registration_handler();
631 enum ConnectionState { InputConnected = 0x1, OutputConnected = 0x2 };
633 int connection_state;
634 bool connection_handler(boost::weak_ptr<ARDOUR::Port>, std::string name1,
635 boost::weak_ptr<ARDOUR::Port>, std::string name2,
637 PBD::ScopedConnection port_connection;
642 mutable LCXLGUI *gui;
645 void stripable_selection_changed();
647 bool in_range_select;
651 } // namespace ArdourSurface
653 #endif /* __ardour_launch_control_h__ */