Trim midi++ port code to either do in or out, but not both in the same object.
git-svn-id: svn://localhost/ardour2/branches/3.0@7391 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
a15bdfc6d9
commit
4885f29be1
@ -134,8 +134,7 @@ MidiTracer::port_changed ()
|
||||
Port* p = Manager::instance()->port (_port_combo.get_active_text());
|
||||
|
||||
if (p) {
|
||||
Parser* parser = p->input() ? p->input() : p->output();
|
||||
parser->any.connect_same_thread (_parser_connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
|
||||
p->parser()->any.connect_same_thread (_parser_connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,11 +77,11 @@ MIDIClock_Slave::rebind (MIDI::Port& p)
|
||||
|
||||
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave: connecting to port %1\n", port->name()));
|
||||
|
||||
port->input()->timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
|
||||
port->input()->start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
|
||||
port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
|
||||
port->input()->stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
|
||||
port->input()->position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
|
||||
port->parser()->timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
|
||||
port->parser()->start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
|
||||
port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
|
||||
port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
|
||||
port->parser()->position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -95,9 +95,9 @@ MTC_Slave::rebind (MIDI::Port& p)
|
||||
|
||||
port = &p;
|
||||
|
||||
port->input()->mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
|
||||
port->input()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
|
||||
port->input()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
|
||||
port->parser()->mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
|
||||
port->parser()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
|
||||
port->parser()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
@ -381,7 +381,7 @@ MTC_Slave::read_current (SafeTime *st) const
|
||||
bool
|
||||
MTC_Slave::locked () const
|
||||
{
|
||||
return port->input()->mtc_locked();
|
||||
return port->parser()->mtc_locked();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -543,7 +543,7 @@ MTC_Slave::reset_window (nframes64_t root)
|
||||
ahead of the window root (taking direction into account).
|
||||
*/
|
||||
|
||||
switch (port->input()->mtc_running()) {
|
||||
switch (port->parser()->mtc_running()) {
|
||||
case MTC_Forward:
|
||||
window_begin = root;
|
||||
if (session.slave_state() == Session::Running) {
|
||||
|
@ -282,12 +282,12 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||
|
||||
MIDI::Manager* m = MIDI::Manager::instance ();
|
||||
|
||||
_mtc_input_port = m->add_port (new MIDI::Port ("MTC", O_RDONLY, _engine.jack()));
|
||||
_mtc_output_port = m->add_port (new MIDI::Port ("MTC", O_WRONLY, _engine.jack()));
|
||||
_midi_input_port = m->add_port (new MIDI::Port ("MIDI control", O_RDONLY, _engine.jack()));
|
||||
_midi_output_port = m->add_port (new MIDI::Port ("MIDI control", O_WRONLY, _engine.jack()));
|
||||
_midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock", O_RDONLY, _engine.jack()));
|
||||
_midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock", O_WRONLY, _engine.jack()));
|
||||
_mtc_input_port = m->add_port (new MIDI::Port ("MTC in", MIDI::Port::IsInput, _engine.jack()));
|
||||
_mtc_output_port = m->add_port (new MIDI::Port ("MTC out", MIDI::Port::IsOutput, _engine.jack()));
|
||||
_midi_input_port = m->add_port (new MIDI::Port ("MIDI control in", MIDI::Port::IsInput, _engine.jack()));
|
||||
_midi_output_port = m->add_port (new MIDI::Port ("MIDI control out", MIDI::Port::IsOutput, _engine.jack()));
|
||||
_midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock in", MIDI::Port::IsInput, _engine.jack()));
|
||||
_midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock out", MIDI::Port::IsOutput, _engine.jack()));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -33,31 +33,17 @@ Channel::Channel (byte channelnum, Port &p) : _port (p)
|
||||
}
|
||||
|
||||
void
|
||||
Channel::connect_input_signals ()
|
||||
Channel::connect_signals ()
|
||||
{
|
||||
_port.input()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
|
||||
_port.input()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
|
||||
_port.input()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
|
||||
_port.input()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
|
||||
_port.input()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
|
||||
_port.input()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
|
||||
_port.input()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
|
||||
_port.parser()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
|
||||
_port.parser()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
|
||||
_port.parser()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
|
||||
_port.parser()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
|
||||
_port.parser()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
|
||||
_port.parser()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
|
||||
_port.parser()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
|
||||
|
||||
_port.input()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Channel::connect_output_signals ()
|
||||
{
|
||||
_port.output()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
|
||||
_port.output()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
|
||||
_port.output()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
|
||||
_port.output()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
|
||||
_port.output()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
|
||||
_port.output()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
|
||||
_port.output()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
|
||||
|
||||
_port.output()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
|
||||
_port.parser()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
@ -188,11 +174,8 @@ Channel::process_controller (Parser & /*parser*/, EventTwoBytes *tb)
|
||||
|
||||
if (tb->controller_number == 0) {
|
||||
_bank_number = (unsigned short) _controller_val[0];
|
||||
if (_port.input()) {
|
||||
_port.input()->bank_change (*_port.input(), _bank_number);
|
||||
_port.input()->channel_bank_change[_channel_number]
|
||||
(*_port.input(), _bank_number);
|
||||
}
|
||||
_port.parser()->bank_change (*_port.parser(), _bank_number);
|
||||
_port.parser()->channel_bank_change[_channel_number] (*_port.parser(), _bank_number);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -112,8 +112,7 @@ class Channel : public PBD::ScopedConnectionList {
|
||||
|
||||
protected:
|
||||
friend class Port;
|
||||
void connect_input_signals ();
|
||||
void connect_output_signals ();
|
||||
void connect_signals ();
|
||||
|
||||
private:
|
||||
Port & _port;
|
||||
|
@ -42,7 +42,12 @@ class PortRequest;
|
||||
|
||||
class Port {
|
||||
public:
|
||||
Port (std::string const &, int, jack_client_t *);
|
||||
enum Flags {
|
||||
IsInput = JackPortIsInput,
|
||||
IsOutput = JackPortIsOutput,
|
||||
};
|
||||
|
||||
Port (std::string const &, Flags, jack_client_t *);
|
||||
Port (const XMLNode&, jack_client_t *);
|
||||
~Port ();
|
||||
|
||||
@ -96,16 +101,24 @@ class Port {
|
||||
return _channel[chn&0x7F];
|
||||
}
|
||||
|
||||
Parser *input() { return input_parser; }
|
||||
Parser *output() { return output_parser; }
|
||||
Parser* parser () {
|
||||
return _parser;
|
||||
}
|
||||
|
||||
const char *name () const { return _tagname.c_str(); }
|
||||
int mode () const { return _mode; }
|
||||
bool ok () const { return _ok; }
|
||||
|
||||
bool receives_input () const {
|
||||
return _flags == IsInput;
|
||||
}
|
||||
|
||||
bool sends_output () const {
|
||||
return _flags == IsOutput;
|
||||
}
|
||||
|
||||
struct Descriptor {
|
||||
std::string tag;
|
||||
int mode;
|
||||
Flags flags;
|
||||
|
||||
Descriptor (const XMLNode&);
|
||||
XMLNode& get_state();
|
||||
@ -128,36 +141,27 @@ private:
|
||||
bool _currently_in_cycle;
|
||||
nframes_t _nframes_this_cycle;
|
||||
std::string _tagname;
|
||||
int _mode;
|
||||
size_t _number;
|
||||
Channel *_channel[16];
|
||||
Parser *input_parser;
|
||||
Parser *output_parser;
|
||||
Parser *_parser;
|
||||
|
||||
static size_t nports;
|
||||
|
||||
void create_port_names ();
|
||||
int create_ports ();
|
||||
int create_port ();
|
||||
|
||||
jack_client_t* _jack_client;
|
||||
std::string _jack_input_port_name; /// input port name, or empty if there isn't one
|
||||
jack_port_t* _jack_input_port;
|
||||
std::string _jack_output_port_name; /// output port name, or empty if there isn't one
|
||||
jack_port_t* _jack_output_port;
|
||||
jack_port_t* _jack_port;
|
||||
nframes_t _last_read_index;
|
||||
timestamp_t _last_write_timestamp;
|
||||
|
||||
/** Channel used to signal to the MidiControlUI that input has arrived */
|
||||
CrossThreadChannel xthread;
|
||||
|
||||
std::string _inbound_connections;
|
||||
std::string _outbound_connections;
|
||||
std::string _connections;
|
||||
PBD::ScopedConnection connect_connection;
|
||||
PBD::ScopedConnection halt_connection;
|
||||
void flush (void* jack_port_buffer);
|
||||
void jack_halted ();
|
||||
void make_connections();
|
||||
void init (std::string const &, int);
|
||||
void make_connections ();
|
||||
void init (std::string const &, Flags);
|
||||
|
||||
static pthread_t _process_thread;
|
||||
|
||||
@ -165,7 +169,8 @@ private:
|
||||
Evoral::EventRingBuffer<timestamp_t> input_fifo;
|
||||
|
||||
Glib::Mutex output_fifo_lock;
|
||||
|
||||
|
||||
Flags _flags;
|
||||
};
|
||||
|
||||
struct PortSet {
|
||||
|
@ -202,13 +202,13 @@ MachineControl::MachineControl (jack_client_t* jack)
|
||||
_receive_device_id = 0;
|
||||
_send_device_id = 0x7f;
|
||||
|
||||
_input_port = Manager::instance()->add_port (new Port ("MMC", O_RDONLY, jack));
|
||||
_output_port = Manager::instance()->add_port (new Port ("MMC", O_WRONLY, jack));
|
||||
_input_port = Manager::instance()->add_port (new Port ("MMC in", Port::IsInput, jack));
|
||||
_output_port = Manager::instance()->add_port (new Port ("MMC out", Port::IsOutput, jack));
|
||||
|
||||
_input_port->input()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
|
||||
_input_port->input()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
|
||||
_input_port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
|
||||
_input_port->input()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
|
||||
_input_port->parser()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
|
||||
_input_port->parser()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
|
||||
_input_port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
|
||||
_input_port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -39,81 +39,59 @@ using namespace MIDI;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
size_t Port::nports = 0;
|
||||
pthread_t Port::_process_thread;
|
||||
Signal0<void> Port::JackHalted;
|
||||
Signal0<void> Port::MakeConnections;
|
||||
|
||||
Port::Port (string const & name, int mode, jack_client_t* jack_client)
|
||||
Port::Port (string const & name, Flags flags, jack_client_t* jack_client)
|
||||
: _currently_in_cycle (false)
|
||||
, _nframes_this_cycle (0)
|
||||
, _jack_client (jack_client)
|
||||
, _jack_input_port (0)
|
||||
, _jack_output_port (0)
|
||||
, _jack_port (0)
|
||||
, _last_read_index (0)
|
||||
, output_fifo (512)
|
||||
, input_fifo (1024)
|
||||
, _flags (flags)
|
||||
{
|
||||
init (name, mode);
|
||||
init (name, flags);
|
||||
}
|
||||
|
||||
Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
||||
: _currently_in_cycle (false)
|
||||
, _nframes_this_cycle (0)
|
||||
, _jack_client (jack_client)
|
||||
, _jack_input_port (0)
|
||||
, _jack_output_port (0)
|
||||
, _jack_port (0)
|
||||
, _last_read_index (0)
|
||||
, output_fifo (512)
|
||||
, input_fifo (1024)
|
||||
{
|
||||
Descriptor desc (node);
|
||||
|
||||
init (desc.tag, desc.mode);
|
||||
init (desc.tag, desc.flags);
|
||||
|
||||
set_state (node);
|
||||
}
|
||||
|
||||
void
|
||||
Port::init (string const & name, int mode)
|
||||
Port::init (string const & name, Flags flags)
|
||||
{
|
||||
_ok = false; /* derived class must set to true if constructor
|
||||
succeeds.
|
||||
*/
|
||||
|
||||
input_parser = 0;
|
||||
output_parser = 0;
|
||||
_parser = 0;
|
||||
|
||||
_tagname = name;
|
||||
_mode = mode;
|
||||
_flags = flags;
|
||||
|
||||
if (_mode == O_RDONLY || _mode == O_RDWR) {
|
||||
input_parser = new Parser (*this);
|
||||
} else {
|
||||
input_parser = 0;
|
||||
}
|
||||
|
||||
if (_mode == O_WRONLY || _mode == O_RDWR) {
|
||||
output_parser = new Parser (*this);
|
||||
} else {
|
||||
output_parser = 0;
|
||||
}
|
||||
_parser = new Parser (*this);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
_channel[i] = new Channel (i, *this);
|
||||
|
||||
if (input_parser) {
|
||||
_channel[i]->connect_input_signals ();
|
||||
}
|
||||
|
||||
if (output_parser) {
|
||||
_channel[i]->connect_output_signals ();
|
||||
}
|
||||
_channel[i] = new Channel (i, *this);
|
||||
_channel[i]->connect_signals ();
|
||||
}
|
||||
|
||||
create_port_names ();
|
||||
|
||||
if (!create_ports ()) {
|
||||
if (!create_port ()) {
|
||||
_ok = true;
|
||||
}
|
||||
|
||||
@ -128,18 +106,11 @@ Port::~Port ()
|
||||
delete _channel[i];
|
||||
}
|
||||
|
||||
if (_jack_input_port) {
|
||||
if (_jack_client && _jack_input_port) {
|
||||
jack_port_unregister (_jack_client, _jack_input_port);
|
||||
if (_jack_port) {
|
||||
if (_jack_client && _jack_port) {
|
||||
jack_port_unregister (_jack_client, _jack_port);
|
||||
}
|
||||
_jack_input_port = 0;
|
||||
}
|
||||
|
||||
if (_jack_output_port) {
|
||||
if (_jack_client && _jack_output_port) {
|
||||
jack_port_unregister (_jack_client, _jack_output_port);
|
||||
}
|
||||
_jack_output_port = 0;
|
||||
_jack_port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,9 +124,7 @@ Port::parse (nframes_t timestamp)
|
||||
once it has data ready.
|
||||
*/
|
||||
|
||||
if (input_parser) {
|
||||
input_parser->set_timestamp (timestamp);
|
||||
}
|
||||
_parser->set_timestamp (timestamp);
|
||||
|
||||
while (1) {
|
||||
|
||||
@ -190,7 +159,7 @@ Port::clock (timestamp_t timestamp)
|
||||
{
|
||||
static byte clockmsg = 0xf8;
|
||||
|
||||
if (_mode != O_RDONLY) {
|
||||
if (sends_output()) {
|
||||
return midimsg (&clockmsg, 1, timestamp);
|
||||
}
|
||||
|
||||
@ -207,16 +176,14 @@ Port::cycle_start (nframes_t nframes)
|
||||
_last_read_index = 0;
|
||||
_last_write_timestamp = 0;
|
||||
|
||||
if (_jack_output_port != 0) {
|
||||
// output
|
||||
void *buffer = jack_port_get_buffer (_jack_output_port, nframes);
|
||||
if (sends_output()) {
|
||||
void *buffer = jack_port_get_buffer (_jack_port, nframes);
|
||||
jack_midi_clear_buffer (buffer);
|
||||
flush (buffer);
|
||||
}
|
||||
|
||||
if (_jack_input_port != 0) {
|
||||
// input
|
||||
void* jack_buffer = jack_port_get_buffer(_jack_input_port, nframes);
|
||||
if (receives_input()) {
|
||||
void* jack_buffer = jack_port_get_buffer(_jack_port, nframes);
|
||||
const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
|
||||
|
||||
jack_midi_event_t ev;
|
||||
@ -236,8 +203,8 @@ Port::cycle_start (nframes_t nframes)
|
||||
void
|
||||
Port::cycle_end ()
|
||||
{
|
||||
if (_jack_output_port != 0) {
|
||||
flush (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle));
|
||||
if (sends_output()) {
|
||||
flush (jack_port_get_buffer (_jack_port, _nframes_this_cycle));
|
||||
}
|
||||
|
||||
_currently_in_cycle = false;
|
||||
@ -250,8 +217,6 @@ std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
|
||||
os << "MIDI::Port { ";
|
||||
os << "name: " << port.name();
|
||||
os << "; ";
|
||||
os << "mode: " << port.mode();
|
||||
os << "; ";
|
||||
os << "ok: " << port.ok();
|
||||
os << "; ";
|
||||
os << " }";
|
||||
@ -271,12 +236,10 @@ Port::Descriptor::Descriptor (const XMLNode& node)
|
||||
|
||||
if ((prop = node.property ("mode")) != 0) {
|
||||
|
||||
mode = O_RDWR;
|
||||
|
||||
if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
|
||||
mode = O_WRONLY;
|
||||
flags = IsOutput;
|
||||
} else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
|
||||
mode = O_RDONLY;
|
||||
flags = IsInput;
|
||||
}
|
||||
|
||||
have_mode = true;
|
||||
@ -291,8 +254,7 @@ void
|
||||
Port::jack_halted ()
|
||||
{
|
||||
_jack_client = 0;
|
||||
_jack_input_port = 0;
|
||||
_jack_output_port = 0;
|
||||
_jack_port = 0;
|
||||
}
|
||||
|
||||
int
|
||||
@ -300,7 +262,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!_jack_output_port) {
|
||||
if (!sends_output()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -344,7 +306,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
|
||||
timestamp = _last_write_timestamp;
|
||||
}
|
||||
|
||||
if (jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle),
|
||||
if (jack_midi_event_write (jack_port_get_buffer (_jack_port, _nframes_this_cycle),
|
||||
timestamp, msg, msglen) == 0) {
|
||||
ret = msglen;
|
||||
_last_write_timestamp = timestamp;
|
||||
@ -352,7 +314,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
|
||||
} else {
|
||||
ret = 0;
|
||||
cerr << "write of " << msglen << " failed, port holds "
|
||||
<< jack_midi_get_event_count (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle))
|
||||
<< jack_midi_get_event_count (jack_port_get_buffer (_jack_port, _nframes_this_cycle))
|
||||
<< endl;
|
||||
}
|
||||
} else {
|
||||
@ -360,11 +322,11 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0 && output_parser) {
|
||||
if (ret > 0 && _parser) {
|
||||
// ardour doesn't care about this and neither should your app, probably
|
||||
// output_parser->raw_preparse (*output_parser, msg, ret);
|
||||
for (int i = 0; i < ret; i++) {
|
||||
output_parser->scanner (msg[i]);
|
||||
_parser->scanner (msg[i]);
|
||||
}
|
||||
// ardour doesn't care about this and neither should your app, probably
|
||||
// output_parser->raw_postparse (*output_parser, msg, ret);
|
||||
@ -411,64 +373,34 @@ Port::flush (void* jack_port_buffer)
|
||||
int
|
||||
Port::read (byte *, size_t)
|
||||
{
|
||||
if (!receives_input()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
timestamp_t time;
|
||||
Evoral::EventType type;
|
||||
uint32_t size;
|
||||
byte buffer[input_fifo.capacity()];
|
||||
|
||||
while (input_fifo.read (&time, &type, &size, buffer)) {
|
||||
if (input_parser) {
|
||||
input_parser->set_timestamp (time);
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
input_parser->scanner (buffer[i]);
|
||||
}
|
||||
_parser->set_timestamp (time);
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
_parser->scanner (buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Port::create_port_names ()
|
||||
{
|
||||
assert(!_jack_input_port);
|
||||
assert(!_jack_output_port);
|
||||
|
||||
if (_mode == O_RDWR || _mode == O_WRONLY) {
|
||||
_jack_output_port_name = _tagname.append ("_out");
|
||||
}
|
||||
|
||||
if (_mode == O_RDWR || _mode == O_RDONLY) {
|
||||
_jack_input_port_name = _tagname.append ("_in");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Port::create_ports ()
|
||||
Port::create_port ()
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
jack_nframes_t nframes = jack_get_buffer_size(_jack_client);
|
||||
|
||||
if (!_jack_output_port_name.empty()) {
|
||||
_jack_output_port = jack_port_register(_jack_client, _jack_output_port_name.c_str(),
|
||||
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
|
||||
if (_jack_output_port) {
|
||||
jack_midi_clear_buffer(jack_port_get_buffer(_jack_output_port, nframes));
|
||||
}
|
||||
ret = ret && (_jack_output_port != NULL);
|
||||
}
|
||||
|
||||
if (!_jack_input_port_name.empty()) {
|
||||
_jack_input_port = jack_port_register(_jack_client, _jack_input_port_name.c_str(),
|
||||
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
|
||||
if (_jack_input_port) {
|
||||
jack_midi_clear_buffer(jack_port_get_buffer(_jack_input_port, nframes));
|
||||
}
|
||||
ret = ret && (_jack_input_port != NULL);
|
||||
_jack_port = jack_port_register(_jack_client, _tagname.c_str(), JACK_DEFAULT_MIDI_TYPE, _flags, 0);
|
||||
if (_jack_port) {
|
||||
jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, jack_get_buffer_size (_jack_client)));
|
||||
}
|
||||
|
||||
return ret ? 0 : -1;
|
||||
return _jack_port == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
@ -477,12 +409,10 @@ Port::get_state () const
|
||||
XMLNode* root = new XMLNode ("MIDI-port");
|
||||
root->add_property ("tag", _tagname);
|
||||
|
||||
if (_mode == O_RDONLY) {
|
||||
if (_flags == IsInput) {
|
||||
root->add_property ("mode", "input");
|
||||
} else if (_mode == O_WRONLY) {
|
||||
root->add_property ("mode", "output");
|
||||
} else {
|
||||
root->add_property ("mode", "duplex");
|
||||
root->add_property ("mode", "output");
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -498,9 +428,9 @@ Port::get_state () const
|
||||
write (device_inquiry, sizeof (device_inquiry), 0);
|
||||
#endif
|
||||
|
||||
if (_jack_output_port) {
|
||||
if (_jack_port) {
|
||||
|
||||
const char** jc = jack_port_get_connections (_jack_output_port);
|
||||
const char** jc = jack_port_get_connections (_jack_port);
|
||||
string connection_string;
|
||||
if (jc) {
|
||||
for (int i = 0; jc[i]; ++i) {
|
||||
@ -513,34 +443,11 @@ Port::get_state () const
|
||||
}
|
||||
|
||||
if (!connection_string.empty()) {
|
||||
root->add_property ("outbound", connection_string);
|
||||
root->add_property ("connections", connection_string);
|
||||
}
|
||||
} else {
|
||||
if (!_outbound_connections.empty()) {
|
||||
root->add_property ("outbound", _outbound_connections);
|
||||
}
|
||||
}
|
||||
|
||||
if (_jack_input_port) {
|
||||
|
||||
const char** jc = jack_port_get_connections (_jack_input_port);
|
||||
string connection_string;
|
||||
if (jc) {
|
||||
for (int i = 0; jc[i]; ++i) {
|
||||
if (i > 0) {
|
||||
connection_string += ',';
|
||||
}
|
||||
connection_string += jc[i];
|
||||
}
|
||||
free (jc);
|
||||
}
|
||||
|
||||
if (!connection_string.empty()) {
|
||||
root->add_property ("inbound", connection_string);
|
||||
}
|
||||
} else {
|
||||
if (!_inbound_connections.empty()) {
|
||||
root->add_property ("inbound", _inbound_connections);
|
||||
if (!_connections.empty()) {
|
||||
root->add_property ("connections", _connections);
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,39 +459,29 @@ Port::set_state (const XMLNode& node)
|
||||
{
|
||||
const XMLProperty* prop;
|
||||
|
||||
if ((prop = node.property ("inbound")) != 0 && _jack_input_port) {
|
||||
_inbound_connections = prop->value ();
|
||||
}
|
||||
|
||||
if ((prop = node.property ("outbound")) != 0 && _jack_output_port) {
|
||||
_outbound_connections = prop->value();
|
||||
if ((prop = node.property ("connections")) != 0 && _jack_port) {
|
||||
_connections = prop->value ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Port::make_connections ()
|
||||
{
|
||||
if (!_inbound_connections.empty()) {
|
||||
if (!_connections.empty()) {
|
||||
vector<string> ports;
|
||||
split (_inbound_connections, ports, ',');
|
||||
split (_connections, ports, ',');
|
||||
for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
|
||||
if (_jack_client) {
|
||||
jack_connect (_jack_client, (*x).c_str(), jack_port_name (_jack_input_port));
|
||||
if (receives_input()) {
|
||||
jack_connect (_jack_client, (*x).c_str(), jack_port_name (_jack_port));
|
||||
} else {
|
||||
jack_connect (_jack_client, jack_port_name (_jack_port), (*x).c_str());
|
||||
}
|
||||
/* ignore failures */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_outbound_connections.empty()) {
|
||||
vector<string> ports;
|
||||
split (_outbound_connections, ports, ',');
|
||||
for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
|
||||
if (_jack_client) {
|
||||
jack_connect (_jack_client, jack_port_name (_jack_output_port), (*x).c_str());
|
||||
/* ignore failures */
|
||||
}
|
||||
}
|
||||
}
|
||||
connect_connection.disconnect ();
|
||||
}
|
||||
|
||||
@ -604,7 +501,7 @@ void
|
||||
Port::reestablish (void* jack)
|
||||
{
|
||||
_jack_client = static_cast<jack_client_t*> (jack);
|
||||
int const r = create_ports ();
|
||||
int const r = create_port ();
|
||||
|
||||
if (r) {
|
||||
PBD::error << "could not reregister ports for " << name() << endmsg;
|
||||
|
@ -124,7 +124,7 @@ void
|
||||
MIDIControllable::learn_about_external_control ()
|
||||
{
|
||||
drop_external_control ();
|
||||
_port.input()->any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
|
||||
_port.parser()->any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
void
|
||||
@ -268,7 +268,7 @@ MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/)
|
||||
|
||||
/* if the our port doesn't do input anymore, forget it ... */
|
||||
|
||||
if (!_port.input()) {
|
||||
if (!_port.parser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -288,11 +288,11 @@ MIDIControllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
|
||||
control_channel = chn;
|
||||
control_additional = additional;
|
||||
|
||||
if (_port.input() == 0) {
|
||||
if (_port.parser() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Parser& p = *_port.input();
|
||||
Parser& p = *_port.parser();
|
||||
|
||||
int chn_i = chn;
|
||||
switch (ev) {
|
||||
|
@ -127,11 +127,11 @@ MIDIInvokable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
|
||||
control_channel = chn;
|
||||
control_additional = additional;
|
||||
|
||||
if (_port.input() == 0) {
|
||||
if (_port.parser() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Parser& p = *_port.input();
|
||||
Parser& p = *_port.parser();
|
||||
|
||||
int chn_i = chn;
|
||||
|
||||
|
@ -563,11 +563,11 @@ MackieControlProtocol::connect_session_signals()
|
||||
}
|
||||
|
||||
void
|
||||
MackieControlProtocol::add_port (MIDI::Port & midi_port, int number)
|
||||
MackieControlProtocol::add_port (MIDI::Port & midi_input_port, MIDI::Port & midi_output_port, int number)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1\n", midi_port.name()));
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1 %2\n", midi_input_port.name(), midi_output_port.name()));
|
||||
|
||||
MackiePort * sport = new MackiePort (*this, midi_port, number);
|
||||
MackiePort * sport = new MackiePort (*this, midi_input_port, midi_output_port, number);
|
||||
_ports.push_back (sport);
|
||||
|
||||
sport->init_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
|
||||
@ -579,18 +579,19 @@ void
|
||||
MackieControlProtocol::create_ports()
|
||||
{
|
||||
MIDI::Manager * mm = MIDI::Manager::instance();
|
||||
MIDI::Port * midi_port = mm->add_port (new MIDI::Port (default_port_name, O_RDWR, session->engine().jack()));
|
||||
MIDI::Port * midi_input_port = mm->add_port (new MIDI::Port (default_port_name, MIDI::Port::IsInput, session->engine().jack()));
|
||||
MIDI::Port * midi_output_port = mm->add_port (new MIDI::Port (default_port_name, MIDI::Port::IsOutput, session->engine().jack()));
|
||||
|
||||
// open main port
|
||||
|
||||
if (!midi_port->ok()) {
|
||||
if (!midi_input_port->ok() || !midi_output_port->ok()) {
|
||||
ostringstream os;
|
||||
os << string_compose (_("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name);
|
||||
os << _("Mackie control MIDI ports could not be created; Mackie control disabled");
|
||||
error << os.str() << endmsg;
|
||||
throw MackieControlException (os.str());
|
||||
}
|
||||
|
||||
add_port (*midi_port, 0);
|
||||
add_port (*midi_input_port, *midi_output_port, 0);
|
||||
|
||||
// open extender ports. Up to 9. Should be enough.
|
||||
// could also use mm->get_midi_ports()
|
||||
@ -600,9 +601,10 @@ MackieControlProtocol::create_ports()
|
||||
for (int index = 1; index <= 9; ++index) {
|
||||
ostringstream os;
|
||||
os << ext_port_base << index;
|
||||
MIDI::Port * midi_port = mm->add_port (new MIDI::Port (os.str(), O_RDWR, session->engine().jack()));
|
||||
if (midi_port->ok()) {
|
||||
add_port (*midi_port, index);
|
||||
MIDI::Port * midi_input_port = mm->add_port (new MIDI::Port (os.str(), MIDI::Port::IsInput, session->engine().jack()));
|
||||
MIDI::Port * midi_output_port = mm->add_port (new MIDI::Port (os.str(), MIDI::Port::IsOutput, session->engine().jack()));
|
||||
if (midi_input_port->ok() && midi_output_port->ok()) {
|
||||
add_port (*midi_input_port, *midi_output_port, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ class MackieControlProtocol
|
||||
*/
|
||||
bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
|
||||
|
||||
void add_port(MIDI::Port &, int number);
|
||||
void add_port (MIDI::Port &, MIDI::Port &, int number);
|
||||
|
||||
/**
|
||||
Read session data and send to surface. Includes
|
||||
|
@ -48,12 +48,12 @@ MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
|
||||
// The MCU extender sysex header
|
||||
MidiByteArray mackie_sysex_hdr_xt ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x11 );
|
||||
|
||||
MackiePort::MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t port_type )
|
||||
: SurfacePort( port, number )
|
||||
, _mcp( mcp )
|
||||
, _port_type( port_type )
|
||||
, _emulation( none )
|
||||
, _initialising( true )
|
||||
MackiePort::MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t port_type)
|
||||
: SurfacePort (input_port, output_port, number)
|
||||
, _mcp( mcp )
|
||||
, _port_type( port_type )
|
||||
, _emulation( none )
|
||||
, _initialising( true )
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::MackiePort\n");
|
||||
}
|
||||
@ -91,7 +91,7 @@ void MackiePort::open()
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::open %1\n", *this));
|
||||
|
||||
port().input()->sysex.connect_same_thread (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
|
||||
input_port().parser()->sysex.connect_same_thread (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
|
||||
|
||||
// make sure the device is connected
|
||||
init();
|
||||
@ -147,7 +147,7 @@ MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
|
||||
{
|
||||
finalise_init( false );
|
||||
ostringstream os;
|
||||
os << "expecting 18 bytes, read " << bytes << " from " << port().name();
|
||||
os << "expecting 18 bytes, read " << bytes << " from " << input_port().name();
|
||||
throw MackieControlException( os.str() );
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & by
|
||||
{
|
||||
finalise_init( false );
|
||||
ostringstream os;
|
||||
os << "expecting 14 bytes, read " << bytes << " from " << port().name();
|
||||
os << "expecting 14 bytes, read " << bytes << " from " << input_port().name();
|
||||
throw MackieControlException( os.str() );
|
||||
}
|
||||
|
||||
@ -273,7 +273,7 @@ void MackiePort::finalise_init( bool yn )
|
||||
void MackiePort::connect_any()
|
||||
{
|
||||
if (!any_connection.connected()) {
|
||||
port().input()->any.connect_same_thread (any_connection, boost::bind (&MackiePort::handle_midi_any, this, _1, _2, _3));
|
||||
input_port().parser()->any.connect_same_thread (any_connection, boost::bind (&MackiePort::handle_midi_any, this, _1, _2, _3));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
enum port_type_t { mcu, ext };
|
||||
enum emulation_t { none, mackie, bcf2000 };
|
||||
|
||||
MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t = mcu );
|
||||
MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t = mcu);
|
||||
~MackiePort();
|
||||
|
||||
virtual void open();
|
||||
|
@ -36,12 +36,12 @@ using namespace std;
|
||||
using namespace Mackie;
|
||||
|
||||
SurfacePort::SurfacePort()
|
||||
: _port( 0 ), _number( 0 ), _active( false )
|
||||
: _input_port (0), _output_port (0), _number (0), _active (false)
|
||||
{
|
||||
}
|
||||
|
||||
SurfacePort::SurfacePort( MIDI::Port & port, int number )
|
||||
: _port( &port ), _number( number ), _active( false )
|
||||
SurfacePort::SurfacePort (MIDI::Port & input_port, MIDI::Port & output_port, int number)
|
||||
: _input_port (&input_port), _output_port (&output_port), _number (number), _active (false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ MidiByteArray SurfacePort::read()
|
||||
#endif
|
||||
|
||||
// read port and copy to return value
|
||||
int nread = port().read( buf, sizeof (buf) );
|
||||
int nread = input_port().read( buf, sizeof (buf) );
|
||||
|
||||
if (nread >= 0) {
|
||||
retval.copy( nread, buf );
|
||||
@ -107,7 +107,7 @@ MidiByteArray SurfacePort::read()
|
||||
if ( errno != EAGAIN )
|
||||
{
|
||||
ostringstream os;
|
||||
os << "Surface: error reading from port: " << port().name();
|
||||
os << "Surface: error reading from port: " << input_port().name();
|
||||
os << ": " << errno << fetch_errmsg( errno );
|
||||
|
||||
cout << os.str() << endl;
|
||||
@ -134,17 +134,17 @@ void SurfacePort::write( const MidiByteArray & mba )
|
||||
Glib::RecMutex::Lock lock( _rwlock );
|
||||
if ( !active() ) return;
|
||||
|
||||
int count = port().write( mba.bytes().get(), mba.size(), 0);
|
||||
int count = output_port().write( mba.bytes().get(), mba.size(), 0);
|
||||
if ( count != (int)mba.size() )
|
||||
{
|
||||
if ( errno == 0 )
|
||||
{
|
||||
cout << "port overflow on " << port().name() << ". Did not write all of " << mba << endl;
|
||||
cout << "port overflow on " << output_port().name() << ". Did not write all of " << mba << endl;
|
||||
}
|
||||
else if ( errno != EAGAIN )
|
||||
{
|
||||
ostringstream os;
|
||||
os << "Surface: couldn't write to port " << port().name();
|
||||
os << "Surface: couldn't write to port " << output_port().name();
|
||||
os << ", error: " << fetch_errmsg( errno ) << "(" << errno << ")";
|
||||
|
||||
cout << os.str() << endl;
|
||||
@ -173,7 +173,7 @@ void SurfacePort::write_sysex( MIDI::byte msg )
|
||||
ostream & Mackie::operator << ( ostream & os, const SurfacePort & port )
|
||||
{
|
||||
os << "{ ";
|
||||
os << "name: " << port.port().name();
|
||||
os << "name: " << port.input_port().name() << " " << port.output_port().name();
|
||||
os << "; ";
|
||||
os << " }";
|
||||
return os;
|
||||
|
@ -37,7 +37,7 @@ namespace Mackie
|
||||
class SurfacePort
|
||||
{
|
||||
public:
|
||||
SurfacePort( MIDI::Port & port, int number );
|
||||
SurfacePort (MIDI::Port & input_port, MIDI::Port & output_port, int number);
|
||||
virtual ~SurfacePort();
|
||||
|
||||
// when this is successful, active() should return true
|
||||
@ -60,8 +60,10 @@ public:
|
||||
/// return the correct sysex header for this port
|
||||
virtual const MidiByteArray & sysex_hdr() const = 0;
|
||||
|
||||
MIDI::Port & port() { return *_port; }
|
||||
const MIDI::Port & port() const { return *_port; }
|
||||
MIDI::Port & input_port() { return *_input_port; }
|
||||
const MIDI::Port & input_port() const { return *_input_port; }
|
||||
MIDI::Port & output_port() { return *_output_port; }
|
||||
const MIDI::Port & output_port() const { return *_output_port; }
|
||||
|
||||
// all control notofications are sent from here
|
||||
PBD::Signal3<void,SurfacePort &, Control &, const ControlState &> control_event;
|
||||
@ -90,7 +92,8 @@ protected:
|
||||
SurfacePort();
|
||||
|
||||
private:
|
||||
MIDI::Port * _port;
|
||||
MIDI::Port * _input_port;
|
||||
MIDI::Port * _output_port;
|
||||
int _number;
|
||||
bool _active;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user