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.
21 #include "ardour/debug.h"
22 #include "ardour/mute_control.h"
23 #include "ardour/session.h"
24 #include "ardour/solo_control.h"
26 #include "launch_control_xl.h"
28 using namespace ArdourSurface;
29 using namespace ARDOUR;
34 LaunchControlXL::build_maps ()
40 #define MAKE_KNOB(i,cc, index, color) \
41 knob = new Knob ((i), (cc), (index), (color), (*this)); \
42 cc_knob_map.insert (std::make_pair (knob->controller_number(), knob)); \
43 id_knob_map.insert (std::make_pair (knob->id(), knob))
45 for (uint8_t n = 0; n < 8; ++n) {
46 MAKE_KNOB (static_cast<KnobID>(n), (n + 13), n, RedFull);
47 MAKE_KNOB (static_cast<KnobID>(n + 8), (n + 29), (n + 8), GreenFull);
48 MAKE_KNOB (static_cast<KnobID>(n + 16), (n + 49), (n + 16), Yellow);
55 #define MAKE_FADER(i,cc) \
56 fader = new Fader ((i), (cc)); \
57 cc_fader_map.insert (std::make_pair (fader->controller_number(), fader)); \
58 id_fader_map.insert (std::make_pair (fader->id(), fader))
60 for (uint8_t n = 0; n < 8; ++n) {
61 MAKE_FADER (static_cast<FaderID>(n), (n + 77) );
66 ControllerButton *controller_button;
67 NoteButton *note_button;
70 #define MAKE_TRACK_BUTTON_PRESS(i,nn,index,color,p) \
71 note_button = new TrackButton ((i), (nn), (index), (color), (p), (*this)); \
72 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
73 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
74 #define MAKE_SELECT_BUTTON_PRESS(i,cc,index,p) \
75 controller_button = new SelectButton ((i), (cc), (index), (p), (*this)); \
76 cc_controller_button_map.insert (std::make_pair (controller_button->controller_number(), controller_button)); \
77 id_controller_button_map.insert (std::make_pair (controller_button->id(), controller_button))
78 #define MAKE_TRACK_STATE_BUTTON_PRESS(i,nn,index,p) \
79 note_button = new TrackStateButton ((i), (nn), (index), (p), (*this)); \
80 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
81 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
82 #define MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(i,nn,index, p,r,l) \
83 note_button = new TrackStateButton ((i), (nn), (index), (p), (r), (l), (*this)); \
84 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
85 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
88 MAKE_TRACK_BUTTON_PRESS(Focus1, 41, 24, GreenFull, &LaunchControlXL::button_track_focus_1);
89 MAKE_TRACK_BUTTON_PRESS(Focus2, 42, 25, GreenFull, &LaunchControlXL::button_track_focus_2);
90 MAKE_TRACK_BUTTON_PRESS(Focus3, 43, 26, GreenFull, &LaunchControlXL::button_track_focus_3);
91 MAKE_TRACK_BUTTON_PRESS(Focus4, 44, 27, GreenFull, &LaunchControlXL::button_track_focus_4);
92 MAKE_TRACK_BUTTON_PRESS(Focus5, 57, 28, GreenFull, &LaunchControlXL::button_track_focus_5);
93 MAKE_TRACK_BUTTON_PRESS(Focus6, 58, 29, GreenFull, &LaunchControlXL::button_track_focus_6);
94 MAKE_TRACK_BUTTON_PRESS(Focus7, 59, 30, GreenFull, &LaunchControlXL::button_track_focus_7);
95 MAKE_TRACK_BUTTON_PRESS(Focus8, 60, 31, GreenFull, &LaunchControlXL::button_track_focus_8);
96 MAKE_TRACK_BUTTON_PRESS(Control1, 73, 32, Yellow, &LaunchControlXL::button_track_control_1);
97 MAKE_TRACK_BUTTON_PRESS(Control2, 74, 33, Yellow, &LaunchControlXL::button_track_control_2);
98 MAKE_TRACK_BUTTON_PRESS(Control3, 75, 34, Yellow, &LaunchControlXL::button_track_control_3);
99 MAKE_TRACK_BUTTON_PRESS(Control4, 76, 35, Yellow, &LaunchControlXL::button_track_control_4);
100 MAKE_TRACK_BUTTON_PRESS(Control5, 89, 36, Yellow, &LaunchControlXL::button_track_control_5);
101 MAKE_TRACK_BUTTON_PRESS(Control6, 90, 37, Yellow, &LaunchControlXL::button_track_control_6);
102 MAKE_TRACK_BUTTON_PRESS(Control7, 91, 38, Yellow, &LaunchControlXL::button_track_control_7);
103 MAKE_TRACK_BUTTON_PRESS(Control8, 92, 39, Yellow, &LaunchControlXL::button_track_control_8);
105 MAKE_SELECT_BUTTON_PRESS(SelectUp, 104, 44, &LaunchControlXL::button_select_up);
106 MAKE_SELECT_BUTTON_PRESS(SelectDown, 105, 45, &LaunchControlXL::button_select_down);
107 MAKE_SELECT_BUTTON_PRESS(SelectLeft, 106, 46, &LaunchControlXL::button_select_left);
108 MAKE_SELECT_BUTTON_PRESS(SelectRight, 107, 47, &LaunchControlXL::button_select_right);
110 MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(Device, 105, 40, &LaunchControlXL::relax, &LaunchControlXL::button_device, &LaunchControlXL::button_device_long_press);;
111 MAKE_TRACK_STATE_BUTTON_PRESS(Mute, 106, 41, &LaunchControlXL::button_mute);
112 MAKE_TRACK_STATE_BUTTON_PRESS(Solo, 107, 42, &LaunchControlXL::button_solo);
113 MAKE_TRACK_STATE_BUTTON_PRESS(Record, 108, 43, &LaunchControlXL::button_record);
118 LaunchControlXL::button_name_by_id (ButtonID id)
132 return "Select Down";
134 return "Select Right";
136 return "Select Left";
177 LaunchControlXL::knob_name_by_id (KnobID id)
236 LaunchControlXL::fader_name_by_id (FaderID id)
262 LaunchControlXL::TrackButton*
263 LaunchControlXL::track_button_by_number(uint8_t n, uint8_t first, uint8_t middle)
265 NNNoteButtonMap::iterator b;
267 b = nn_note_button_map.find (first + n);
269 b = nn_note_button_map.find (middle + n - 4);
272 TrackButton* button = 0;
274 if (b != nn_note_button_map.end()) {
275 button = static_cast<TrackButton*>(b->second);
283 LaunchControlXL::button_track_focus(uint8_t n)
289 TrackButton* b = focus_button_by_number(n);
295 if ( stripable[n]->is_selected() ) {
296 b->set_color(AmberFull);
298 b->set_color(AmberLow);
300 write (b->state_msg());
304 boost::shared_ptr<AutomationControl>
305 LaunchControlXL::get_ac_by_state(uint8_t n) {
306 boost::shared_ptr<AutomationControl> ac;
308 switch(track_mode()) {
310 ac = stripable[n]->mute_control();
314 ac = stripable[n]->solo_control();
318 ac = stripable[n]->rec_enable_control();
329 LaunchControlXL::update_track_control_led(uint8_t n)
331 TrackButton* b = control_button_by_number(n);
333 if (!stripable[n] || !b) {
337 boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
340 switch(track_mode()) {
342 if (ac->get_value()) {
343 b->set_color(AmberFull);
345 b->set_color(AmberLow);
350 if (ac && stripable[n] != master ) {
351 if (ac->get_value()) {
352 b->set_color(GreenFull);
354 b->set_color(GreenLow);
363 if (ac->get_value()) {
364 b->set_color(RedFull);
366 b->set_color(RedLow);
377 write (b->state_msg());
382 LaunchControlXL::solo_mute_rec_changed(uint32_t n) {
386 update_track_control_led(n);
390 LaunchControlXL::button_track_control(uint8_t n) {
394 boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
397 session->set_control (ac, !ac->get_value(), PBD::Controllable::UseGroup);
402 LaunchControlXL::button_track_mode(TrackMode state)
404 set_track_mode(state);
405 for (uint8_t n = 0; n < 8; ++n) {
406 update_track_control_led(n);
409 TrackStateButton* mute = static_cast<TrackStateButton*>(id_note_button_map[Mute]);
410 TrackStateButton* solo = static_cast<TrackStateButton*>(id_note_button_map[Solo]);
411 TrackStateButton* record = static_cast<TrackStateButton*>(id_note_button_map[Record]);
413 write(mute->state_msg( (state == TrackMute) ));
414 write(solo->state_msg( (state == TrackSolo) ));
415 write(record->state_msg( (state == TrackRecord) ));
419 LaunchControlXL::button_select_left()
421 switch_bank (max (0, bank_start - 1));
425 LaunchControlXL::button_select_right()
427 switch_bank (max (0, bank_start + 1));
431 LaunchControlXL::button_select_up()
437 LaunchControlXL::button_select_down()
443 LaunchControlXL::button_device()
449 LaunchControlXL::button_device_long_press()
455 LaunchControlXL::button_long_press_timeout (ButtonID id, Button* button)
457 if (buttons_down.find (id) != buttons_down.end()) {
458 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, invoking method\n", id));
459 (this->*button->long_press_method) ();
461 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, expired/cancelled\n", id));
462 /* release happened and somehow we were not cancelled */
465 /* whichever button this was, we've used it ... don't invoke the
468 consumed.insert (id);
470 return false; /* don't get called again */
475 LaunchControlXL::start_press_timeout (Button* button, ButtonID id)
477 Glib::RefPtr<Glib::TimeoutSource> timeout = Glib::TimeoutSource::create (500); // milliseconds
478 button->timeout_connection = timeout->connect (sigc::bind (sigc::mem_fun (*this, &LaunchControlXL::button_long_press_timeout), id, button));
479 timeout->attach (main_loop()->get_context());