#include "midi++/parser.h"
-#include "temporal/time.h"
-#include "temporal/bbt_time.h"
-
#include "ardour/amp.h"
#include "ardour/async_midi_port.h"
#include "ardour/audioengine.h"
/* master cannot be removed, so no need to connect to going-away signal */
master = session->master_out ();
- /* the master bus will always be on the last channel on the lcxl */
- stripable[7] = master;
-
run_event_loop ();
ports_release ();
stop_event_loop ();
+ tear_down_gui ();
}
connect_session_signals ();
-
init_buttons (true);
in_use = true;
+ DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose("use_fader8master inital value '%1'\n", use_fader8master));
+ set_fader8master(use_fader8master);
+
return 0;
}
void
LaunchControlXL::init_buttons (bool startup)
{
+ reset(template_number());
+
if (startup) {
- button_track_mode(track_mode());
+ switch_bank(bank_start);
}
}
}
}
+void
+LaunchControlXL::reset(uint8_t chan)
+{
+ MidiByteArray msg (3, 176 + chan, 0, 0); // turn off all leds, reset buffer settings and duty cycle
+
+ write(msg);
+}
int
LaunchControlXL::set_active (bool yn)
{
NoteButton* nb = id_note_button_map[*x];
if (cb != 0) {
cb->timeout_connection.disconnect();
- }
- else if (nb != 0) {
+ } else if (nb != 0) {
nb->timeout_connection.disconnect();
}
}
buttons_down.insert(button->id());
DEBUG_TRACE(DEBUG::LaunchControlXL, string_compose("button pressed: %1\n", LaunchControlXL::button_name_by_id(button->id())));
start_press_timeout(button, button->id());
- }
- else {
+ } else {
DEBUG_TRACE(DEBUG::LaunchControlXL, string_compose("button depressed: %1\n", LaunchControlXL::button_name_by_id(button->id())));
buttons_down.erase(button->id());
button->timeout_connection.disconnect();
if (c == consumed.end()) {
if (ev->value == 0) {
(this->*button->release_method)();
- }
- else {
+ } else {
(this->*button->press_method)();
}
- }
- else {
+ } else {
DEBUG_TRACE(DEBUG::LaunchControlXL, "button was consumed, ignored\n");
consumed.erase(c);
}
}
+bool
+LaunchControlXL::check_pick_up(Controller* controller, boost::shared_ptr<AutomationControl> ac)
+{
+ /* returns false until the controller value matches with the current setting of the stripable's ac */
+ return ( abs( controller->value() / 127.0 - ac->internal_to_interface(ac->get_value()) ) < 0.007875 );
+}
+
void
LaunchControlXL::handle_knob_message (Knob* knob)
{
boost::shared_ptr<AutomationControl> ac;
- if (knob->id() < 8) { // sendA
- ac = stripable[chan]->trim_control();
- }
- else if (knob->id() >= 8 && knob->id() < 16) { // sendB
- ac = stripable[chan]->pan_width_control();
- }
- else if (knob->id() >= 16 && knob->id() < 24) { // pan
- ac = stripable[chan]->pan_azimuth_control();
+ if (knob->id() < 8) { // sendA knob
+ if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
+ ac = stripable[chan]->trim_control();
+ } else {
+ ac = stripable[chan]->send_level_controllable (0);
+ }
+ } else if (knob->id() >= 8 && knob->id() < 16) { // sendB knob
+ if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
+#ifdef MIXBUS
+ ac = stripable[chan]->filter_freq_controllable (true);
+#else
+ /* something */
+#endif
+ } else {
+ ac = stripable[chan]->send_level_controllable (1);
+ }
+ } else if (knob->id() >= 16 && knob->id() < 24) { // pan knob
+ if (buttons_down.find(Device) != buttons_down.end()) { // Device button hold
+#ifdef MIXBUS
+ ac = stripable[chan]->comp_threshold_controllable();
+#else
+ ac = stripable[chan]->pan_width_control();
+#endif
+ } else {
+ ac = stripable[chan]->pan_azimuth_control();
+ }
}
- if (ac) {
+ if (ac && check_pick_up(knob, ac)) {
ac->set_value ( ac->interface_to_internal( knob->value() / 127.0), PBD::Controllable::UseGroup );
}
}
}
boost::shared_ptr<AutomationControl> ac = stripable[fader->id()]->gain_control();
- if (ac) {
+ if (ac && check_pick_up(fader, ac)) {
ac->set_value ( ac->interface_to_internal( fader->value() / 127.0), PBD::Controllable::UseGroup );
}
}
// DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("CC %1 (value %2)\n", (int) ev->controller_number, (int) ev->value));
CCControllerButtonMap::iterator b = cc_controller_button_map.find (ev->controller_number);
- CCFaderMap::iterator f = cc_fader_map.find (ev->controller_number);
+ CCFaderMap::iterator f = cc_fader_map.find (ev->controller_number);
CCKnobMap::iterator k = cc_knob_map.find (ev->controller_number);
if (b != cc_controller_button_map.end()) {
Button* button = b->second;
handle_button_message(button, ev);
- }
- else if (f != cc_fader_map.end()) {
+ } else if (f != cc_fader_map.end()) {
Fader* fader = f->second;
fader->set_value(ev->value);
handle_fader_message(fader);
- }
- else if (k != cc_knob_map.end()) {
+ } else if (k != cc_knob_map.end()) {
Knob* knob = k->second;
knob->set_value(ev->value);
handle_knob_message(knob);
NNNoteButtonMap::iterator b = nn_note_button_map.find (ev->controller_number);
if (b != nn_note_button_map.end()) {
- Button* button = b->second;
- handle_button_message(button, ev);
- }
+ Button* button = b->second;
+ handle_button_message(button, ev);
+ }
}
void LaunchControlXL::handle_midi_note_off_message(MIDI::Parser & parser, MIDI::EventTwoBytes *ev, MIDI::channel_t chan)
child->add_child_nocopy (_async_out->get_state());
node.add_child_nocopy (*child);
+ child = new XMLNode (X_("Configuration"));
+ child->set_property ("fader8master", LaunchControlXL::use_fader8master);
+ node.add_child_nocopy (*child);
+
return node;
}
}
}
+ if ((child = node.child (X_("Configuration"))) !=0) {
+ /* this should propably become a for-loop at some point */
+ child->get_property ("fader8master", use_fader8master);
+ }
+
return retval;
}
return;
}
if (which < 8) {
- button_track_focus( (uint8_t)which );
+ update_track_focus_led ((uint8_t) which);
+ update_knob_led((uint8_t) which);
}
}
-
}
void
SelectButton* sl = static_cast<SelectButton*>(id_controller_button_map[SelectLeft]);
SelectButton* sr = static_cast<SelectButton*>(id_controller_button_map[SelectRight]);
- if (sl && sr) {
- write(sl->state_msg( (base) ));
- write(sr->state_msg( !(base) ));
- }
-
-
-
- stripable_connections.drop_connections ();
-
/* work backwards so we can tell if we should actually switch banks */
boost::shared_ptr<Stripable> s[8];
uint32_t different = 0;
+ int stripable_counter;
+
+ if (LaunchControlXL::use_fader8master) {
+ stripable_counter = 7;
+ } else {
+ stripable_counter = 8;
+ }
- for (int n = 0; n < 7; ++n) {
+ for (int n = 0; n < stripable_counter; ++n) {
s[n] = session->get_remote_nth_stripable (base+n, PresentationInfo::Flag (PresentationInfo::Route|PresentationInfo::VCA));
if (s[n] != stripable[n]) {
different++;
}
}
+ if (sl && sr) {
+ write(sl->state_msg((base)));
+ write(sr->state_msg((s[1] != 0)));
+ }
+
if (!s[0]) {
/* not even the first stripable exists, do nothing */
- for (int n = 0; n < 7; ++n) {
- stripable[n].reset ();
- }
return;
}
- for (int n = 0; n < 7; ++n) {
+ stripable_connections.drop_connections ();
+
+ for (int n = 0; n < stripable_counter; ++n) {
stripable[n] = s[n];
}
if (stripable[n]->rec_enable_control()) {
stripable[n]->rec_enable_control()->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::rec_changed, this, n), lcxl);
}
-
-
- button_track_focus(n);
- update_track_control_led(n);
}
+ update_track_focus_led(n);
+ button_track_mode(track_mode());
+ update_knob_led(n);
}
}
break;
}
}
+
+void
+LaunchControlXL::set_fader8master (bool yn)
+{
+ if (yn) {
+ stripable[7] = master;
+ }
+ switch_bank(bank_start);
+}