From 054a09b567fcda7e2aa35b38f5c1255ddefa3d2e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 6 Jul 2023 16:18:37 -0600 Subject: [PATCH] launchpad pro: full communication and note/pad mapping functional --- libs/surfaces/launchpad_pro/lppro.cc | 215 ++++++++++++++++++++++++--- libs/surfaces/launchpad_pro/lppro.h | 38 ++++- 2 files changed, 230 insertions(+), 23 deletions(-) diff --git a/libs/surfaces/launchpad_pro/lppro.cc b/libs/surfaces/launchpad_pro/lppro.cc index fd7ff4c2bc..6a8dfac821 100644 --- a/libs/surfaces/launchpad_pro/lppro.cc +++ b/libs/surfaces/launchpad_pro/lppro.cc @@ -73,6 +73,20 @@ using namespace Gtkmm2ext; #define LAUNCHPADPROMK3 0x0123 static const std::vector sysex_header ({ 0xf0, 0x00, 0x20, 0x29, 0x2, 0xe }); +const LaunchPadPro::PadID LaunchPadPro::all_pad_ids[] = { + Shift, Left, Right, Session, Note, Chord, Custom, Sequencer, Projects, + Patterns, Steps, PatternSettings, Velocity, Probability, Mutation, MicroStep, PrintToClip, + StopClip, Device, Sends, Pan, Volume, Solo, Mute, RecordArm, + CaptureMIDI, Play, FixedLength, Quantize, Duplicate, Clear, Down, Up, + Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8, +}; + +const LaunchPadPro::Layout LaunchPadPro::AllLayouts[] = { + SessionLayout, Fader, ChordLayout, CustomLayout, NoteLayout, Scale, SequencerSettings, + SequencerSteps, SequencerVelocity, SequencerPatternSettings, SequencerProbability, SequencerMutation, + SequencerMicroStep, SequencerProjects, SequencerPatterns, SequencerTempo, SequencerSwing, ProgrammerLayout, Settings, CustomSettings +}; + bool LaunchPadPro::available () { @@ -115,6 +129,7 @@ LaunchPadPro::LaunchPadPro (ARDOUR::Session& s) : MIDISurface (s, X_("Novation Launchpad Pro"), X_("Launchpad Pro"), false) , _daw_out_port (nullptr) , _gui (nullptr) + , _current_layout (SessionLayout) { run_event_loop (); port_setup (); @@ -129,6 +144,7 @@ LaunchPadPro::LaunchPadPro (ARDOUR::Session& s) build_color_map (); build_pad_map (); + build_layout_maps (); } LaunchPadPro::~LaunchPadPro () @@ -143,7 +159,7 @@ LaunchPadPro::~LaunchPadPro () int LaunchPadPro::set_active (bool yn) { - DEBUG_TRACE (DEBUG::Launchpad, string_compose("Launchpad Pro::set_active init with yn: '%1'\n", yn)); + DEBUG_TRACE (DEBUG::Launchpad, string_compose("Launchpad Pro::set_active init with yn: %1\n", yn)); if (yn == active()) { return 0; @@ -155,13 +171,6 @@ LaunchPadPro::set_active (bool yn) return -1; } - if ((_connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) { - std::cerr << "LPP claims connection state is " << _connection_state << std::endl; - begin_using_device (); - } else { - /* begin_using_device () will get called once we're connected */ - } - } else { /* Control Protocol Manager never calls us with false, but * insteads destroys us. @@ -192,16 +201,28 @@ LaunchPadPro::stop_event_loop () int LaunchPadPro::begin_using_device () { + // if (((DEBUG::Launchpad) & PBD::debug_bits).any()) { PBD::debug_print ("Fooey", "bar!"); } DEBUG_TRACE (DEBUG::Launchpad, "begin using device\n"); + std::cerr << "connect to daw port parser\n"; + connect_to_port_parser (*_daw_in_port); + + /* Connect DAW input port to event loop */ + + AsyncMIDIPort* asp; + + asp = dynamic_cast (_daw_in_port); + asp->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &MIDISurface::midi_input_handler), _daw_in_port)); + asp->xthread().attach (main_loop()->get_context()); + set_device_mode (Programmer); - scroll_text ("hello, world", 13, true, 3); + all_pads_off (); + // scroll_text ("hello, world", 13, true, 3); #if 0 init_buttons (true); init_touch_strip (false); reset_pad_colors (); - splash (); /* catch current selection, if any so that we can wire up the pads if appropriate */ stripable_selection_changed (); @@ -276,7 +297,7 @@ LaunchPadPro::input_port_name () const */ return X_("system:midi_capture_1319078870"); #else - return X_("Launchpad Pro MK3 MIDI 1 in"); + return X_("Launchpad Pro MK3 MIDI 1"); #endif } @@ -289,7 +310,7 @@ LaunchPadPro::input_daw_port_name () const */ return X_("system:midi_capture_1319078870"); #else - return X_("Launchpad Pro MK3 MIDI 3 in"); + return X_("Launchpad Pro MK3 MIDI 3"); #endif } @@ -302,7 +323,7 @@ LaunchPadPro::output_port_name () const */ return X_("system:midi_playback_3409210341"); #else - return X_("Launchpad Pro MK3 MIDI 1 out"); + return X_("Launchpad Pro MK3 MIDI 1"); #endif } @@ -315,7 +336,7 @@ LaunchPadPro::output_daw_port_name () const */ return X_("system:midi_playback_3409210341"); #else - return X_("Launchpad Pro MK3 MIDI 3 out"); + return X_("Launchpad Pro MK3 MIDI 3"); #endif } @@ -508,21 +529,34 @@ LaunchPadPro::pad_off (int pad_id) void LaunchPadPro::all_pads_off () { - for (PadMap::iterator p = pad_map.begin(); p != pad_map.end(); ++p) { - Pad& pad (p->second); - pad.set (13, Pad::Static); - write (pad.state_msg()); + MidiByteArray msg (sysex_header); + msg.reserve (msg.size() + (106 * 3) + 3); + msg.push_back (0x3); + for (size_t n = 1; n < 32; ++n) { + msg.push_back (0x0); + msg.push_back (n); + msg.push_back (13); } + msg.push_back (0xf7); + write (msg); } void -LaunchPadPro::all_pads_on () +LaunchPadPro::all_pads_on (int color) { + MidiByteArray msg (sysex_header); + msg.push_back (0xe); + msg.push_back (color & 0x7f); + msg.push_back (0xf7); + write (msg); + +#if 0 for (PadMap::iterator p = pad_map.begin(); p != pad_map.end(); ++p) { Pad& pad (p->second); pad.set (random() % color_map.size(), Pad::Static); write (pad.state_msg()); } +#endif } void @@ -569,6 +603,24 @@ void LaunchPadPro::handle_midi_sysex (MIDI::Parser&, MIDI::byte* raw_bytes, size_t sz) { DEBUG_TRACE (DEBUG::Launchpad, string_compose ("Sysex, %1 bytes\n", sz)); + + if (sz < sysex_header.size() + 1) { + return; + } + + raw_bytes += sysex_header.size(); + + switch (raw_bytes[0]) { + case 0x0: /* layout info */ + if (sz < sysex_header.size() + 2) { + return; + } + _current_layout = AllLayouts[raw_bytes[1]]; + std::cerr << "Current layout = " << _current_layout << std::endl; + break; + default: + break; + } } void @@ -586,13 +638,16 @@ LaunchPadPro::handle_midi_note_on_message (MIDI::Parser& parser, MIDI::EventTwoB return; } - DEBUG_TRACE (DEBUG::Launchpad, string_compose ("Note On %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity)); + DEBUG_TRACE (DEBUG::Launchpad, string_compose ("Note On %1/0x%3%4%5 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity, std::hex, (int) ev->note_number, std::dec)); + const int idx = (_current_layout * 127) + ev->note_number; + const int coord = layout_note_xy_map[idx]; } void LaunchPadPro::handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes* ev) { DEBUG_TRACE (DEBUG::Launchpad, string_compose ("Note Off %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity)); + } void @@ -607,11 +662,13 @@ LaunchPadPro::connect_daw_ports () { if (!_daw_in || !_daw_out) { /* ports not registered yet */ + std::cerr << "no daw port registered\n"; return; } if (_daw_in->connected() && _daw_out->connected()) { /* don't waste cycles here */ + std::cerr << "daw port already connected\n"; return; } @@ -647,8 +704,6 @@ LaunchPadPro::ports_acquire () return 0; } - connect_to_port_parser (*_daw_in_port); - ret = -1; } @@ -712,3 +767,119 @@ LaunchPadPro::scroll_text (std::string const & txt, int color, bool loop, float write (msg); } } + +void +LaunchPadPro::build_layout_maps () +{ + static const XY_Note_Map maps[] = { + { /* Session */ + { 0xb, 0xc, 0xe, 0xd, 0xf, 0x10, 0x11, 0x12 }, + { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c }, + { 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }, + { 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30 }, + { 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a }, + { 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44 }, + { 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e }, + { 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58 } + }, + + { /* Fader */ + { 0x0, 0x15, 0x2a, 0x3f, 0x40, 0x55, 0x6a, 0x7f }, + { 0x0, 0x15, 0x2a, 0x3f, 0x40, 0x55, 0x6a, 0x7f }, + { 0x0, 21, 42, 63, 64, 85, 106, 127 }, + { 0x0, 21, 42, 63, 64, 85, 106, 127 }, + { 0x0, 0x11, 0x22, 0x34, 0x46, 0x59, 0x6c, 0x7f }, + { 0x0, 0x11, 0x22, 0x34, 0x46, 0x59, 0x6c, 0x7f }, + { 0x0, 17, 34, 52, 70, 89, 108, 127 }, + { 0x0, 17, 34, 52, 70, 89, 108, 127 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Vertical Fader */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* Programmer */ + + { 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12 }, + { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c }, + { 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }, + { 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30 }, + { 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a }, + { 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44 }, + { 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e }, + { 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58 } + }, + { /* Settings */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }, + { /* CustomSettings */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + } + }; + + const size_t num_layouts = sizeof (AllLayouts) / sizeof (AllLayouts[0]); + + layout_xy_note_map.resize (num_layouts * 64); + + for (auto const layout : AllLayouts) { + for (int row = 0; row < 8; ++row) { + for (int col = 0; col < 8; ++col) { + const int idx = (layout * 64) + (row*8) + col; + layout_xy_note_map[idx] = maps[layout][row][col]; + } + } + } + + layout_note_xy_map.resize (128 * num_layouts); + + for (auto const layout : AllLayouts) { + for (int row = 0; row < 8; ++row) { + for (int col = 0; col < 8; ++col) { + const int idx1 = (layout * 64) + (row*8) + col; + const int note = layout_xy_note_map[idx1]; + const int idx2 = (layout * 127) + note; + layout_note_xy_map[idx2] = row*8 + col; + } + } + } +} diff --git a/libs/surfaces/launchpad_pro/lppro.h b/libs/surfaces/launchpad_pro/lppro.h index 4cba46f403..b0f238cc22 100644 --- a/libs/surfaces/launchpad_pro/lppro.h +++ b/libs/surfaces/launchpad_pro/lppro.h @@ -113,6 +113,8 @@ class LaunchPadPro : public MIDISurface Lower8 = 0x6c }; + static const PadID all_pad_ids[]; + LaunchPadPro (ARDOUR::Session&); ~LaunchPadPro (); @@ -139,6 +141,31 @@ class LaunchPadPro : public MIDISurface Programmer }; + enum Layout { + SessionLayout, + Fader, + ChordLayout, + CustomLayout, + NoteLayout, + Scale, + SequencerSettings, + SequencerSteps, + SequencerVelocity, + SequencerPatternSettings, + SequencerProbability, + SequencerMutation, + SequencerMicroStep, + SequencerProjects, + SequencerPatterns, + SequencerTempo, + SequencerSwing, + ProgrammerLayout, + Settings, + CustomSettings + }; + + static const Layout AllLayouts[]; + typedef std::map ColorMap; ColorMap color_map; void build_color_map (); @@ -219,7 +246,7 @@ class LaunchPadPro : public MIDISurface void light_pad (int pad_id, int color, Pad::ColorMode); void pad_off (int pad_id); void all_pads_off (); - void all_pads_on (); + void all_pads_on (int color); void set_device_mode (DeviceMode); @@ -250,6 +277,15 @@ class LaunchPadPro : public MIDISurface mutable LPPRO_GUI* _gui; void build_gui (); + + typedef int XY_Note_Map[8][8]; + typedef int Note_XY_Map[127]; + + std::vector layout_xy_note_map; + std::vector layout_note_xy_map; + + void build_layout_maps (); + Layout _current_layout; }; } /* namespace */