2018-08-06 21:41:12 -04:00
|
|
|
/*
|
2019-08-03 08:34:29 -04:00
|
|
|
* Copyright (C) 2018 Jan Lentfer <jan.lentfer@web.de>
|
|
|
|
* Copyright (C) 2018 Robin Gareus <robin@gareus.org>
|
|
|
|
* Copyright (C) 2018 Térence Clastres <t.clastres@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
#ifndef __ardour_launch_control_h__
|
|
|
|
#define __ardour_launch_control_h__
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
#include <stack>
|
|
|
|
#include <list>
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
#define ABSTRACT_UI_EXPORTS
|
|
|
|
#include "pbd/abstract_ui.h"
|
|
|
|
|
|
|
|
#include "midi++/types.h"
|
|
|
|
|
|
|
|
#include "ardour/mode.h"
|
|
|
|
#include "ardour/types.h"
|
|
|
|
|
|
|
|
#include "control_protocol/control_protocol.h"
|
|
|
|
#include "control_protocol/types.h"
|
|
|
|
|
|
|
|
#include "midi_byte_array.h"
|
|
|
|
|
|
|
|
namespace MIDI {
|
|
|
|
class Parser;
|
|
|
|
class Port;
|
|
|
|
} // namespace MIDI
|
|
|
|
|
|
|
|
namespace ARDOUR {
|
|
|
|
class AsyncMIDIPort;
|
|
|
|
class Port;
|
|
|
|
class MidiBuffer;
|
|
|
|
class MidiTrack;
|
|
|
|
} // namespace ARDOUR
|
|
|
|
|
|
|
|
namespace ArdourSurface {
|
|
|
|
|
|
|
|
|
|
|
|
struct LaunchControlRequest : public BaseUI::BaseRequestObject {
|
2018-08-07 09:30:26 -04:00
|
|
|
public:
|
|
|
|
LaunchControlRequest() {}
|
|
|
|
~LaunchControlRequest() {}
|
2018-08-06 21:41:12 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
class LCXLGUI;
|
|
|
|
class LaunchControlMenu;
|
|
|
|
|
|
|
|
class LaunchControlXL : public ARDOUR::ControlProtocol,
|
2018-08-24 10:53:06 -04:00
|
|
|
public AbstractUI<LaunchControlRequest>
|
|
|
|
{
|
2018-08-06 21:41:12 -04:00
|
|
|
public:
|
2018-08-07 09:30:26 -04:00
|
|
|
enum TrackMode {
|
|
|
|
TrackMute,
|
|
|
|
TrackSolo,
|
|
|
|
TrackRecord
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ButtonID {
|
|
|
|
Focus1 = 0,
|
|
|
|
Focus2,
|
|
|
|
Focus3,
|
|
|
|
Focus4,
|
|
|
|
Focus5,
|
|
|
|
Focus6,
|
|
|
|
Focus7,
|
|
|
|
Focus8,
|
|
|
|
Control1,
|
|
|
|
Control2,
|
|
|
|
Control3,
|
|
|
|
Control4,
|
|
|
|
Control5,
|
|
|
|
Control6,
|
|
|
|
Control7,
|
|
|
|
Control8,
|
|
|
|
Device,
|
|
|
|
Mute,
|
|
|
|
Solo,
|
|
|
|
Record,
|
|
|
|
SelectUp,
|
|
|
|
SelectDown,
|
|
|
|
SelectLeft,
|
|
|
|
SelectRight
|
|
|
|
};
|
|
|
|
|
|
|
|
enum FaderID {
|
|
|
|
Fader1 = 0,
|
|
|
|
Fader2,
|
|
|
|
Fader3,
|
|
|
|
Fader4,
|
|
|
|
Fader5,
|
|
|
|
Fader6,
|
|
|
|
Fader7,
|
|
|
|
Fader8
|
|
|
|
};
|
|
|
|
|
|
|
|
enum KnobID {
|
|
|
|
SendA1 = 0,
|
|
|
|
SendA2,
|
|
|
|
SendA3,
|
|
|
|
SendA4,
|
|
|
|
SendA5,
|
|
|
|
SendA6,
|
|
|
|
SendA7,
|
|
|
|
SendA8,
|
|
|
|
SendB1,
|
|
|
|
SendB2,
|
|
|
|
SendB3,
|
|
|
|
SendB4,
|
|
|
|
SendB5,
|
|
|
|
SendB6,
|
|
|
|
SendB7,
|
|
|
|
SendB8,
|
|
|
|
Pan1,
|
|
|
|
Pan2,
|
|
|
|
Pan3,
|
|
|
|
Pan4,
|
|
|
|
Pan5,
|
|
|
|
Pan6,
|
|
|
|
Pan7,
|
|
|
|
Pan8
|
|
|
|
};
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
enum DeviceStatus {
|
|
|
|
dev_nonexistant = 0,
|
|
|
|
dev_inactive,
|
|
|
|
dev_active
|
|
|
|
};
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
enum LEDFlag { Normal = 0xC, Blink = 0x8, DoubleBuffering = 0x0 };
|
2018-08-13 20:59:58 -04:00
|
|
|
enum LEDColor { Off=0, RedLow = 1, RedFull = 3, GreenLow = 16, GreenFull = 48, YellowLow = 34, YellowFull = 51, AmberLow = 18, AmberFull = 35};
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
#ifdef MIXBUS
|
|
|
|
enum CompParam {
|
|
|
|
CompMakeup,
|
|
|
|
CompMode,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct Controller {
|
2024-10-18 19:51:44 -04:00
|
|
|
Controller(uint8_t cn, uint8_t val, std::function<void ()> action)
|
2018-09-08 13:03:45 -04:00
|
|
|
: _controller_number(cn)
|
|
|
|
, _value(val)
|
|
|
|
, action_method(action) {}
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
uint8_t controller_number() const { return _controller_number; }
|
|
|
|
uint8_t value() const { return _value; }
|
|
|
|
void set_value(uint8_t val) { _value = val; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
uint8_t _controller_number;
|
|
|
|
uint8_t _value;
|
2018-09-08 13:03:45 -04:00
|
|
|
|
|
|
|
public:
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> action_method;
|
2018-08-07 09:30:26 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct LED {
|
2018-08-07 09:48:39 -04:00
|
|
|
LED(uint8_t i, LEDColor c, LaunchControlXL& l) : _index(i), _color(c), _flag(Normal), lcxl(&l) {}
|
2018-08-07 09:30:26 -04:00
|
|
|
LED(uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& lcxl) : _index(i), _color(c), _flag(f) {}
|
2018-08-07 09:36:22 -04:00
|
|
|
virtual ~LED() {}
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
LEDColor color() const { return _color; }
|
|
|
|
LEDFlag flag() const { return _flag; }
|
|
|
|
uint8_t index() const { return _index; }
|
|
|
|
void set_flag(LEDFlag f) { _flag = f; }
|
|
|
|
|
|
|
|
virtual MidiByteArray state_msg(bool light) const = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
uint8_t _index;
|
|
|
|
LEDColor _color;
|
|
|
|
LEDFlag _flag;
|
|
|
|
MidiByteArray _state_msg;
|
|
|
|
LaunchControlXL* lcxl;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MultiColorLED : public LED {
|
|
|
|
MultiColorLED (uint8_t i, LEDColor c, LaunchControlXL& l) : LED(i, c, l) {}
|
|
|
|
MultiColorLED (uint8_t i, LEDColor c, LEDFlag f, LaunchControlXL& l)
|
|
|
|
: LED(i, c, f, l) {}
|
|
|
|
|
|
|
|
void set_color(LEDColor c) { _color = c; }
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Button {
|
2024-10-18 19:51:44 -04:00
|
|
|
Button(ButtonID id, std::function<void ()> press, std::function<void ()> release,
|
|
|
|
std::function<void ()> long_press)
|
2018-08-07 09:30:26 -04:00
|
|
|
: press_method(press)
|
2018-09-21 10:06:16 -04:00
|
|
|
, release_method(release)
|
|
|
|
, long_press_method(long_press),
|
|
|
|
_id(id) {}
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
virtual ~Button() {}
|
|
|
|
|
|
|
|
ButtonID id() const { return _id; }
|
|
|
|
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press_method;
|
|
|
|
std::function<void ()> release_method;
|
|
|
|
std::function<void ()> long_press_method;
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
sigc::connection timeout_connection;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
ButtonID _id;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ControllerButton : public Button {
|
|
|
|
ControllerButton(ButtonID id, uint8_t cn,
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press,
|
|
|
|
std::function<void ()> release,
|
|
|
|
std::function<void ()> long_release)
|
2018-09-21 10:06:16 -04:00
|
|
|
: Button(id, press, release, long_release), _controller_number(cn) {}
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
uint8_t controller_number() const { return _controller_number; }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
private:
|
|
|
|
uint8_t _controller_number;
|
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct NoteButton : public Button {
|
|
|
|
NoteButton(ButtonID id, uint8_t cn,
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press,
|
|
|
|
std::function<void ()> release,
|
|
|
|
std::function<void ()> release_long)
|
2018-08-07 09:30:26 -04:00
|
|
|
: Button(id, press, release, release_long), _note_number(cn) {}
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
uint8_t note_number() const { return _note_number; }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
private:
|
|
|
|
uint8_t _note_number;
|
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct TrackButton : public NoteButton, public MultiColorLED {
|
2018-09-21 10:06:16 -04:00
|
|
|
TrackButton(ButtonID id, uint8_t nn, uint8_t index, LEDColor c_on, LEDColor c_off,
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press,
|
|
|
|
std::function<void ()> release,
|
|
|
|
std::function<void ()> release_long,
|
|
|
|
std::function<uint8_t ()> check,
|
2018-08-07 09:30:26 -04:00
|
|
|
LaunchControlXL& l)
|
2018-09-21 10:06:16 -04:00
|
|
|
: NoteButton(id, nn, press, release, release_long)
|
|
|
|
, MultiColorLED(index, Off, l)
|
|
|
|
, check_method(check)
|
|
|
|
, _color_enabled (c_on)
|
|
|
|
, _color_disabled (c_off) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LEDColor color_enabled() const { return _color_enabled; }
|
|
|
|
LEDColor color_disabled() const { return _color_disabled; }
|
|
|
|
void set_color_enabled (LEDColor c_on) { _color_enabled = c_on; }
|
|
|
|
void set_color_disabled (LEDColor c_off) { _color_disabled = c_off; }
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<uint8_t ()> check_method;
|
2018-09-21 10:06:16 -04:00
|
|
|
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
MidiByteArray state_msg(bool light = true) const;
|
2018-09-21 10:06:16 -04:00
|
|
|
|
|
|
|
private:
|
|
|
|
LEDColor _color_enabled;
|
|
|
|
LEDColor _color_disabled;
|
2018-08-07 09:30:26 -04:00
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct SelectButton : public ControllerButton, public LED {
|
2018-09-21 10:06:16 -04:00
|
|
|
SelectButton(ButtonID id, uint8_t cn, uint8_t index,
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press,
|
|
|
|
std::function<void ()> release,
|
|
|
|
std::function<void ()> long_release,
|
2018-09-21 10:06:16 -04:00
|
|
|
LaunchControlXL& l)
|
|
|
|
: ControllerButton(id, cn, press, release, long_release), LED(index, RedFull, l) {}
|
|
|
|
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
MidiByteArray state_msg(bool light) const;
|
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct TrackStateButton : public NoteButton, public LED {
|
2018-09-21 10:06:16 -04:00
|
|
|
TrackStateButton(ButtonID id, uint8_t nn, uint8_t index,
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<void ()> press,
|
|
|
|
std::function<void ()> release,
|
|
|
|
std::function<void ()> release_long,
|
2018-08-07 09:30:26 -04:00
|
|
|
LaunchControlXL& l)
|
|
|
|
: NoteButton(id, nn, press, release, release_long)
|
2018-08-13 20:59:58 -04:00
|
|
|
, LED(index, YellowLow, l) {}
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
MidiByteArray state_msg(bool light) const;
|
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct Fader : public Controller {
|
2024-10-18 19:51:44 -04:00
|
|
|
Fader(FaderID id, uint8_t cn, std::function<void ()> action)
|
2018-09-08 13:03:45 -04:00
|
|
|
: Controller(cn, 0, action), _id(id) {} // minimal value
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
FaderID id() const { return _id; }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void controller_changed(Controller* controller);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
private:
|
|
|
|
FaderID _id;
|
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
struct Knob : public Controller, public MultiColorLED {
|
2024-10-18 19:51:44 -04:00
|
|
|
Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, std::function<void ()> action,
|
2018-09-21 10:06:16 -04:00
|
|
|
LaunchControlXL &l)
|
2018-09-08 13:03:45 -04:00
|
|
|
: Controller(cn, 64, action)
|
2018-08-13 20:59:58 -04:00
|
|
|
, MultiColorLED(index, Off, l)
|
2018-09-21 10:06:16 -04:00
|
|
|
, _id(id)
|
|
|
|
, _color_enabled (c_on)
|
|
|
|
, _color_disabled (c_off) {} // knob 50/50 value
|
|
|
|
|
2024-10-18 19:51:44 -04:00
|
|
|
Knob(KnobID id, uint8_t cn, uint8_t index, LEDColor c_on, LEDColor c_off, std::function<void ()> action,
|
|
|
|
std::function<uint8_t ()> check, LaunchControlXL &l)
|
2018-09-21 10:06:16 -04:00
|
|
|
: Controller(cn, 64, action)
|
|
|
|
, MultiColorLED(index, Off, l)
|
|
|
|
, check_method(check)
|
|
|
|
, _id(id)
|
|
|
|
, _color_enabled (c_on)
|
|
|
|
, _color_disabled (c_off) {} // knob 50/50 value
|
|
|
|
|
|
|
|
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
KnobID id() const { return _id; }
|
2018-09-21 10:06:16 -04:00
|
|
|
LEDColor color_enabled() const { return _color_enabled; }
|
|
|
|
LEDColor color_disabled() const { return _color_disabled; }
|
2024-10-18 19:51:44 -04:00
|
|
|
std::function<uint8_t ()> check_method;
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
MidiByteArray state_msg(bool light = true) const;
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
private:
|
|
|
|
KnobID _id;
|
2018-09-21 10:06:16 -04:00
|
|
|
LEDColor _color_enabled;
|
|
|
|
LEDColor _color_disabled;
|
2018-08-07 09:30:26 -04:00
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
public:
|
2018-08-07 09:30:26 -04:00
|
|
|
LaunchControlXL(ARDOUR::Session &);
|
|
|
|
~LaunchControlXL();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
std::list<std::shared_ptr<ARDOUR::Bundle> > bundles();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
bool has_editor() const { return true; }
|
|
|
|
void *get_gui() const;
|
|
|
|
void tear_down_gui();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-24 07:29:01 -04:00
|
|
|
int get_amount_of_tracks();
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
int set_active(bool yn);
|
2022-04-06 23:56:32 -04:00
|
|
|
XMLNode& get_state() const;
|
2018-08-07 09:30:26 -04:00
|
|
|
int set_state(const XMLNode &node, int version);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2024-10-18 12:01:28 -04:00
|
|
|
PBD::Signal<void()> ConnectionChange;
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Port> input_port();
|
|
|
|
std::shared_ptr<ARDOUR::Port> output_port();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
Button *button_by_id(ButtonID);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
static std::string button_name_by_id(ButtonID);
|
|
|
|
static std::string knob_name_by_id(KnobID);
|
|
|
|
static std::string fader_name_by_id(FaderID);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void write(const MidiByteArray &);
|
2018-08-09 14:10:40 -04:00
|
|
|
void reset(uint8_t chan);
|
2018-08-24 10:53:06 -04:00
|
|
|
|
2018-08-18 15:52:43 -04:00
|
|
|
void set_fader8master (bool yn);
|
2018-08-24 10:53:06 -04:00
|
|
|
bool fader8master () const { return _fader8master; }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-24 07:29:01 -04:00
|
|
|
void set_refresh_leds_flag (bool yn);
|
|
|
|
bool refresh_leds_flag () const { return _refresh_leds_flag; }
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
void set_device_mode (bool yn);
|
|
|
|
bool device_mode () const { return _device_mode; }
|
|
|
|
|
2024-01-08 09:19:39 -05:00
|
|
|
#ifdef MIXBUS
|
2020-02-13 09:35:16 -05:00
|
|
|
void set_ctrllowersends (bool yn);
|
|
|
|
bool ctrllowersends () const { return _ctrllowersends; }
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
void store_fss_type();
|
|
|
|
bool fss_is_mixbus() const { return _fss_is_mixbus; }
|
|
|
|
#endif
|
2018-08-07 09:30:26 -04:00
|
|
|
TrackMode track_mode() const { return _track_mode; }
|
|
|
|
void set_track_mode(TrackMode mode);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
uint8_t template_number() const { return _template_number; }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
void set_send_bank (int offset);
|
|
|
|
void send_bank_switch(bool up);
|
|
|
|
int send_bank_base () const { return _send_bank_base; }
|
|
|
|
|
2022-05-16 17:24:27 -04:00
|
|
|
CONTROL_PROTOCOL_THREADS_NEED_TEMPO_MAP_DECL();
|
|
|
|
|
2018-08-06 21:41:12 -04:00
|
|
|
private:
|
2018-08-07 09:30:26 -04:00
|
|
|
bool in_use;
|
|
|
|
TrackMode _track_mode;
|
|
|
|
uint8_t _template_number;
|
|
|
|
|
2018-08-24 10:53:06 -04:00
|
|
|
bool _fader8master;
|
2018-09-21 10:06:16 -04:00
|
|
|
bool _device_mode;
|
2024-01-08 09:19:39 -05:00
|
|
|
#ifdef MIXBUS
|
2020-02-13 09:35:16 -05:00
|
|
|
bool _ctrllowersends;
|
2018-09-21 10:06:16 -04:00
|
|
|
bool _fss_is_mixbus;
|
|
|
|
#endif
|
2018-08-24 07:29:01 -04:00
|
|
|
bool _refresh_leds_flag;
|
2018-08-24 10:53:06 -04:00
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
int _send_bank_base;
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void do_request(LaunchControlRequest *);
|
|
|
|
|
|
|
|
int begin_using_device();
|
|
|
|
int stop_using_device();
|
|
|
|
int ports_acquire();
|
|
|
|
void ports_release();
|
|
|
|
void run_event_loop();
|
|
|
|
void stop_event_loop();
|
|
|
|
|
|
|
|
void relax() {}
|
|
|
|
|
|
|
|
/* map of NoteButtons by NoteNumber */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<int, std::shared_ptr<NoteButton> > NNNoteButtonMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
NNNoteButtonMap nn_note_button_map;
|
|
|
|
/* map of NoteButtons by ButtonID */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<ButtonID, std::shared_ptr<NoteButton> > IDNoteButtonMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
IDNoteButtonMap id_note_button_map;
|
|
|
|
/* map of ControllerNoteButtons by CC */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<int, std::shared_ptr<ControllerButton> > CCControllerButtonMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
CCControllerButtonMap cc_controller_button_map;
|
|
|
|
/* map of ControllerButtons by ButtonID */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<ButtonID, std::shared_ptr<ControllerButton> > IDControllerButtonMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
IDControllerButtonMap id_controller_button_map;
|
|
|
|
|
|
|
|
|
|
|
|
/* map of Fader by CC */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<int, std::shared_ptr<Fader> > CCFaderMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
CCFaderMap cc_fader_map;
|
|
|
|
/* map of Fader by FaderID */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<FaderID, std::shared_ptr<Fader> > IDFaderMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
IDFaderMap id_fader_map;
|
|
|
|
|
|
|
|
/* map of Knob by CC */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<int, std::shared_ptr<Knob> > CCKnobMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
CCKnobMap cc_knob_map;
|
|
|
|
/* map of Knob by KnobID */
|
2023-02-16 18:33:28 -05:00
|
|
|
typedef std::map<KnobID, std::shared_ptr<Knob> > IDKnobMap;
|
2018-08-07 09:30:26 -04:00
|
|
|
IDKnobMap id_knob_map;
|
|
|
|
|
|
|
|
std::set<ButtonID> buttons_down;
|
|
|
|
std::set<ButtonID> consumed;
|
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
bool button_long_press_timeout(ButtonID id, std::shared_ptr<Button> button);
|
|
|
|
void start_press_timeout(std::shared_ptr<Button> , ButtonID);
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
void init_buttons();
|
2018-08-07 09:30:26 -04:00
|
|
|
void init_buttons(bool startup);
|
2018-09-21 10:06:16 -04:00
|
|
|
void init_buttons (ButtonID buttons[], uint8_t i);
|
|
|
|
void init_knobs();
|
|
|
|
void init_knobs(KnobID knobs[], uint8_t i);
|
|
|
|
void init_knobs_and_buttons();
|
|
|
|
|
|
|
|
void init_device_mode();
|
|
|
|
void init_dm_callbacks();
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
void switch_template(uint8_t t);
|
2018-09-21 10:06:16 -04:00
|
|
|
void filter_stripables (ARDOUR::StripableList& strips) const;
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
void build_maps();
|
|
|
|
|
|
|
|
// Bundle to represent our input ports
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Bundle> _input_bundle;
|
2018-08-07 09:30:26 -04:00
|
|
|
// Bundle to represent our output ports
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Bundle> _output_bundle;
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
MIDI::Port *_input_port;
|
|
|
|
MIDI::Port *_output_port;
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Port> _async_in;
|
|
|
|
std::shared_ptr<ARDOUR::Port> _async_out;
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
void connect_to_parser();
|
2023-02-16 18:33:28 -05:00
|
|
|
void handle_button_message(std::shared_ptr<Button> button, MIDI::EventTwoBytes *);
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
bool check_pick_up(std::shared_ptr<Controller> controller, std::shared_ptr<ARDOUR::AutomationControl> ac, bool rotary = false);
|
2018-08-10 12:44:10 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void handle_midi_controller_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
|
|
|
|
void handle_midi_note_on_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
|
|
|
|
void handle_midi_note_off_message(MIDI::Parser &, MIDI::EventTwoBytes *, MIDI::channel_t chan);
|
|
|
|
void handle_midi_sysex(MIDI::Parser &, MIDI::byte *, size_t count);
|
|
|
|
|
|
|
|
bool midi_input_handler(Glib::IOCondition ioc, MIDI::Port *port);
|
|
|
|
|
|
|
|
void thread_init();
|
|
|
|
|
|
|
|
PBD::ScopedConnectionList session_connections;
|
|
|
|
void connect_session_signals();
|
|
|
|
void notify_transport_state_changed();
|
|
|
|
void notify_loop_state_changed();
|
|
|
|
void notify_parameter_changed(std::string);
|
|
|
|
|
2018-08-13 20:59:58 -04:00
|
|
|
/* Knob methods */
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<Knob> knob_by_id(KnobID id);
|
|
|
|
std::shared_ptr<Knob>* knobs_by_column(uint8_t col, std::shared_ptr<Knob>* knob_col);
|
2018-09-21 10:06:16 -04:00
|
|
|
void update_knob_led_by_strip(uint8_t n);
|
|
|
|
void update_knob_led_by_id(uint8_t id, LEDColor color);
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2018-09-08 13:03:45 -04:00
|
|
|
void knob_sendA(uint8_t n);
|
|
|
|
void knob_sendB(uint8_t n);
|
|
|
|
void knob_pan(uint8_t n);
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
uint8_t dm_check_dummy(DeviceStatus ds);
|
|
|
|
|
|
|
|
void dm_fader(FaderID id);
|
|
|
|
uint8_t dm_check_pan_azi ();
|
|
|
|
void dm_pan_azi(KnobID k);
|
|
|
|
uint8_t dm_check_pan_width();
|
|
|
|
void dm_pan_width (KnobID k);
|
|
|
|
uint8_t dm_check_trim ();
|
|
|
|
void dm_trim(KnobID k);
|
|
|
|
uint8_t dm_mute_enabled();
|
|
|
|
void dm_mute_switch();
|
|
|
|
uint8_t dm_solo_enabled();
|
|
|
|
void dm_solo_switch();
|
|
|
|
uint8_t dm_recenable_enabled();
|
|
|
|
void dm_recenable_switch();
|
|
|
|
void dm_select_prev_strip();
|
|
|
|
void dm_select_next_strip();
|
2018-09-08 13:03:45 -04:00
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
#ifdef MIXBUS
|
|
|
|
void dm_mb_eq_switch();
|
|
|
|
void dm_mb_eq (KnobID k, bool gain, uint8_t band);
|
|
|
|
uint8_t dm_mb_eq_freq_enabled();
|
|
|
|
uint8_t dm_mb_eq_gain_enabled(uint8_t band);
|
|
|
|
void dm_mb_eq_shape_switch(uint8_t band);
|
|
|
|
uint8_t dm_mb_eq_shape_enabled(uint8_t band);
|
|
|
|
uint8_t dm_mb_flt_enabled();
|
|
|
|
void dm_mb_flt_frq (KnobID k, bool hpf);
|
|
|
|
void dm_mb_flt_switch();
|
|
|
|
void dm_mb_send_enabled(KnobID k);
|
|
|
|
uint8_t dm_mb_check_send_knob(KnobID k);
|
|
|
|
uint8_t dm_mb_check_send_button(uint8_t s);
|
|
|
|
void dm_mb_sends (KnobID k);
|
|
|
|
void dm_mb_send_switch (ButtonID b);
|
|
|
|
uint8_t dm_mb_comp_enabled();
|
|
|
|
void dm_mb_comp_switch();
|
|
|
|
void dm_mb_comp (KnobID k, CompParam c);
|
|
|
|
void dm_mb_comp_thresh (FaderID id);
|
|
|
|
uint8_t dm_mb_has_tapedrive();
|
|
|
|
void dm_mb_tapedrive (KnobID k);
|
|
|
|
uint8_t dm_mb_master_assign_enabled();
|
|
|
|
void dm_mb_master_assign_switch();
|
|
|
|
#endif
|
2018-09-08 13:03:45 -04:00
|
|
|
|
|
|
|
/* Fader methods */
|
|
|
|
void fader(uint8_t n);
|
|
|
|
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
/* Button methods */
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<TrackButton> track_button_by_range(uint8_t n, uint8_t first, uint8_t middle);
|
|
|
|
std::shared_ptr<TrackButton> focus_button_by_column(uint8_t col) { return track_button_by_range(col, 41, 57) ; }
|
|
|
|
std::shared_ptr<TrackButton> control_button_by_column(uint8_t col) { return track_button_by_range(col, 73, 89) ; }
|
2018-08-07 09:30:26 -04:00
|
|
|
|
|
|
|
|
|
|
|
void button_device();
|
|
|
|
void button_device_long_press();
|
|
|
|
void button_track_mode(TrackMode state);
|
2018-08-12 14:27:18 -04:00
|
|
|
void button_mute();
|
2018-09-21 10:06:16 -04:00
|
|
|
void button_mute_long_press();
|
2018-08-12 14:27:18 -04:00
|
|
|
void button_solo();
|
2018-09-21 10:06:16 -04:00
|
|
|
void button_solo_long_press();
|
2018-08-12 14:27:18 -04:00
|
|
|
void button_record();
|
2018-08-07 09:30:26 -04:00
|
|
|
void button_select_up();
|
|
|
|
void button_select_down();
|
|
|
|
void button_select_left();
|
|
|
|
void button_select_right();
|
|
|
|
|
|
|
|
void button_track_focus(uint8_t n);
|
2018-09-21 10:06:16 -04:00
|
|
|
void button_press_track_control(uint8_t n);
|
|
|
|
void button_release_track_control(uint8_t n);
|
2018-08-07 09:30:26 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::AutomationControl> get_ac_by_state(uint8_t n);
|
2018-08-15 16:19:13 -04:00
|
|
|
void update_track_focus_led(uint8_t n);
|
2018-08-07 09:30:26 -04:00
|
|
|
void update_track_control_led(uint8_t n);
|
|
|
|
|
2018-09-21 10:06:16 -04:00
|
|
|
void send_bank_switch_0() { send_bank_switch(0); }
|
|
|
|
void send_bank_switch_1() { send_bank_switch(1); }
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
/* stripables */
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
int32_t bank_start;
|
|
|
|
PBD::ScopedConnectionList stripable_connections;
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Stripable> stripable[8];
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
void stripables_added ();
|
|
|
|
|
|
|
|
void stripable_property_change (PBD::PropertyChange const& what_changed, uint32_t which);
|
|
|
|
|
|
|
|
void switch_bank (uint32_t base);
|
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void solo_changed (uint32_t n) { solo_mute_rec_changed(n); }
|
|
|
|
void mute_changed (uint32_t n) { solo_mute_rec_changed(n); }
|
2018-09-21 10:06:16 -04:00
|
|
|
void rec_changed (uint32_t n) { solo_mute_rec_changed(n); }
|
2018-08-24 07:29:01 -04:00
|
|
|
void solo_iso_changed (uint32_t n);
|
|
|
|
void solo_iso_led_bank ();
|
|
|
|
#ifdef MIXBUS
|
|
|
|
void master_send_changed (uint32_t n);
|
|
|
|
void master_send_led_bank ();
|
|
|
|
#endif
|
2018-09-21 10:06:16 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void solo_mute_rec_changed (uint32_t n);
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
/* special Stripable */
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::Stripable> master;
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void port_registration_handler();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
enum ConnectionState { InputConnected = 0x1, OutputConnected = 0x2 };
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
int connection_state;
|
2023-02-16 18:33:28 -05:00
|
|
|
bool connection_handler(std::weak_ptr<ARDOUR::Port>, std::string name1,
|
|
|
|
std::weak_ptr<ARDOUR::Port>, std::string name2,
|
2018-08-07 09:30:26 -04:00
|
|
|
bool yn);
|
2021-02-04 00:19:37 -05:00
|
|
|
PBD::ScopedConnection port_connection;
|
2018-08-07 09:30:26 -04:00
|
|
|
void connected();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
/* GUI */
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
mutable LCXLGUI *gui;
|
|
|
|
void build_gui();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
void stripable_selection_changed();
|
2018-08-06 21:41:12 -04:00
|
|
|
|
2018-08-07 09:30:26 -04:00
|
|
|
bool in_range_select;
|
2018-08-24 10:53:06 -04:00
|
|
|
};
|
2018-08-06 21:41:12 -04:00
|
|
|
|
|
|
|
|
|
|
|
} // namespace ArdourSurface
|
|
|
|
|
|
|
|
#endif /* __ardour_launch_control_h__ */
|