Add support for PreSonus Faderport2 (2018 model)

This is a cleaned-up, foward-ported version of Ben's
Mixbus patch (d6694c5b31).
This commit is contained in:
Ben Loftis 2018-07-31 14:46:20 +02:00 committed by Robin Gareus
parent 506a42daf3
commit 948834bb1e
14 changed files with 314 additions and 24 deletions

View File

@ -578,6 +578,8 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
reserved_io_names[_("Mackie")] = false;
reserved_io_names[_("FaderPort Recv")] = false;
reserved_io_names[_("FaderPort Send")] = false;
reserved_io_names[_("FaderPort2 Recv")] = false;
reserved_io_names[_("FaderPort2 Send")] = false;
reserved_io_names[_("FaderPort8 Recv")] = false;
reserved_io_names[_("FaderPort8 Send")] = false;
reserved_io_names[_("FaderPort16 Recv")] = false;

View File

@ -950,6 +950,7 @@ PortManager::port_is_control_only (std::string const& name)
X_(".*FaderPort .*"),
X_(".*FaderPort8 .*"),
X_(".*FaderPort16 .*"),
X_(".*FaderPort2 .*"),
X_(".*US-2400 .*"),
X_(".*Mackie .*"),
};

View File

@ -23,6 +23,7 @@
#include "ardour/plugin_insert.h"
#include "ardour/session.h"
#include "ardour/session_configuration.h"
#include "ardour/track.h"
#include "ardour/types.h"
#include "gtkmm2ext/actions.h"
@ -39,6 +40,9 @@ using namespace ArdourSurface::FP_NAMESPACE::FP8Types;
#define BindMethod(ID, CB) \
_ctrls.button (FP8Controls::ID).released.connect_same_thread (button_connections, boost::bind (&FaderPort8:: CB, this));
#define BindMethod2(ID, ACT, CB) \
_ctrls.button (FP8Controls::ID). ACT .connect_same_thread (button_connections, boost::bind (&FaderPort8:: CB, this));
#define BindFunction(ID, ACT, CB, ...) \
_ctrls.button (FP8Controls::ID). ACT .connect_same_thread (button_connections, boost::bind (&FaderPort8:: CB, this, __VA_ARGS__));
@ -57,11 +61,11 @@ _ctrls.button (ID).released.connect_same_thread (button_connections, boost::bind
void
FaderPort8::setup_actions ()
{
BindMethod (BtnPlay, button_play);
BindMethod (BtnStop, button_stop);
BindMethod (BtnLoop, button_loop);
BindMethod (BtnRecord, button_record);
BindMethod (BtnClick, button_metronom);
BindMethod2 (BtnPlay, pressed, button_play);
BindMethod2 (BtnStop, pressed, button_stop);
BindMethod2 (BtnLoop, pressed, button_loop);
BindMethod2 (BtnRecord, pressed, button_record);
BindMethod2 (BtnClick, pressed, button_metronom);
BindAction (BtnRedo, "Editor", "redo");
BindAction (BtnSave, "Common", "Save");
@ -93,7 +97,11 @@ FaderPort8::setup_actions ()
BindFunction (BtnALatch, released, button_automation, ARDOUR::Latch);
_ctrls.button (FP8Controls::BtnEncoder).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_encoder, this));
#ifdef FADERPORT2
_ctrls.button (FP8Controls::BtnParam).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_encoder, this));
#else
_ctrls.button (FP8Controls::BtnParam).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_parameter, this));
#endif
BindMethod (BtnBypass, button_bypass);
@ -105,6 +113,9 @@ FaderPort8::setup_actions ()
BindMethod (BtnLink, button_link);
BindMethod (BtnLock, button_lock);
BindMethod (BtnChanLock, button_chanlock); //FP2 only
BindMethod (BtnFlip, button_flip); //FP2 only
// user-specific
for (FP8Controls::UserButtonMap::const_iterator i = _ctrls.user_buttons ().begin ();
i != _ctrls.user_buttons ().end (); ++i) {
@ -179,6 +190,20 @@ FaderPort8::button_open ()
AccessAction ("Common", "addExistingAudioFiles");
}
}
void
FaderPort8::button_chanlock ()
{
_chan_locked = !_chan_locked;
_ctrls.button (FP8Controls::BtnChannel).set_blinking (_chan_locked);
}
void
FaderPort8::button_flip ()
{
}
void
FaderPort8::button_lock ()
{
@ -218,7 +243,7 @@ FaderPort8::button_automation (ARDOUR::AutoState as)
switch (fadermode) {
case ModePlugins:
#if 0 // Plugin Control Automation Mode
for ( std::list <ProcessorCtrl>::iterator i = _proc_params.begin(); i != _proc_params.end(); ++i) {
for (std::list <ProcessorCtrl>::iterator i = _proc_params.begin(); i != _proc_params.end(); ++i) {
((*i).ac)->set_automation_state (as);
}
#endif
@ -450,11 +475,21 @@ FaderPort8::handle_encoder_link (int steps)
void
FaderPort8::button_arm (bool press)
{
#ifdef FADERPORT2
boost::shared_ptr<Stripable> s = first_selected_stripable();
if (press && s) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(s);
if (t) {
t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), PBD::Controllable::UseGroup);
}
}
#else
FaderMode fadermode = _ctrls.fader_mode ();
if (fadermode == ModeTrack || fadermode == ModePan) {
_ctrls.button (FP8Controls::BtnArm).set_active (press);
ARMButtonChange (press); /* EMIT SIGNAL */
}
#endif
}
void
@ -466,6 +501,7 @@ FaderPort8::button_prev_next (bool next)
break;
case NavMaster:
case NavScroll:
case NavPan:
bank (!next, false);
break;
case NavBank:
@ -533,6 +569,8 @@ FaderPort8::button_encoder ()
}
}
break;
case NavPan:
break;
case NavSection:
// TODO nudge
break;
@ -620,6 +658,9 @@ FaderPort8::encoder_navigate (bool neg, int steps)
AccessAction ("Common", "nudge-playhead-forward");
}
break;
case NavPan:
abort(); /*NOTREACHED*/
break;
}
}

View File

@ -63,13 +63,13 @@ FaderPort8::send_session_state ()
notify_mute_changed ();
notify_parameter_changed ("clicking");
notify_automation_mode_changed (); // XXX (stip specific, see below)
notify_route_state_changed (); // XXX (stip specific, see below)
}
// TODO: AutomationState display of plugin & send automation
// TODO: link/lock control AS.
void
FaderPort8::notify_automation_mode_changed ()
FaderPort8::notify_route_state_changed ()
{
boost::shared_ptr<Stripable> s = first_selected_stripable();
boost::shared_ptr<AutomationControl> ac;
@ -92,6 +92,9 @@ FaderPort8::notify_automation_mode_changed ()
_ctrls.button (FP8Controls::BtnATouch).set_active (false);
_ctrls.button (FP8Controls::BtnARead).set_active (false);
_ctrls.button (FP8Controls::BtnAWrite).set_active (false);
#ifdef FADERPORT2
_ctrls.button (FP8Controls::BtnArm).set_active (false);
#endif
return;
}
@ -101,6 +104,12 @@ FaderPort8::notify_automation_mode_changed ()
_ctrls.button (FP8Controls::BtnARead).set_active (as == Play);
_ctrls.button (FP8Controls::BtnAWrite).set_active (as == Write);
_ctrls.button (FP8Controls::BtnALatch).set_active (as == Latch);
#ifdef FADERPORT2
/* handle the Faderport's track-arm button */
ac = s->rec_enable_control ();
_ctrls.button (FP8Controls::BtnArm).set_active (ac ? ac->get_value() : false);
#endif
}
void

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2015 Paul Davis
*
* 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 <pbd/failed_constructor.h>
#include "control_protocol/control_protocol.h"
#include "faderport8.h"
using namespace ARDOUR;
using namespace ArdourSurface::FP_NAMESPACE;
static ControlProtocol*
new_faderport2_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s)
{
FaderPort8* fp;
try {
fp = new FaderPort8 (*s);
} catch (failed_constructor& err) {
return 0;
}
if (fp->set_active (true)) {
delete fp;
return 0;
}
return fp;
}
static void
delete_faderport2_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp)
{
delete cp;
}
static bool
probe_faderport2_midi_protocol (ControlProtocolDescriptor* /*descriptor*/)
{
return FaderPort8::probe ();
}
static void*
faderport2_request_buffer_factory (uint32_t num_requests)
{
return FaderPort8::request_factory (num_requests);
}
static ControlProtocolDescriptor faderport2_midi_descriptor = {
/*name : */ "PreSonus FaderPort2",
/*id : */ "uri://ardour.org/surfaces/faderport2:0",
/*ptr : */ 0,
/*module : */ 0,
/*mandatory : */ 0,
/*supports_feedback : */ true,
/*probe : */ probe_faderport2_midi_protocol,
/*initialize : */ new_faderport2_midi_protocol,
/*destroy : */ delete_faderport2_midi_protocol,
/*request_buffer_factory */ faderport2_request_buffer_factory
};
extern "C" ARDOURSURFACE_API
ControlProtocolDescriptor* protocol_descriptor () {
return &faderport2_midi_descriptor;
}

View File

@ -89,6 +89,8 @@ debug_2byte_msg (std::string const& msg, int b0, int b1)
FaderPort8::FaderPort8 (Session& s)
#ifdef FADERPORT16
: ControlProtocol (s, _("PreSonus FaderPort16"))
#elif defined FADERPORT2
: ControlProtocol (s, _("PreSonus FaderPort2"))
#else
: ControlProtocol (s, _("PreSonus FaderPort8"))
#endif
@ -107,6 +109,7 @@ FaderPort8::FaderPort8 (Session& s)
, gui (0)
, _link_enabled (false)
, _link_locked (false)
, _chan_locked (false)
, _clock_mode (1)
, _scribble_mode (2)
, _two_line_text (false)
@ -118,6 +121,9 @@ FaderPort8::FaderPort8 (Session& s)
#ifdef FADERPORT16
inp = AudioEngine::instance()->register_input_port (DataType::MIDI, "FaderPort16 Recv", true);
outp = AudioEngine::instance()->register_output_port (DataType::MIDI, "FaderPort16 Send", true);
#elif defined FADERPORT2
inp = AudioEngine::instance()->register_input_port (DataType::MIDI, "FaderPort2 Recv", true);
outp = AudioEngine::instance()->register_output_port (DataType::MIDI, "FaderPort2 Send", true);
#else
inp = AudioEngine::instance()->register_input_port (DataType::MIDI, "FaderPort8 Recv", true);
outp = AudioEngine::instance()->register_output_port (DataType::MIDI, "FaderPort8 Send", true);
@ -131,10 +137,13 @@ FaderPort8::FaderPort8 (Session& s)
#ifdef FADERPORT16
_input_bundle.reset (new ARDOUR::Bundle (_("FaderPort16 (Receive)"), true));
_output_bundle.reset (new ARDOUR::Bundle (_("FaderPort16 (Send) "), false));
_output_bundle.reset (new ARDOUR::Bundle (_("FaderPort16 (Send)"), false));
#elif defined FADERPORT2
_input_bundle.reset (new ARDOUR::Bundle (_("FaderPort2 (Receive)"), true));
_output_bundle.reset (new ARDOUR::Bundle (_("FaderPort2 (Send)"), false));
#else
_input_bundle.reset (new ARDOUR::Bundle (_("FaderPort8 (Receive)"), true));
_output_bundle.reset (new ARDOUR::Bundle (_("FaderPort8 (Send) "), false));
_output_bundle.reset (new ARDOUR::Bundle (_("FaderPort8 (Send)"), false));
#endif
_input_bundle->add_channel (
@ -309,7 +318,7 @@ FaderPort8::close ()
DEBUG_TRACE (DEBUG::FaderPort8, "FaderPort8::close\n");
stop_midi_handling ();
session_connections.drop_connections ();
automation_state_connections.drop_connections ();
route_state_connections.drop_connections ();
assigned_stripable_connections.drop_connections ();
_assigned_strips.clear ();
drop_ctrl_connections ();
@ -588,7 +597,15 @@ FaderPort8::controller_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
encoder_navigate (tb->value & dir_mask ? true : false, tb->value & step_mask);
}
if (tb->controller_number == 0x10) {
#ifdef FADERPORT2
if (_ctrls.nav_mode() == NavPan) {
encoder_parameter (tb->value & dir_mask ? true : false, tb->value & step_mask);
} else {
encoder_navigate (tb->value & dir_mask ? true : false, tb->value & step_mask);
}
#else
encoder_parameter (tb->value & dir_mask ? true : false, tb->value & step_mask);
#endif
}
}
@ -974,6 +991,16 @@ FaderPort8::assign_stripables (bool select_only)
set_periodic_display_mode (FP8Strip::Stripables);
}
#ifdef FADERPORT2
boost::shared_ptr<Stripable> s = first_selected_stripable();
if (s) {
_ctrls.strip(0).set_stripable (s, _ctrls.fader_mode() == ModePan);
} else {
_ctrls.strip(0).unset_controllables ( FP8Strip::CTRL_ALL );
}
return;
#endif
int n_strips = strips.size();
int channel_off = get_channel_off (_ctrls.mix_mode ());
channel_off = std::min (channel_off, n_strips - N_STRIPS);
@ -1752,7 +1779,7 @@ FaderPort8::notify_fader_mode_changed ()
break;
}
assign_strips ();
notify_automation_mode_changed ();
notify_route_state_changed ();
}
void
@ -1828,6 +1855,20 @@ FaderPort8::notify_stripable_property_changed (boost::weak_ptr<Stripable> ws, co
}
}
#ifdef FADERPORT2
void
FaderPort8::stripable_selection_changed ()
{
if (!_device_active || _chan_locked) {
return;
}
route_state_connections.drop_connections ();
assign_stripables (false);
subscribe_to_strip_signals ();
}
#else
void
FaderPort8::stripable_selection_changed ()
{
@ -1837,7 +1878,7 @@ FaderPort8::stripable_selection_changed ()
*/
return;
}
automation_state_connections.drop_connections();
route_state_connections.drop_connections();
switch (_ctrls.fader_mode ()) {
case ModePlugins:
@ -1869,21 +1910,34 @@ FaderPort8::stripable_selection_changed ()
_ctrls.strip(id).select_button ().set_blinking (sel && s == first_selected_stripable ());
}
/* track automation-mode of primary selection */
subscribe_to_strip_signals ();
}
#endif
void
FaderPort8::subscribe_to_strip_signals ()
{
/* keep track of automation-mode of primary selection, shared buttons */
boost::shared_ptr<Stripable> s = first_selected_stripable();
if (s) {
boost::shared_ptr<AutomationControl> ac;
ac = s->gain_control();
if (ac && ac->alist()) {
ac->alist()->automation_state_changed.connect (automation_state_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_automation_mode_changed, this), this);
ac->alist()->automation_state_changed.connect (route_state_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_route_state_changed, this), this);
}
ac = s->pan_azimuth_control();
if (ac && ac->alist()) {
ac->alist()->automation_state_changed.connect (automation_state_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_automation_mode_changed, this), this);
ac->alist()->automation_state_changed.connect (route_state_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_route_state_changed, this), this);
}
#ifdef FADERPORT2
ac = s->rec_enable_control();
if (ac) {
ac->Changed.connect (route_state_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_route_state_changed, this), this);
}
#endif
}
/* set lights */
notify_automation_mode_changed ();
notify_route_state_changed ();
}
@ -1968,6 +2022,12 @@ FaderPort8::select_prev_next (bool next)
void
FaderPort8::bank (bool down, bool page)
{
#ifdef FADERPORT2
// XXX this should preferably be in actions.cc
AccessAction ("Editor", down ? "select-prev-stripable" : "select-next-stripable");
return;
#endif
int dt = page ? N_STRIPS : 1;
if (down) {
dt *= -1;

View File

@ -201,9 +201,10 @@ private:
void notify_pi_property_changed (const PBD::PropertyChange&);
void notify_stripable_property_changed (boost::weak_ptr<ARDOUR::Stripable>, const PBD::PropertyChange&);
void stripable_selection_changed ();
void subscribe_to_strip_signals ();
PBD::ScopedConnection selection_connection;
PBD::ScopedConnectionList automation_state_connections;
PBD::ScopedConnectionList route_state_connections;
PBD::ScopedConnectionList modechange_connections;
/* **************************************************************************/
struct ProcessorCtrl {
@ -265,7 +266,7 @@ private:
void notify_history_changed ();
void notify_solo_changed ();
void notify_mute_changed ();
void notify_automation_mode_changed ();
void notify_route_state_changed ();
void notify_plugin_active_changed ();
/* actions */
@ -290,6 +291,9 @@ private:
void button_prev_next (bool);
void button_action (const std::string& group, const std::string& item);
void button_chanlock (); /* FP2 only */
void button_flip (); /* FP2 only */
void button_encoder ();
void button_parameter ();
void encoder_navigate (bool, int);
@ -317,6 +321,8 @@ private:
bool _link_enabled;
bool _link_locked; // can only be true if _link_enabled
bool _chan_locked; /* FP2 only */
/* user prefs */
uint32_t _clock_mode;
uint32_t _scribble_mode;

View File

@ -25,9 +25,11 @@
#include "pbd/signals.h"
#ifdef FADERPORT16
#define FP_NAMESPACE FP16
# define FP_NAMESPACE FP16
#elif defined FADERPORT2
# define FP_NAMESPACE FP2
#else
#define FP_NAMESPACE FP8
# define FP_NAMESPACE FP8
#endif
namespace ArdourSurface { namespace FP_NAMESPACE {
@ -157,7 +159,8 @@ namespace FP8Types {
NavBank,
NavMaster,
NavSection,
NavMarker
NavMarker,
NavPan /* FP2 only */
};
enum MixMode {

View File

@ -61,7 +61,11 @@ bool FP8ButtonInterface::force_change = false;
FP8Controls::FP8Controls (FP8Base& b)
: _fadermode (ModeTrack)
#ifdef FADERPORT2
, _navmode (NavScroll)
#else
, _navmode (NavMaster)
#endif
, _mixmode (MixAll)
, _display_timecode (false)
{
@ -72,6 +76,38 @@ FP8Controls::FP8Controls (FP8Base& b)
NEWBUTTON (0x5e, BtnPlay, false);
NEWBUTTON (0x5f, BtnRecord, false);
#ifdef FADERPORT2
NEWSHIFTBUTTON (0x4a, BtnARead, BtnAOff, true);
NEWSHIFTBUTTON (0x4b, BtnAWrite, BtnATrim, true);
NEWSHIFTBUTTON (0x4d, BtnATouch, BtnALatch, true);
NEWSHIFTBUTTON (0x2e, BtnPrev, BtnUndo, false);
NEWSHIFTBUTTON (0x2f, BtnNext, BtnRedo, false);
NEWSHIFTBUTTON (0x2a, BtnPan, BtnFlip, true); //TODO: Flip Pan knob to fader ...?
NEWSHIFTBUTTON (0x36, BtnChannel, BtnChanLock, true);
NEWSHIFTBUTTON (0x38, BtnScroll, BtnZoom, true);
NEWSHIFTBUTTON (0x3a, BtnMaster, BtnF1, false);
NEWSHIFTBUTTON (0x3b, BtnClick, BtnF2, false);
NEWSHIFTBUTTON (0x3c, BtnSection, BtnF3, false);
NEWSHIFTBUTTON (0x3d, BtnMarker, BtnF4, false);
//these buttons do not exist in FP2, but they need to exist in the ctrlmap:
NEWBUTTON (0x71, BtnBank, false);
NEWBUTTON (0x72, BtnF5, false);
NEWBUTTON (0x73, BtnF6, false);
NEWBUTTON (0x74, BtnF7, false);
NEWBUTTON (0x75, BtnF8, false);
NEWBUTTON (0x76, BtnUser1, false);
NEWBUTTON (0x77, BtnUser2, false);
NEWBUTTON (0x78, BtnUser3, false);
NEWBUTTON (0x79, BtnSave, false);
#else
NEWSHIFTBUTTON (0x4a, BtnARead, BtnUser3, true);
NEWSHIFTBUTTON (0x4b, BtnAWrite, BtnUser2, true);
NEWSHIFTBUTTON (0x4c, BtnATrim, BtnRedo, true);
@ -91,10 +127,12 @@ FP8Controls::FP8Controls (FP8Base& b)
NEWSHIFTBUTTON (0x3c, BtnSection, BtnF7, false);
NEWSHIFTBUTTON (0x3d, BtnMarker, BtnF8, false);
NEWBUTTON (0x2a, BtnPan, false);
#endif
NEWSHIFTBUTTON (0x28, BtnTrack, BtnTimecode, false);
NEWBUTTON (0x2b, BtnPlugins, false);
NEWBUTTON (0x29, BtnSend, false);
NEWBUTTON (0x2a, BtnPan, false);
NEWSHIFTBUTTON (0x00, BtnArm, BtnArmAll, false);
NEWBUTTON (0x01, BtnSoloClear, false);
@ -131,6 +169,9 @@ FP8Controls::FP8Controls (FP8Base& b)
BindNav (BtnMaster, NavMaster);
BindNav (BtnSection, NavSection);
BindNav (BtnMarker, NavMarker);
#ifdef FADERPORT2
BindNav (BtnPan, NavPan);
#endif
#define BindFader(BTN, MODE)\
button (BTN).released.connect_same_thread (button_connections, boost::bind (&FP8Controls::set_fader_mode, this, MODE))
@ -138,7 +179,9 @@ FP8Controls::FP8Controls (FP8Base& b)
BindFader (BtnTrack, ModeTrack);
BindFader (BtnPlugins, ModePlugins);
BindFader (BtnSend, ModeSend);
#ifndef FADERPORT2
BindFader (BtnPan, ModePan);
#endif
#define BindMix(BTN, MODE)\
@ -260,6 +303,14 @@ FP8Controls::initialize ()
button (BtnMFX).set_color (0x0000ffff);
button (BtnMUser).set_color (0x0000ffff);
#ifdef FADERPORT2
/* encoder mode-switches are orange, to match the Master switch physical color */
button (BtnLink).set_color (0x000000ff);
button (BtnChannel).set_color (0x0000ffff);
button (BtnScroll).set_color (0x0000ffff);
button (BtnPan).set_color (0xffffffff);
#endif
for (uint8_t id = 0; id < N_STRIPS; ++id) {
chanstrip[id]->initialize ();
}
@ -268,7 +319,11 @@ FP8Controls::initialize ()
all_lights_off ();
/* default modes */
#ifdef FADERPORT2
button (BtnScroll).set_active (true);
#else
button (BtnMaster).set_active (true);
#endif
button (BtnTrack).set_active (true);
button (BtnMAll).set_active (true);
button (BtnTimecode).set_active (_display_timecode);
@ -357,6 +412,9 @@ FP8Controls::set_nav_mode (NavigationMode m)
button (BtnMaster).set_active (m == NavMaster);
button (BtnSection).set_active (m == NavSection);
button (BtnMarker).set_active (m == NavMarker);
#ifdef FADERPORT2
button (BtnPan).set_active (m == NavPan);
#endif
_navmode = m;
}

View File

@ -112,6 +112,10 @@ public:
BtnLink,
BtnLock,
/* FP2 only */
BtnChanLock,
BtnFlip
};
typedef std::map <ButtonId, std::string> UserButtonMap;
@ -126,9 +130,15 @@ public:
PBD::Signal0<void> FaderModeChanged;
PBD::Signal0<void> MixModeChanged;
#ifdef FADERPORT2
FP8Types::FaderMode fader_mode () const { return FP8Types::ModeTrack; }
FP8Types::MixMode mix_mode () const { return FP8Types::MixUser; }
#else
FP8Types::FaderMode fader_mode () const { return _fadermode; }
FP8Types::NavigationMode nav_mode () const { return _navmode; }
FP8Types::MixMode mix_mode () const { return _mixmode; }
#endif
FP8Types::NavigationMode nav_mode () const { return _navmode; }
bool display_timecode () const { return _display_timecode; }
FP8ButtonInterface& button (ButtonId id);

View File

@ -733,8 +733,10 @@ void
FP8Strip::periodic ()
{
periodic_update_fader ();
#ifndef FADERPORT2
periodic_update_meter ();
if (_displaymode != PluginSelect && _displaymode != PluginParam) {
periodic_update_timecode (_base.clock_mode ());
}
#endif
}

View File

@ -30,6 +30,8 @@
#ifdef FADERPORT16
# define N_STRIPS 16
#elif defined FADERPORT2
# define N_STRIPS 1
#else
# define N_STRIPS 8
#endif

View File

@ -95,6 +95,8 @@ FP8GUI::FP8GUI (FaderPort8& p)
std::string data_file_path;
#ifdef FADERPORT16
string name = "faderport16-small.png";
#elif defined FADERPORT2
string name = ""; // TODO
#else
string name = "faderport8-small.png";
#endif

View File

@ -47,5 +47,18 @@ def build(bld):
obj.use = 'libardour libardour_cp libgtkmm2ext libpbd'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
obj = bld(features = 'cxx cxxshlib')
obj.source = list(fp8_16_sources)
obj.source += [ 'faderport2_interface.cc' ]
obj.defines = [ 'PACKAGE="ardour_faderport8"' ]
obj.defines += [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.defines += [ 'FADERPORT2' ]
obj.includes = [ '.' ]
obj.name = 'libardour_faderport2'
obj.target = 'ardour_faderport2'
obj.uselib = 'GTKMM GTK GDK XML'
obj.use = 'libardour libardour_cp libgtkmm2ext libpbd'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
def shutdown():
autowaf.shutdown()