skeleton for launchpad pro support

This commit is contained in:
Paul Davis 2023-07-03 10:47:40 -06:00
parent 6c44dbf9d6
commit 3fa15d9162
10 changed files with 908 additions and 2 deletions

View File

@ -19,7 +19,7 @@ export GTK2_RC_FILES=/nonexistent
# can find all the components.
#
export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/faderport8:$libs/surfaces/faderport:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie:$libs/surfaces/us2400:$libs/surfaces/wiimote:$libs/surfaces/push2:$libs/surfaces/maschine2:$libs/surfaces/cc121:$libs/surfaces/launch_control_xl:$libs/surfaces/contourdesign:$libs/surfaces/websockets:$libs/surfaces/console1
export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/faderport8:$libs/surfaces/faderport:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie:$libs/surfaces/us2400:$libs/surfaces/wiimote:$libs/surfaces/push2:$libs/surfaces/maschine2:$libs/surfaces/cc121:$libs/surfaces/launch_control_xl:$libs/surfaces/contourdesign:$libs/surfaces/websockets:$libs/surfaces/console1:$libs/surfaces/launchpad_pro
export ARDOUR_PANNER_PATH=$libs/panners
export ARDOUR_DATA_PATH=$TOP/share:$TOP/build:$TOP/gtk2_ardour:$TOP/build/gtk2_ardour
export ARDOUR_MIDIMAPS_PATH=$TOP/share/midi_maps

View File

@ -88,6 +88,7 @@ namespace PBD {
LIBARDOUR_API extern DebugBits ProcessThreads;
LIBARDOUR_API extern DebugBits Processors;
LIBARDOUR_API extern DebugBits Push2;
LIBARDOUR_API extern DebugBits Launchpad;
LIBARDOUR_API extern DebugBits MIDISurface;
LIBARDOUR_API extern DebugBits Selection;
LIBARDOUR_API extern DebugBits SessionEvents;

View File

@ -83,6 +83,7 @@ PBD::DebugBits PBD::DEBUG::Ports = PBD::new_debug_bit ("Ports");
PBD::DebugBits PBD::DEBUG::ProcessThreads = PBD::new_debug_bit ("processthreads");
PBD::DebugBits PBD::DEBUG::Processors = PBD::new_debug_bit ("processors");
PBD::DebugBits PBD::DEBUG::Push2 = PBD::new_debug_bit ("push2");
PBD::DebugBits PBD::DEBUG::Launchpad = PBD::new_debug_bit ("launchpad");
PBD::DebugBits PBD::DEBUG::MIDISurface = PBD::new_debug_bit ("midisurface");
PBD::DebugBits PBD::DEBUG::Selection = PBD::new_debug_bit ("selection");
PBD::DebugBits PBD::DEBUG::SessionEvents = PBD::new_debug_bit ("sessionevents");

View File

@ -0,0 +1,272 @@
/*
* Copyright (C) 2016 Paul Davis <paul@linuxaudiosystems.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.
*/
#include <gtkmm/alignment.h>
#include <gtkmm/label.h>
#include <gtkmm/liststore.h>
#include "pbd/unwind.h"
#include "pbd/strsplit.h"
#include "pbd/file_utils.h"
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/gui_thread.h"
#include "gtkmm2ext/utils.h"
#include "ardour/audioengine.h"
#include "ardour/filesystem_paths.h"
#include "ardour/parameter_descriptor.h"
#include "lppro.h"
#include "gui.h"
#include "pbd/i18n.h"
using namespace PBD;
using namespace ARDOUR;
using namespace ArdourSurface;
using namespace Gtk;
using namespace Gtkmm2ext;
void*
LaunchPadPro::get_gui () const
{
if (!_gui) {
const_cast<LaunchPadPro*>(this)->build_gui ();
}
static_cast<Gtk::VBox*>(_gui)->show_all();
return _gui;
}
void
LaunchPadPro::tear_down_gui ()
{
if (_gui) {
Gtk::Widget *w = static_cast<Gtk::VBox*>(_gui)->get_parent();
if (w) {
w->hide();
delete w;
}
}
delete _gui;
_gui = 0;
}
void
LaunchPadPro::build_gui ()
{
_gui = new LPPRO_GUI (*this);
}
/*--------------------*/
LPPRO_GUI::LPPRO_GUI (LaunchPadPro& p)
: _lp (p)
, _table (2, 5)
, _action_table (5, 4)
, _ignore_active_change (false)
{
set_border_width (12);
_table.set_row_spacings (4);
_table.set_col_spacings (6);
_table.set_border_width (12);
_table.set_homogeneous (false);
std::string data_file_path;
std::string name = "push2-small.png";
Searchpath spath(ARDOUR::ardour_data_search_path());
spath.add_subdirectory_to_paths ("icons");
find_file (spath, name, data_file_path);
if (!data_file_path.empty()) {
_image.set (data_file_path);
_hpacker.pack_start (_image, false, false);
}
Gtk::Label* l;
int row = 0;
_input_combo.pack_start (_midi_port_columns.short_name);
_output_combo.pack_start (_midi_port_columns.short_name);
_input_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &LPPRO_GUI::active_port_changed), &_input_combo, true));
_output_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &LPPRO_GUI::active_port_changed), &_output_combo, false));
l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Incoming MIDI on:")));
l->set_alignment (1.0, 0.5);
_table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
_table.attach (_input_combo, 1, 2, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
row++;
l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Outgoing MIDI on:")));
l->set_alignment (1.0, 0.5);
_table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
_table.attach (_output_combo, 1, 2, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
row++;
_hpacker.pack_start (_table, true, true);
set_spacing (12);
pack_start (_hpacker, false, false);
/* update the port connection combos */
update_port_combos ();
/* catch future changes to connection state */
ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&LPPRO_GUI::connection_handler, this), gui_context());
ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&LPPRO_GUI::connection_handler, this), gui_context());
_lp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&LPPRO_GUI::connection_handler, this), gui_context());
}
LPPRO_GUI::~LPPRO_GUI ()
{
}
void
LPPRO_GUI::connection_handler ()
{
/* ignore all changes to combobox active strings here, because we're
updating them to match a new ("external") reality - we were called
because port connections have changed.
*/
PBD::Unwinder<bool> ici (_ignore_active_change, true);
update_port_combos ();
}
void
LPPRO_GUI::update_port_combos ()
{
std::vector<std::string> midi_inputs;
std::vector<std::string> midi_outputs;
if (!_lp.input_port() || !_lp.output_port()) {
return;
}
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsTerminal), midi_inputs);
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsTerminal), midi_outputs);
Glib::RefPtr<Gtk::ListStore> input = build_midi_port_list (midi_inputs, true);
Glib::RefPtr<Gtk::ListStore> output = build_midi_port_list (midi_outputs, false);
bool input_found = false;
bool output_found = false;
int n;
_input_combo.set_model (input);
_output_combo.set_model (output);
Gtk::TreeModel::Children children = input->children();
Gtk::TreeModel::Children::iterator i;
i = children.begin();
++i; /* skip "Disconnected" */
for (n = 1; i != children.end(); ++i, ++n) {
std::string port_name = (*i)[_midi_port_columns.full_name];
if (_lp.input_port()->connected_to (port_name)) {
_input_combo.set_active (n);
input_found = true;
break;
}
}
if (!input_found) {
_input_combo.set_active (0); /* disconnected */
}
children = output->children();
i = children.begin();
++i; /* skip "Disconnected" */
for (n = 1; i != children.end(); ++i, ++n) {
std::string port_name = (*i)[_midi_port_columns.full_name];
if (_lp.output_port()->connected_to (port_name)) {
_output_combo.set_active (n);
output_found = true;
break;
}
}
if (!output_found) {
_output_combo.set_active (0); /* disconnected */
}
}
Glib::RefPtr<Gtk::ListStore>
LPPRO_GUI::build_midi_port_list (std::vector<std::string> const & ports, bool for_input)
{
Glib::RefPtr<Gtk::ListStore> store = ListStore::create (_midi_port_columns);
TreeModel::Row row;
row = *store->append ();
row[_midi_port_columns.full_name] = std::string();
row[_midi_port_columns.short_name] = _("Disconnected");
for (std::vector<std::string>::const_iterator p = ports.begin(); p != ports.end(); ++p) {
row = *store->append ();
row[_midi_port_columns.full_name] = *p;
std::string pn = ARDOUR::AudioEngine::instance()->get_pretty_name_by_name (*p);
if (pn.empty ()) {
pn = (*p).substr ((*p).find (':') + 1);
}
row[_midi_port_columns.short_name] = pn;
}
return store;
}
void
LPPRO_GUI::active_port_changed (Gtk::ComboBox* combo, bool for_input)
{
if (_ignore_active_change) {
return;
}
TreeModel::iterator active = combo->get_active ();
std::string new_port = (*active)[_midi_port_columns.full_name];
if (new_port.empty()) {
if (for_input) {
_lp.input_port()->disconnect_all ();
} else {
_lp.output_port()->disconnect_all ();
}
return;
}
if (for_input) {
if (!_lp.input_port()->connected_to (new_port)) {
_lp.input_port()->disconnect_all ();
_lp.input_port()->connect (new_port);
}
} else {
if (!_lp.output_port()->connected_to (new_port)) {
_lp.output_port()->disconnect_all ();
_lp.output_port()->connect (new_port);
}
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2016 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __ardour_lppro_gui_h__
#define __ardour_lppro_gui_h__
#include <vector>
#include <string>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/combobox.h>
#include <gtkmm/image.h>
#include <gtkmm/table.h>
#include <gtkmm/treestore.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/notebook.h>
namespace Gtk {
class ListStore;
}
#include "ardour/mode.h"
#include "lppro.h"
namespace ArdourSurface {
class LPPRO_GUI : public Gtk::VBox
{
public:
LPPRO_GUI (LaunchPadPro&);
~LPPRO_GUI ();
private:
LaunchPadPro& _lp;
Gtk::HBox _hpacker;
Gtk::Table _table;
Gtk::Table _action_table;
Gtk::ComboBox _input_combo;
Gtk::ComboBox _output_combo;
Gtk::Image _image;
void update_port_combos ();
void connection_handler ();
PBD::ScopedConnectionList _port_connections;
struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
MidiPortColumns() {
add (short_name);
add (full_name);
}
Gtk::TreeModelColumn<std::string> short_name;
Gtk::TreeModelColumn<std::string> full_name;
};
MidiPortColumns _midi_port_columns;
bool _ignore_active_change;
Glib::RefPtr<Gtk::ListStore> build_midi_port_list (std::vector<std::string> const & ports, bool for_input);
void active_port_changed (Gtk::ComboBox*,bool for_input);
#if 0
struct PressureModeColumns : public Gtk::TreeModel::ColumnRecord {
PressureModeColumns() {
add (mode);
add (name);
}
Gtk::TreeModelColumn<Push2::PressureMode> mode;
Gtk::TreeModelColumn<std::string> name;
};
PressureModeColumns _pressure_mode_columns;
Glib::RefPtr<Gtk::ListStore> build_pressure_mode_columns ();
Gtk::ComboBox _pressure_mode_selector;
Gtk::Label _pressure_mode_label;
void reprogram_pressure_mode ();
#endif
};
}
#endif /* __ardour_lppro_gui_h__ */

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2016 Paul Davis <paul@linuxaudiosystems.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.
*/
#include <stdexcept>
#include "pbd/error.h"
#include "ardour/rc_configuration.h"
#include "control_protocol/control_protocol.h"
#include "lppro.h"
using namespace ARDOUR;
using namespace PBD;
using namespace ArdourSurface;
static ControlProtocol*
new_lppro (Session* s)
{
LaunchPadPro * p2 = 0;
try {
p2 = new LaunchPadPro (*s);
/* do not set active here - wait for set_state() */
}
catch (std::exception & e) {
error << "Error instantiating LaunchPad Pro support: " << e.what() << endmsg;
delete p2;
p2 = 0;
}
return p2;
}
static void
delete_lppro (ControlProtocol* cp)
{
try
{
delete cp;
}
catch ( std::exception & e )
{
std::cout << "Exception caught trying to finalize LaunchPad Pro support: " << e.what() << std::endl;
}
}
static bool
probe_lppro_midi_protocol ()
{
std::string i, o;
return LaunchPadPro::probe (i, o);
}
static ControlProtocolDescriptor lppro_descriptor = {
/* name */ "Novation LaunchPad Pro",
/* id */ "uri://ardour.org/surfaces/lppro:0",
/* module */ 0,
/* available */ LaunchPadPro::available,
/* probe_port */ probe_lppro_midi_protocol,
/* match usb */ 0, // LaunchPadPro::match_usb,
/* initialize */ new_lppro,
/* destroy */ delete_lppro,
};
extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &lppro_descriptor; }

View File

@ -0,0 +1,280 @@
/*
* Copyright (C) 2016-2018 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2017-2018 Robin Gareus <robin@gareus.org>
*
* 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.
*/
#include <algorithm>
#include <bitset>
#include <stdlib.h>
#include <pthread.h>
#include "pbd/compose.h"
#include "pbd/convert.h"
#include "pbd/debug.h"
#include "pbd/failed_constructor.h"
#include "pbd/file_utils.h"
#include "pbd/search_path.h"
#include "pbd/enumwriter.h"
#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"
#include "ardour/debug.h"
#include "ardour/midiport_manager.h"
#include "ardour/midi_track.h"
#include "ardour/midi_port.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour/types_convert.h"
#include "gtkmm2ext/gui_thread.h"
#include "gtkmm2ext/rgb_macros.h"
#include "gtkmm2ext/colors.h"
#include "gui.h"
#include "lppro.h"
#include "pbd/i18n.h"
#ifdef PLATFORM_WINDOWS
#define random() rand()
#endif
using namespace ARDOUR;
using namespace PBD;
using namespace Glib;
using namespace ArdourSurface;
using namespace Gtkmm2ext;
#include "pbd/abstract_ui.cc" // instantiate template
#define NOVATION 0x1235
#define LAUNCHPADPROMK3 0x0123
bool
LaunchPadPro::available ()
{
bool rv = LIBUSB_SUCCESS == libusb_init (0);
if (rv) {
libusb_exit (0);
}
return rv;
}
bool
LaunchPadPro::match_usb (uint16_t vendor, uint16_t device)
{
return vendor == NOVATION && device == LAUNCHPADPROMK3;
}
bool
LaunchPadPro::probe (std::string& i, std::string& o)
{
vector<string> midi_inputs;
vector<string> midi_outputs;
AudioEngine::instance()->get_ports ("", DataType::MIDI, PortFlags (IsOutput|IsTerminal), midi_inputs);
AudioEngine::instance()->get_ports ("", DataType::MIDI, PortFlags (IsInput|IsTerminal), midi_outputs);
auto has_lppro = [](string const& s) {
std::string pn = AudioEngine::instance()->get_hardware_port_name_by_name (s);
return pn.find ("Launchpad Pro MK3 MIDI 1") != string::npos;
};
auto pi = std::find_if (midi_inputs.begin (), midi_inputs.end (), has_lppro);
auto po = std::find_if (midi_outputs.begin (), midi_outputs.end (), has_lppro);
if (pi == midi_inputs.end () || po == midi_outputs.end ()) {
return false;
}
i = *pi;
o = *po;
return true;
}
LaunchPadPro::LaunchPadPro (ARDOUR::Session& s)
: MIDISurface (s, X_("Novation Launchpad Pro"), X_("Launchpad Pro"), true)
{
run_event_loop ();
port_setup ();
std::string pn_in, pn_out;
if (probe (pn_in, pn_out)) {
_async_in->connect (pn_in);
_async_out->connect (pn_out);
}
}
LaunchPadPro::~LaunchPadPro ()
{
DEBUG_TRACE (DEBUG::Launchpad, "push2 control surface object being destroyed\n");
stop_event_loop ();
MIDISurface::drop ();
}
int
LaunchPadPro::set_active (bool yn)
{
DEBUG_TRACE (DEBUG::Launchpad, string_compose("Launchpad Pro::set_active init with yn: '%1'\n", yn));
if (yn == active()) {
return 0;
}
if (yn) {
if (device_acquire ()) {
return -1;
}
if ((_connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
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.
*/
}
ControlProtocol::set_active (yn);
DEBUG_TRACE (DEBUG::Launchpad, string_compose("Launchpad Pro::set_active done with yn: '%1'\n", yn));
return 0;
}
void
LaunchPadPro::run_event_loop ()
{
DEBUG_TRACE (DEBUG::Launchpad, "start event loop\n");
BaseUI::run ();
}
void
LaunchPadPro::stop_event_loop ()
{
DEBUG_TRACE (DEBUG::Launchpad, "stop event loop\n");
BaseUI::quit ();
}
int
LaunchPadPro::begin_using_device ()
{
DEBUG_TRACE (DEBUG::Launchpad, "begin using device\n");
#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 ();
request_pressure_mode ();
#endif
return MIDISurface::begin_using_device ();
}
int
LaunchPadPro::stop_using_device ()
{
DEBUG_TRACE (DEBUG::Launchpad, "stop using device\n");
if (!_in_use) {
DEBUG_TRACE (DEBUG::Launchpad, "nothing to do, device not in use\n");
return 0;
}
#if 0
init_buttons (false);
strip_buttons_off ();
for (auto & pad : _xy_pad_map) {
pad->set_color (LED::Black);
pad->set_state (LED::NoTransition);
write (pad->state_msg());
}
#endif
return MIDISurface::stop_using_device ();
}
XMLNode&
LaunchPadPro::get_state() const
{
XMLNode& node (MIDISurface::get_state());
return node;
}
int
LaunchPadPro::set_state (const XMLNode & node, int version)
{
DEBUG_TRACE (DEBUG::Launchpad, string_compose ("LaunchPadPro::set_state: active %1\n", active()));
int retval = 0;
if (MIDISurface::set_state (node, version)) {
return -1;
}
return retval;
}
std::string
LaunchPadPro::input_port_name () const
{
#ifdef __APPLE__
/* the origin of the numeric magic identifiers is known only to Novation
and may change in time. This is part of how CoreMIDI works.
*/
return X_("system:midi_capture_1319078870");
#else
return X_("Launchpad Pro MK3 MIDI 1 in");
#endif
}
std::string
LaunchPadPro::output_port_name () const
{
#ifdef __APPLE__
/* the origin of the numeric magic identifiers is known only to Novation
and may change in time. This is part of how CoreMIDI works.
*/
return X_("system:midi_playback_3409210341");
#else
return X_("Launchpad Pro MK3 MIDI 1 out");
#endif
}
void
LaunchPadPro::stripable_selection_changed ()
{
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2016-2018 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __ardour_lppro_h__
#define __ardour_lppro_h__
#include <vector>
#include <map>
#include <stack>
#include <list>
#include <set>
#include <libusb.h>
#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 "gtkmm2ext/colors.h"
#include "midi_surface/midi_byte_array.h"
#include "midi_surface/midi_surface.h"
namespace MIDI {
class Parser;
class Port;
}
namespace ARDOUR {
class Port;
class MidiBuffer;
class MidiTrack;
}
namespace ArdourSurface {
class LPPRO_GUI;
class LaunchPadPro : public MIDISurface
{
public:
enum ButtonID {
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
};
LaunchPadPro (ARDOUR::Session&);
~LaunchPadPro ();
static bool available ();
static bool match_usb (uint16_t, uint16_t);
static bool probe (std::string&, std::string&);
std::string input_port_name () const;
std::string output_port_name () const;
bool has_editor () const { return true; }
void* get_gui () const;
void tear_down_gui ();
int set_active (bool yn);
XMLNode& get_state() const;
int set_state (const XMLNode & node, int version);
private:
int begin_using_device ();
int stop_using_device ();
int device_acquire () { return 0; }
void device_release () { }
void run_event_loop ();
void stop_event_loop ();
void stripable_selection_changed ();
mutable LPPRO_GUI* _gui;
void build_gui ();
};
} /* namespace */
#endif /* __ardour_lppro_h__ */

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
from waflib.extras import autowaf as autowaf
import os
# Mandatory variables
top = '.'
out = 'build'
def options(opt):
autowaf.set_options(opt)
def configure(conf):
autowaf.check_pkg(conf, 'pangomm-1.4', uselib_store='PANGOMM', atleast_version='1.4', mandatory=True)
autowaf.check_pkg(conf, 'cairomm-1.0', uselib_store='CAIROMM', atleast_version='1.8.4', mandatory=True)
def build(bld):
obj = bld(features = 'cxx cxxshlib')
obj.source = '''
lppro.cc
interface.cc
gui.cc
'''
obj.defines = [ 'PACKAGE="ardour_launchpad_pro"' ]
obj.defines += [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.defines += [ 'VERSIONSTRING="' + bld.env['VERSION'] + '"' ]
obj.includes = ['.', '..', './launchpad_pro']
obj.name = 'libardour_launchpad_pro'
obj.target = 'ardour_launchpad_pro'
obj.uselib = 'CAIROMM PANGOMM USB GTKMM SIGCPP XML OSX'
obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libcanvas libtemporal'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
def shutdown():
autowaf.shutdown()

View File

@ -28,7 +28,8 @@ children = [
'us2400',
'launch_control_xl',
'osc',
'console1'
'console1',
'launchpad_pro'
]
def options(opt):
@ -89,6 +90,7 @@ def build(bld):
bld.recurse('launch_control_xl')
bld.recurse('osc')
bld.recurse('console1')
bld.recurse('launchpad_pro')
if bld.is_defined('BUILD_WIIMOTE'):
bld.recurse('wiimote')