get faderport i/o working, basics of identifying control activity

This commit is contained in:
Paul Davis 2015-11-24 18:00:11 -05:00
parent 2f1cdd3ffe
commit a15cf9f0b3
7 changed files with 627 additions and 301 deletions

View file

@ -0,0 +1,512 @@
/*
Copyright (C) 2006 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdint.h>
#include <sstream>
#include <algorithm>
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
#include "pbd/controllable_descriptor.h"
#include "pbd/error.h"
#include "pbd/failed_constructor.h"
#include "pbd/file_utils.h"
#include "pbd/xml++.h"
#include "pbd/compose.h"
#include "midi++/port.h"
#include "ardour/audioengine.h"
#include "ardour/filesystem_paths.h"
#include "ardour/session.h"
#include "ardour/route.h"
#include "ardour/midi_ui.h"
#include "ardour/midi_port.h"
#include "ardour/rc_configuration.h"
#include "ardour/midiport_manager.h"
#include "ardour/debug.h"
#include "ardour/async_midi_port.h"
#include "faderport.h"
using namespace ARDOUR;
using namespace PBD;
using namespace Glib;
using namespace std;
#include "i18n.h"
#define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
FaderPort::FaderPort (Session& s)
: ControlProtocol (s, _("Faderport"))
, _motorised (true)
, _threshold (10)
, gui (0)
, connection_state (ConnectionState (0))
, _device_active (false)
, fader_msb (0)
, fader_lsb (0)
{
boost::shared_ptr<ARDOUR::Port> inp;
boost::shared_ptr<ARDOUR::Port> outp;
inp = AudioEngine::instance()->register_input_port (DataType::MIDI, "Faderport Recv", true);
outp = AudioEngine::instance()->register_output_port (DataType::MIDI, "Faderport Send", true);
_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(inp);
_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(outp);
if (_input_port == 0 || _output_port == 0) {
throw failed_constructor();
}
do_feedback = false;
_feedback_interval = 10 * 1000; // microseconds
last_feedback_time = 0;
native_counter = 0;
_current_bank = 0;
_bank_size = 0;
/* handle device inquiry response */
_input_port->parser()->sysex.connect_same_thread (midi_connections, boost::bind (&FaderPort::sysex_handler, this, _1, _2, _3));
/* handle switches */
_input_port->parser()->poly_pressure.connect_same_thread (midi_connections, boost::bind (&FaderPort::switch_handler, this, _1, _2));
/* handle encoder */
_input_port->parser()->pitchbend.connect_same_thread (midi_connections, boost::bind (&FaderPort::encoder_handler, this, _1, _2));
/* handle fader */
_input_port->parser()->controller.connect_same_thread (midi_connections, boost::bind (&FaderPort::fader_handler, this, _1, _2));
/* This connection means that whenever data is ready from the input
* port, the relevant thread will invoke our ::midi_input_handler()
* method, which will read the data, and invoke the parser.
*/
_input_port->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &FaderPort::midi_input_handler), _input_port));
_input_port->xthread().attach (midi_ui_context()->main_loop()->get_context());
Session::SendFeedback.connect_same_thread (*this, boost::bind (&FaderPort::send_feedback, this));
//Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&FaderPort::send_feedback, this), midi_ui_context());;
/* this one is cross-thread */
Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&FaderPort::reset_controllables, this), midi_ui_context());
/* Catch port connections and disconnections */
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::connection_handler, this, _1, _2, _3, _4, _5), midi_ui_context());
}
FaderPort::~FaderPort ()
{
if (_input_port) {
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("unregistering input port %1\n", boost::shared_ptr<ARDOUR::Port>(_input_port)->name()));
AudioEngine::instance()->unregister_port (_input_port);
_input_port.reset ();
}
if (_output_port) {
// _output_port->drain (10000); //ToDo: is this necessary? It hangs the shutdown, for me
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("unregistering output port %1\n", boost::shared_ptr<ARDOUR::Port>(_output_port)->name()));
AudioEngine::instance()->unregister_port (_output_port);
_output_port.reset ();
}
tear_down_gui ();
}
void
FaderPort::switch_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
{
switch (tb->controller_number) {
case Mute:
cerr << "Mute\n";
break;
case Solo:
cerr << "Solo\n";
break;
case Rec:
cerr << "Rec\n";
break;
case Left:
cerr << "Left\n";
break;
case Bank:
cerr << "Bank\n";
break;
case Right:
cerr << "Right\n";
break;
case Output:
cerr << "Output\n";
break;
case Read:
cerr << "Read\n";
break;
case Write:
cerr << "Write\n";
break;
case Touch:
cerr << "Touch\n";
break;
case Off:
cerr << "Off\n";
break;
case Mix:
cerr << "Mix\n";
break;
case Proj:
cerr << "Proj\n";
break;
case Trns:
cerr << "Trns\n";
break;
case Undo:
cerr << "Undo\n";
break;
case Shift:
cerr << "Shift\n";
break;
case Punch:
cerr << "Punch\n";
break;
case User:
cerr << "User\n";
break;
case Loop:
cerr << "Loop\n";
break;
case Rewind:
cerr << "Rewind\n";
break;
case Ffwd:
cerr << "Ffwd\n";
break;
case Stop:
cerr << "Stop\n";
break;
case Play:
cerr << "Play\n";
break;
case RecEnable:
cerr << "RecEnable\n";
break;
case Fader:
cerr << "Fader touch\n";
break;
default:
cerr << "eh?\n";
}
/* send feedback to turn on the LED */
MIDI::byte buf[3];
buf[0] = 0xa0;
buf[1] = tb->controller_number;
buf[2] = tb->value;
_output_port->write (buf, 3, 0);
}
void
FaderPort::encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb)
{
if (pb < 8192) {
cerr << "Encoder right\n";
} else {
cerr << "Encoder left\n";
}
}
void
FaderPort::fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
{
bool was_fader = false;
if (tb->controller_number == 0x0) {
fader_msb = tb->value;
was_fader = true;
} else if (tb->controller_number == 0x20) {
fader_lsb = tb->value;
was_fader = true;
}
if (was_fader) {
cerr << "Fader now at " << ((fader_msb<<7)|fader_lsb) << endl;
}
}
void
FaderPort::sysex_handler (MIDI::Parser &p, MIDI::byte *buf, size_t sz)
{
if (sz < 17) {
return;
}
if (buf[2] == 0x7f &&
buf[3] == 0x06 &&
buf[4] == 0x02 &&
buf[5] == 0x0 &&
buf[6] == 0x1 &&
buf[7] == 0x06 &&
buf[8] == 0x02 &&
buf[9] == 0x0 &&
buf[10] == 0x01 &&
buf[11] == 0x0) {
_device_active = true;
cerr << "FaderPort identified\n";
/* put it into native mode */
MIDI::byte native[3];
native[0] = 0x91;
native[1] = 0x00;
native[2] = 0x64;
_output_port->write (native, 3, 0);
}
}
int
FaderPort::set_active (bool /*yn*/)
{
return 0;
}
void
FaderPort::set_feedback_interval (microseconds_t ms)
{
_feedback_interval = ms;
}
void
FaderPort::send_feedback ()
{
/* This is executed in RT "process" context", so no blocking calls
*/
if (!do_feedback) {
return;
}
microseconds_t now = get_microseconds ();
if (last_feedback_time != 0) {
if ((now - last_feedback_time) < _feedback_interval) {
return;
}
}
last_feedback_time = now;
}
bool
FaderPort::midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port)
{
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", boost::shared_ptr<MIDI::Port>(port)->name()));
if (ioc & ~IO_IN) {
return false;
}
if (ioc & IO_IN) {
if (port) {
port->clear ();
}
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", boost::shared_ptr<MIDI::Port>(port)->name()));
framepos_t now = session->engine().sample_time();
port->parse (now);
}
return true;
}
XMLNode&
FaderPort::get_state ()
{
XMLNode& node (ControlProtocol::get_state());
XMLNode* child;
child = new XMLNode (X_("Input"));
child->add_child_nocopy (boost::shared_ptr<ARDOUR::Port>(_input_port)->get_state());
node.add_child_nocopy (*child);
child = new XMLNode (X_("Output"));
child->add_child_nocopy (boost::shared_ptr<ARDOUR::Port>(_output_port)->get_state());
node.add_child_nocopy (*child);
return node;
}
int
FaderPort::set_state (const XMLNode& node, int version)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
XMLNode const* child;
if (ControlProtocol::set_state (node, version)) {
return -1;
}
if ((child = node.child (X_("Input"))) != 0) {
XMLNode* portnode = child->child (Port::state_node_name.c_str());
if (portnode) {
boost::shared_ptr<ARDOUR::Port>(_input_port)->set_state (*portnode, version);
}
}
if ((child = node.child (X_("Output"))) != 0) {
XMLNode* portnode = child->child (Port::state_node_name.c_str());
if (portnode) {
boost::shared_ptr<ARDOUR::Port>(_output_port)->set_state (*portnode, version);
}
}
return 0;
}
int
FaderPort::set_feedback (bool yn)
{
do_feedback = yn;
last_feedback_time = 0;
return 0;
}
bool
FaderPort::get_feedback () const
{
return do_feedback;
}
void
FaderPort::set_current_bank (uint32_t b)
{
_current_bank = b;
// reset_controllables ();
}
void
FaderPort::next_bank ()
{
_current_bank++;
// reset_controllables ();
}
void
FaderPort::prev_bank()
{
if (_current_bank) {
_current_bank--;
// reset_controllables ();
}
}
void
FaderPort::set_motorised (bool m)
{
_motorised = m;
}
void
FaderPort::set_threshold (int t)
{
_threshold = t;
}
void
FaderPort::reset_controllables ()
{
}
bool
FaderPort::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
{
if (!_input_port || !_output_port) {
return false;
}
string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_input_port)->name());
string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_output_port)->name());
std::cerr << "Checking " << name1 << (yn ? " + " : " - " ) << name2 << " vs. " << ni << " & " << no << std::endl;
if (ni == name1 || ni == name2) {
if (yn) {
connection_state |= InputConnected;
} else {
connection_state &= ~InputConnected;
}
} else if (no == name1 || no == name2) {
if (yn) {
connection_state |= OutputConnected;
} else {
connection_state &= ~OutputConnected;
}
} else {
/* not our ports */
return false;
}
if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
/* XXX this is a horrible hack. Without a short sleep here,
something prevents the device wakeup messages from being
sent and/or the responses from being received.
*/
g_usleep (100000);
connected ();
} else {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 disconnected (input or output or both)\n", _name));
_device_active = false;
}
return true; /* connection status changed */
}
void
FaderPort::connected ()
{
std::cerr << "faderport connected\n";
/* send device inquiry */
MIDI::byte buf[6];
buf[0] = 0xf0;
buf[1] = 0x7e;
buf[2] = 0x7f;
buf[3] = 0x06;
buf[4] = 0x01;
buf[5] = 0xf7;
_output_port->write (buf, 6, 0);
}

View file

@ -17,8 +17,8 @@
*/
#ifndef ardour_generic_midi_control_protocol_h
#define ardour_generic_midi_control_protocol_h
#ifndef ardour_surface_faderport_h
#define ardour_surface_faderport_h
#include <list>
#include <glibmm/threads.h>
@ -60,13 +60,20 @@ class MIDIControllable;
class MIDIFunction;
class MIDIAction;
class FaderportMidiControlProtocol : public ARDOUR::ControlProtocol {
class FaderPort : public ARDOUR::ControlProtocol {
public:
FaderportMidiControlProtocol (ARDOUR::Session&);
virtual ~FaderportMidiControlProtocol();
FaderPort (ARDOUR::Session&);
virtual ~FaderPort();
int set_active (bool yn);
static bool probe() { return true; } //do SysEx device check here?
/* It would be nice to send a device query message here to see if
* faderport is out there. But the probe() API doesn't provide
* a set of ports to be checked, so there's really no nice
* way to do this. We would have to fall back on the PortManager
* and get a list of all physical ports. Could be done ....
*/
static bool probe() { return true; }
void set_feedback_interval (ARDOUR::microseconds_t);
@ -84,6 +91,8 @@ class FaderportMidiControlProtocol : public ARDOUR::ControlProtocol {
void next_bank ();
void prev_bank ();
void reset_controllables ();
void set_motorised (bool);
bool motorised () const {
@ -96,11 +105,11 @@ class FaderportMidiControlProtocol : public ARDOUR::ControlProtocol {
return _threshold;
}
bool device_active() const { return _device_active; }
private:
MIDI::Port* _input_port;
MIDI::Port* _output_port;
boost::shared_ptr<ARDOUR::Port> _async_in;
boost::shared_ptr<ARDOUR::Port> _async_out;
boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
ARDOUR::microseconds_t _feedback_interval;
ARDOUR::microseconds_t last_feedback_time;
@ -109,10 +118,9 @@ class FaderportMidiControlProtocol : public ARDOUR::ControlProtocol {
bool do_feedback;
void send_feedback ();
PBD::ScopedConnection midi_recv_connection;
void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t);
PBD::ScopedConnectionList midi_connections;
bool midi_input_handler (Glib::IOCondition ioc, ARDOUR::AsyncMIDIPort* port);
bool midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port);
std::string _current_binding;
uint32_t _bank_size;
@ -127,6 +135,82 @@ class FaderportMidiControlProtocol : public ARDOUR::ControlProtocol {
mutable void *gui;
void build_gui ();
bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
PBD::ScopedConnection port_connection;
enum ConnectionState {
InputConnected = 0x1,
OutputConnected = 0x2
};
#endif /* ardour_generic_midi_control_protocol_h */
int connection_state;
void connected ();
bool _device_active;
int fader_msb;
int fader_lsb;
void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
void switch_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
void encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb);
void fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
enum InButtonID {
Mute = 18,
Solo = 17,
Rec = 16,
Left = 19,
Bank = 20,
Right = 21,
Output = 22,
Read = 10,
Write = 9,
Touch = 8,
Off = 23,
Mix = 11,
Proj = 12,
Trns = 13,
Undo = 14,
Shift = 2,
Punch = 1,
User = 0,
Loop = 15,
Rewind = 3,
Ffwd = 4,
Stop = 5,
Play = 6,
RecEnable = 7,
Fader = 127,
};
/*
enum OutButtonID {
Mute = 18,
Solo = 17,
Rec = 16,
Left = 19,
Bank = 20,
Right = 21,
Output = 22,
Read = 10,
Write = 9,
Touch = 8,
Off = 23,
Mix = 11,
Proj = 12,
Trns = 13,
Undo = 14,
Shift = 2,
Punch = 1,
User = 0,
Loop = 15,
Rewind = 3,
Ffwd = 4,
Stop = 5,
Play = 6,
RecEnable = 7,
}
*/
};
#endif /* ardour_surface_faderport_h */

View file

@ -20,27 +20,27 @@
#include <pbd/failed_constructor.h>
#include "control_protocol/control_protocol.h"
#include "faderport_midi_protocol.h"
#include "faderport.h"
using namespace ARDOUR;
static ControlProtocol*
new_faderport_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s)
{
FaderportMidiControlProtocol* fmcp;
FaderPort* fp;
try {
fmcp = new FaderportMidiControlProtocol (*s);
fp = new FaderPort (*s);
} catch (failed_constructor& err) {
return 0;
}
if (fmcp->set_active (true)) {
delete fmcp;
if (fp->set_active (true)) {
delete fp;
return 0;
}
return fmcp;
return fp;
}
static void
@ -52,7 +52,7 @@ delete_faderport_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Contr
static bool
probe_faderport_midi_protocol (ControlProtocolDescriptor* /*descriptor*/)
{
return FaderportMidiControlProtocol::probe ();
return FaderPort::probe ();
}
static ControlProtocolDescriptor faderport_midi_descriptor = {

View file

@ -1,270 +0,0 @@
/*
Copyright (C) 2006 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdint.h>
#include <sstream>
#include <algorithm>
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
#include "pbd/controllable_descriptor.h"
#include "pbd/error.h"
#include "pbd/failed_constructor.h"
#include "pbd/file_utils.h"
#include "pbd/xml++.h"
#include "pbd/compose.h"
#include "midi++/port.h"
#include "ardour/audioengine.h"
#include "ardour/filesystem_paths.h"
#include "ardour/session.h"
#include "ardour/route.h"
#include "ardour/midi_ui.h"
#include "ardour/midi_port.h"
#include "ardour/rc_configuration.h"
#include "ardour/midiport_manager.h"
#include "ardour/debug.h"
#include "ardour/async_midi_port.h"
#include "faderport_midi_protocol.h"
using namespace ARDOUR;
using namespace PBD;
using namespace Glib;
using namespace std;
#include "i18n.h"
#define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
FaderportMidiControlProtocol::FaderportMidiControlProtocol (Session& s)
: ControlProtocol (s, _("Faderport"))
, _motorised (true)
, _threshold (10)
, gui (0)
{
_async_in = AudioEngine::instance()->register_input_port (DataType::MIDI, "Faderport Recv", true);
_async_out = AudioEngine::instance()->register_output_port (DataType::MIDI, "Faderport Send", true);
if (_async_in == 0 || _async_out == 0) {
throw failed_constructor();
}
_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_in).get();
_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_out).get();
do_feedback = false;
_feedback_interval = 10 * 1000; // microseconds
last_feedback_time = 0;
native_counter = 0;
_current_bank = 0;
_bank_size = 0;
//NOTE TO PAUL:
// "midi_receiver" and "midi_input_handler"
// were 2 different approaches to try to capture MIDI data; neither seems to work as expected.
//not sure if this should do anything
(*_input_port).parser()->any.connect_same_thread (midi_recv_connection, boost::bind (&FaderportMidiControlProtocol::midi_receiver, this, _1, _2, _3));
//this is raw port acces (?)
// _input_port->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &FaderportMidiControlProtocol::midi_input_handler), _input_port));
Session::SendFeedback.connect_same_thread (*this, boost::bind (&FaderportMidiControlProtocol::send_feedback, this));
//Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&FaderportMidiControlProtocol::send_feedback, this), midi_ui_context());;
/* this one is cross-thread */
//Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&FaderportMidiControlProtocol::reset_controllables, this), midi_ui_context());
}
FaderportMidiControlProtocol::~FaderportMidiControlProtocol ()
{
if (_input_port) {
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("unregistering input port %1\n", _async_in->name()));
AudioEngine::instance()->unregister_port (_async_in);
_async_in.reset ((ARDOUR::Port*) 0);
}
if (_output_port) {
// _output_port->drain (10000); //ToDo: is this necessary? It hangs the shutdown, for me
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("unregistering output port %1\n", _async_out->name()));
AudioEngine::instance()->unregister_port (_async_out);
_async_out.reset ((ARDOUR::Port*) 0);
}
tear_down_gui ();
}
void
FaderportMidiControlProtocol::midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t)
{
//NOTE: this never did anything
// printf("got some midi\n");
}
int
FaderportMidiControlProtocol::set_active (bool /*yn*/)
{
return 0;
}
void
FaderportMidiControlProtocol::set_feedback_interval (microseconds_t ms)
{
_feedback_interval = ms;
}
void
FaderportMidiControlProtocol::send_feedback ()
{
/* This is executed in RT "process" context", so no blocking calls
*/
if (!do_feedback) {
return;
}
microseconds_t now = get_microseconds ();
if (last_feedback_time != 0) {
if ((now - last_feedback_time) < _feedback_interval) {
return;
}
}
//occasionally tell the Faderport to go into "Native" mode
//ToDo: trigger this on MIDI port connection ?
native_counter++;
if (native_counter > 10) {
native_counter = 0;
MIDI::byte midibuf[64];
MIDI::byte *buf = midibuf;
*buf++ = (0x91);
*buf++ = (0x00);
*buf++ = (0x64);
_output_port->write (buf, 3, 0);
}
last_feedback_time = now;
}
bool
FaderportMidiControlProtocol::midi_input_handler (Glib::IOCondition ioc, ARDOUR::AsyncMIDIPort* port)
{
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", ((ARDOUR::Port*)port)->name()));
if (ioc & ~IO_IN) {
return false;
}
if (ioc & IO_IN) {
AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*> (port);
if (asp) {
asp->clear ();
}
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name()));
// framepos_t now = _session.engine().sample_time();
// port->parse (now);
}
return true;
}
XMLNode&
FaderportMidiControlProtocol::get_state ()
{
XMLNode& node (ControlProtocol::get_state());
char buf[32];
return node;
}
int
FaderportMidiControlProtocol::set_state (const XMLNode& node, int version)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
const XMLProperty* prop;
if (ControlProtocol::set_state (node, version)) {
return -1;
}
return 0;
}
int
FaderportMidiControlProtocol::set_feedback (bool yn)
{
do_feedback = yn;
last_feedback_time = 0;
return 0;
}
bool
FaderportMidiControlProtocol::get_feedback () const
{
return do_feedback;
}
void
FaderportMidiControlProtocol::set_current_bank (uint32_t b)
{
_current_bank = b;
// reset_controllables ();
}
void
FaderportMidiControlProtocol::next_bank ()
{
_current_bank++;
// reset_controllables ();
}
void
FaderportMidiControlProtocol::prev_bank()
{
if (_current_bank) {
_current_bank--;
// reset_controllables ();
}
}
void
FaderportMidiControlProtocol::set_motorised (bool m)
{
_motorised = m;
}
void
FaderportMidiControlProtocol::set_threshold (int t)
{
_threshold = t;
}

View file

@ -31,18 +31,18 @@
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/utils.h"
#include "faderport_midi_protocol.h"
#include "faderport.h"
#include "i18n.h"
class GMCPGUI : public Gtk::VBox
{
public:
GMCPGUI (FaderportMidiControlProtocol&);
GMCPGUI (FaderPort&);
~GMCPGUI ();
private:
FaderportMidiControlProtocol& cp;
FaderPort& cp;
Gtk::ComboBoxText map_combo;
Gtk::Adjustment bank_adjustment;
Gtk::SpinButton bank_spinner;
@ -63,17 +63,17 @@ using namespace Gtk;
using namespace Gtkmm2ext;
void*
FaderportMidiControlProtocol::get_gui () const
FaderPort::get_gui () const
{
if (!gui) {
const_cast<FaderportMidiControlProtocol*>(this)->build_gui ();
const_cast<FaderPort*>(this)->build_gui ();
}
static_cast<Gtk::VBox*>(gui)->show_all();
return gui;
}
void
FaderportMidiControlProtocol::tear_down_gui ()
FaderPort::tear_down_gui ()
{
if (gui) {
Gtk::Widget *w = static_cast<Gtk::VBox*>(gui)->get_parent();
@ -87,14 +87,14 @@ FaderportMidiControlProtocol::tear_down_gui ()
}
void
FaderportMidiControlProtocol::build_gui ()
FaderPort::build_gui ()
{
gui = (void*) new GMCPGUI (*this);
}
/*--------------------*/
GMCPGUI::GMCPGUI (FaderportMidiControlProtocol& p)
GMCPGUI::GMCPGUI (FaderPort& p)
: cp (p)
, bank_adjustment (1, 1, 100, 1, 10)
, bank_spinner (bank_adjustment)

View file

@ -15,7 +15,7 @@ def configure(conf):
def build(bld):
obj = bld(features = 'cxx cxxshlib')
obj.source = '''
faderport_midi_protocol.cc
faderport.cc
fmcp_gui.cc
faderport_interface.cc
'''