summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-07-06 00:16:36 +0000
committerCarl Hetherington <carl@carlh.net>2010-07-06 00:16:36 +0000
commit91850f0eb4ab9f63bc6582d042d5495ea1968031 (patch)
treefb73d1ed43c228984cdd61c70f19d81e82f420a4 /libs
parentdc1e5d09a27180b35453b45edaeb0a117d1489f9 (diff)
Remove non-JACK midi++ ports.
git-svn-id: svn://localhost/ardour2/branches/3.0@7377 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/ticker.h5
-rw-r--r--libs/ardour/audioengine.cc10
-rw-r--r--libs/ardour/midi_clock_slave.cc1
-rw-r--r--libs/ardour/midi_ui.cc4
-rw-r--r--libs/ardour/session.cc4
-rw-r--r--libs/ardour/ticker.cc13
-rw-r--r--libs/midi++2/alsa_sequencer_midiport.cc429
-rw-r--r--libs/midi++2/coremidi_midiport.cc157
-rw-r--r--libs/midi++2/factory.cc128
-rw-r--r--libs/midi++2/fd_midiport.cc181
-rw-r--r--libs/midi++2/fifomidi.cc44
-rw-r--r--libs/midi++2/jack_midiport.cc433
-rw-r--r--libs/midi++2/manager.cc28
-rw-r--r--libs/midi++2/midi++/alsa_rawmidi.h52
-rw-r--r--libs/midi++2/midi++/alsa_sequencer.h76
-rw-r--r--libs/midi++2/midi++/coremidi_midiport.h79
-rw-r--r--libs/midi++2/midi++/factory.h43
-rw-r--r--libs/midi++2/midi++/fd_midiport.h91
-rw-r--r--libs/midi++2/midi++/fifomidi.h52
-rw-r--r--libs/midi++2/midi++/jack.h117
-rw-r--r--libs/midi++2/midi++/manager.h2
-rw-r--r--libs/midi++2/midi++/nullmidi.h68
-rw-r--r--libs/midi++2/midi++/port.h140
-rw-r--r--libs/midi++2/port.cc478
-rw-r--r--libs/midi++2/wscript14
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc22
-rw-r--r--libs/surfaces/mackie/surface_port.cc2
27 files changed, 504 insertions, 2169 deletions
diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h
index e133ad5d23..f5cda677ed 100644
--- a/libs/ardour/ardour/ticker.h
+++ b/libs/ardour/ardour/ticker.h
@@ -19,7 +19,6 @@
*/
-#include "midi++/jack.h"
#include "pbd/signals.h"
#include "ardour/types.h"
@@ -29,6 +28,10 @@
#ifndef TICKER_H_
#define TICKER_H_
+namespace MIDI {
+ class Port;
+}
+
namespace ARDOUR
{
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index b9ec8e465b..33a76fa7b4 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -32,7 +32,7 @@
#include "pbd/stacktrace.h"
#include "pbd/unknown_type.h"
-#include "midi++/jack.h"
+#include "midi++/port.h"
#include "midi++/mmc.h"
#include "midi++/manager.h"
@@ -147,7 +147,7 @@ _thread_init_callback (void * /*arg*/)
SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
- MIDI::JACK_MidiPort::set_process_thread (pthread_self());
+ MIDI::Port::set_process_thread (pthread_self());
MIDI::MachineControl::set_sending_thread (pthread_self ());
}
@@ -263,7 +263,7 @@ AudioEngine::stop (bool forever)
} else {
jack_deactivate (_priv_jack);
Stopped(); /* EMIT SIGNAL */
- MIDI::JACK_MidiPort::JackHalted (); /* EMIT SIGNAL */
+ MIDI::Port::JackHalted (); /* EMIT SIGNAL */
}
}
@@ -1074,7 +1074,7 @@ AudioEngine::halted (void *arg)
if (was_running) {
ae->Halted(""); /* EMIT SIGNAL */
- MIDI::JACK_MidiPort::JackHalted (); /* EMIT SIGNAL */
+ MIDI::Port::JackHalted (); /* EMIT SIGNAL */
}
}
@@ -1358,7 +1358,7 @@ AudioEngine::disconnect_from_jack ()
if (_running) {
_running = false;
Stopped(); /* EMIT SIGNAL */
- MIDI::JACK_MidiPort::JackHalted (); /* EMIT SIGNAL */
+ MIDI::Port::JackHalted (); /* EMIT SIGNAL */
}
return 0;
diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc
index c4ee65dd6b..a1682127d8 100644
--- a/libs/ardour/midi_clock_slave.cc
+++ b/libs/ardour/midi_clock_slave.cc
@@ -28,7 +28,6 @@
#include "pbd/pthread_utils.h"
#include "midi++/port.h"
-#include "midi++/jack.h"
#include "ardour/debug.h"
#include "ardour/slave.h"
diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc
index be13209513..5d9407d579 100644
--- a/libs/ardour/midi_ui.cc
+++ b/libs/ardour/midi_ui.cc
@@ -104,9 +104,7 @@ MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port)
if (ioc & IO_IN) {
- if (port->must_drain_selectable()) {
- CrossThreadChannel::drain (port->selectable());
- }
+ CrossThreadChannel::drain (port->selectable());
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", port->name()));
nframes64_t now = _session.engine().frame_time();
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 4fdcb6f5f9..dd6a453080 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -98,7 +98,7 @@
#include "ardour/utils.h"
#include "ardour/graph.h"
-#include "midi++/jack.h"
+#include "midi++/port.h"
#include "midi++/mmc.h"
#include "i18n.h"
@@ -645,7 +645,7 @@ Session::hookup_io ()
/* Tell all IO objects to connect themselves together */
IO::enable_connecting ();
- MIDI::JACK_MidiPort::MakeConnections ();
+ MIDI::Port::MakeConnections ();
/* Now reset all panners */
diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc
index dbe81ae32c..4327e25c72 100644
--- a/libs/ardour/ticker.cc
+++ b/libs/ardour/ticker.cc
@@ -18,6 +18,8 @@
$Id$
*/
+#include "midi++/port.h"
+#include "evoral/midi_events.h"
#include "ardour/ticker.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
@@ -138,9 +140,6 @@ void MidiClockTicker::tick(const nframes_t& transport_frames, const BBT_Time& /*
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0)
return;
- MIDI::JACK_MidiPort* jack_port = dynamic_cast<MIDI::JACK_MidiPort*>(_midi_port);
- assert(jack_port);
-
while (true) {
double next_tick = _last_tick + one_ppqn_in_frames(transport_frames);
nframes_t next_tick_offset = nframes_t(next_tick) - transport_frames;
@@ -150,11 +149,11 @@ void MidiClockTicker::tick(const nframes_t& transport_frames, const BBT_Time& /*
<< ":Last tick time:" << _last_tick << ":"
<< ":Next tick time:" << next_tick << ":"
<< "Offset:" << next_tick_offset << ":"
- << "cycle length:" << jack_port->nframes_this_cycle()
+ << "cycle length:" << _midi_port->nframes_this_cycle()
<< endl;
#endif
- if (next_tick_offset >= jack_port->nframes_this_cycle())
+ if (next_tick_offset >= _midi_port->nframes_this_cycle())
return;
send_midi_clock_event(next_tick_offset);
@@ -183,9 +182,7 @@ void MidiClockTicker::send_midi_clock_event(nframes_t offset)
return;
}
-#ifdef WITH_JACK_MIDI
- assert (MIDI::JACK_MidiPort::is_process_thread());
-#endif // WITH_JACK_MIDI
+ assert (MIDI::Port::is_process_thread());
#ifdef DEBUG_MIDI_CLOCK
cerr << "Tick with offset " << offset << endl;
#endif // DEBUG_MIDI_CLOCK
diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc
deleted file mode 100644
index 4a6dc6b3ea..0000000000
--- a/libs/midi++2/alsa_sequencer_midiport.cc
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- Copyright (C) 2004 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.
-
- $Id$
-*/
-
-#include <fcntl.h>
-#include <cerrno>
-
-#include "pbd/failed_constructor.h"
-#include "pbd/error.h"
-#include "pbd/xml++.h"
-
-#include "midi++/types.h"
-#include "midi++/alsa_sequencer.h"
-
-#include "i18n.h"
-
-//#define DOTRACE 1
-
-#ifdef DOTRACE
-#define TR_FN() (cerr << __FUNCTION__ << endl)
-#define TR_VAL(v) (cerr << __FILE__ " " << __LINE__ << " " #v "=" << v << endl)
-#else
-#define TR_FN()
-#define TR_VAL(v)
-#endif
-
-using namespace std;
-using namespace MIDI;
-using namespace PBD;
-
-snd_seq_t* ALSA_SequencerMidiPort::seq = 0;
-
-ALSA_SequencerMidiPort::ALSA_SequencerMidiPort (const XMLNode& node)
- : Port (node)
- , decoder (0)
- , encoder (0)
- , port_id (-1)
-{
- TR_FN();
- int err;
- Descriptor desc (node);
-
- if (!seq && init_client (desc.device) < 0) {
- _ok = false;
-
- } else {
-
- if (0 <= (err = create_ports (desc)) &&
- 0 <= (err = snd_midi_event_new (1024, &decoder)) && // Length taken from ARDOUR::Session::midi_read ()
- 0 <= (err = snd_midi_event_new (64, &encoder))) { // Length taken from ARDOUR::Session::mmc_buffer
- snd_midi_event_init (decoder);
- snd_midi_event_init (encoder);
- _ok = true;
- }
- }
-
- set_state (node);
-}
-
-ALSA_SequencerMidiPort::~ALSA_SequencerMidiPort ()
-{
- if (decoder) {
- snd_midi_event_free (decoder);
- }
- if (encoder) {
- snd_midi_event_free (encoder);
- }
- if (port_id >= 0) {
- snd_seq_delete_port (seq, port_id);
- }
-}
-
-int
-ALSA_SequencerMidiPort::selectable () const
-{
- struct pollfd pfd[1];
- if (0 <= snd_seq_poll_descriptors (seq, pfd, 1, POLLIN | POLLOUT)) {
- return pfd[0].fd;
- }
- return -1;
-}
-
-int
-ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t ignored)
-{
- TR_FN ();
- int R;
- int totwritten = 0;
- snd_midi_event_reset_encode (encoder);
- int nwritten = snd_midi_event_encode (encoder, msg, msglen, &SEv);
- TR_VAL (nwritten);
- while (0 < nwritten) {
- if (0 <= (R = snd_seq_event_output (seq, &SEv)) &&
- 0 <= (R = snd_seq_drain_output (seq))) {
- bytes_written += nwritten;
- totwritten += nwritten;
- if (output_parser) {
- output_parser->raw_preparse (*output_parser, msg, nwritten);
- for (int i = 0; i < nwritten; i++) {
- output_parser->scanner (msg[i]);
- }
- output_parser->raw_postparse (*output_parser, msg, nwritten);
- }
- } else {
- TR_VAL(R);
- return R;
- }
-
- msglen -= nwritten;
- msg += nwritten;
- if (msglen > 0) {
- nwritten = snd_midi_event_encode (encoder, msg, msglen, &SEv);
- TR_VAL(nwritten);
- }
- else {
- break;
- }
- }
-
- return totwritten;
-}
-
-int
-ALSA_SequencerMidiPort::read (byte *buf, size_t max)
-{
- TR_FN();
- int err;
- snd_seq_event_t *ev;
- if (0 <= (err = snd_seq_event_input (seq, &ev))) {
- TR_VAL(err);
- err = snd_midi_event_decode (decoder, buf, max, ev);
- }
-
- if (err > 0) {
- bytes_read += err;
-
- if (input_parser) {
- input_parser->raw_preparse (*input_parser, buf, err);
- for (int i = 0; i < err; i++) {
- input_parser->scanner (buf[i]);
- }
- input_parser->raw_postparse (*input_parser, buf, err);
- }
- }
- return -ENOENT == err ? 0 : err;
-}
-
-int
-ALSA_SequencerMidiPort::create_ports (const Port::Descriptor& desc)
-{
- int err;
- unsigned int caps = 0;
-
- if (desc.mode == O_WRONLY || desc.mode == O_RDWR)
- caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
- if (desc.mode == O_RDONLY || desc.mode == O_RDWR)
- caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
-
- if (0 <= (err = snd_seq_create_simple_port (seq, desc.tag.c_str(), caps,
- (SND_SEQ_PORT_TYPE_MIDI_GENERIC|
- SND_SEQ_PORT_TYPE_SOFTWARE|
- SND_SEQ_PORT_TYPE_APPLICATION)))) {
-
- port_id = err;
-
- snd_seq_ev_clear (&SEv);
- snd_seq_ev_set_source (&SEv, port_id);
- snd_seq_ev_set_subs (&SEv);
- snd_seq_ev_set_direct (&SEv);
-
- return 0;
- }
-
- return err;
-}
-
-int
-ALSA_SequencerMidiPort::init_client (std::string name)
-{
- static bool called = false;
-
- if (called) {
- return -1;
- }
-
- called = true;
-
- if (snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) >= 0) {
- snd_seq_set_client_name (seq, name.c_str());
- return 0;
- } else {
- warning << "The ALSA MIDI system is not available. No ports based on it will be created"
- << endmsg;
- return -1;
- }
-}
-
-int
-ALSA_SequencerMidiPort::discover (vector<PortSet>& ports)
-{
- int n = 0;
-
- snd_seq_client_info_t *client_info;
- snd_seq_port_info_t *port_info;
-
- snd_seq_client_info_alloca (&client_info);
- snd_seq_port_info_alloca (&port_info);
- snd_seq_client_info_set_client (client_info, -1);
-
- while (snd_seq_query_next_client(seq, client_info) >= 0) {
-
- int alsa_client;
-
- if ((alsa_client = snd_seq_client_info_get_client(client_info)) <= 0) {
- break;
- }
-
- snd_seq_port_info_set_client(port_info, alsa_client);
- snd_seq_port_info_set_port(port_info, -1);
-
- char client[256];
- snprintf (client, sizeof (client), "%d:%s", alsa_client, snd_seq_client_info_get_name(client_info));
-
- ports.push_back (PortSet (client));
-
- while (snd_seq_query_next_port(seq, port_info) >= 0) {
-
-#if 0
- int type = snd_seq_port_info_get_type(pinfo);
- if (!(type & SND_SEQ_PORT_TYPE_PORT)) {
- continue;
- }
-#endif
-
- unsigned int port_capability = snd_seq_port_info_get_capability(port_info);
-
- if ((port_capability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) {
-
- int alsa_port = snd_seq_port_info_get_port(port_info);
-
- char port[256];
- snprintf (port, sizeof (port), "%d:%s", alsa_port, snd_seq_port_info_get_name(port_info));
-
- std::string mode;
-
- if (port_capability & SND_SEQ_PORT_CAP_READ) {
- if (port_capability & SND_SEQ_PORT_CAP_WRITE) {
- mode = "duplex";
- } else {
- mode = "output";
- }
- } else if (port_capability & SND_SEQ_PORT_CAP_WRITE) {
- if (port_capability & SND_SEQ_PORT_CAP_READ) {
- mode = "duplex";
- } else {
- mode = "input";
- }
- }
-
- XMLNode node (X_("MIDI-port"));
- node.add_property ("device", client);
- node.add_property ("tag", port);
- node.add_property ("mode", mode);
- node.add_property ("type", "alsa/sequencer");
-
- ports.back().ports.push_back (node);
- ++n;
- }
- }
- }
-
- return n;
-}
-
-void
-ALSA_SequencerMidiPort::get_connections (vector<SequencerPortAddress>& connections, int dir) const
-{
- snd_seq_query_subscribe_t *subs;
- snd_seq_addr_t seq_addr;
-
- snd_seq_query_subscribe_alloca (&subs);
-
- // Get port connections...
-
- if (dir) {
- snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_WRITE);
- } else {
- snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_READ);
- }
-
- snd_seq_query_subscribe_set_index(subs, 0);
- seq_addr.client = snd_seq_client_id (seq);
- seq_addr.port = port_id;
- snd_seq_query_subscribe_set_root(subs, &seq_addr);
-
- while (snd_seq_query_port_subscribers(seq, subs) >= 0) {
-
- if (snd_seq_query_subscribe_get_time_real (subs)) {
- /* interesting connection */
-
- seq_addr = *snd_seq_query_subscribe_get_addr (subs);
-
- connections.push_back (SequencerPortAddress (seq_addr.client,
- seq_addr.port));
- }
-
- snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1);
- }
-}
-
-XMLNode&
-ALSA_SequencerMidiPort::get_state () const
-{
- XMLNode& root (Port::get_state ());
- vector<SequencerPortAddress> connections;
- XMLNode* sub = 0;
- char buf[256];
-
- get_connections (connections, 1);
-
- if (!connections.empty()) {
- if (!sub) {
- sub = new XMLNode (X_("connections"));
- }
- for (vector<SequencerPortAddress>::iterator i = connections.begin(); i != connections.end(); ++i) {
- XMLNode* cnode = new XMLNode (X_("read"));
- snprintf (buf, sizeof (buf), "%d:%d", i->first, i->second);
- cnode->add_property ("dest", buf);
- sub->add_child_nocopy (*cnode);
- }
- }
-
- connections.clear ();
- get_connections (connections, 0);
-
- if (!connections.empty()) {
- if (!sub) {
- sub = new XMLNode (X_("connections"));
- }
- for (vector<SequencerPortAddress>::iterator i = connections.begin(); i != connections.end(); ++i) {
- XMLNode* cnode = new XMLNode (X_("write"));
- snprintf (buf, sizeof (buf), "%d:%d", i->first, i->second);
- cnode->add_property ("dest", buf);
- sub->add_child_nocopy (*cnode);
- }
- }
-
- if (sub) {
- root.add_child_nocopy (*sub);
- }
-
- return root;
-}
-
-void
-ALSA_SequencerMidiPort::set_state (const XMLNode& node)
-{
- Port::set_state (node);
-
- XMLNodeList children (node.children());
- XMLNodeIterator iter;
-
- for (iter = children.begin(); iter != children.end(); ++iter) {
-
- if ((*iter)->name() == X_("connections")) {
-
- XMLNodeList gchildren ((*iter)->children());
- XMLNodeIterator gciter;
-
- for (gciter = gchildren.begin(); gciter != gchildren.end(); ++gciter) {
- XMLProperty* prop;
-
- if ((prop = (*gciter)->property ("dest")) != 0) {
- int client;
- int port;
-
- if (sscanf (prop->value().c_str(), "%d:%d", &client, &port) == 2) {
-
- snd_seq_port_subscribe_t *sub;
- snd_seq_addr_t seq_addr;
-
- snd_seq_port_subscribe_alloca(&sub);
-
- if ((*gciter)->name() == X_("write")) {
-
- seq_addr.client = snd_seq_client_id (seq);
- seq_addr.port = port_id;
- snd_seq_port_subscribe_set_sender(sub, &seq_addr);
-
- seq_addr.client = client;
- seq_addr.port = port;
- snd_seq_port_subscribe_set_dest(sub, &seq_addr);
-
- } else {
-
- seq_addr.client = snd_seq_client_id (seq);
- seq_addr.port = port_id;
- snd_seq_port_subscribe_set_dest(sub, &seq_addr);
-
- seq_addr.client = client;
- seq_addr.port = port;
- snd_seq_port_subscribe_set_sender(sub, &seq_addr);
- }
-
- snd_seq_subscribe_port (seq, sub);
- }
- }
- }
-
- break;
- }
- }
-}
diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc
deleted file mode 100644
index 4349ea45f4..0000000000
--- a/libs/midi++2/coremidi_midiport.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- Copyright (C) 2004 Paul Davis
- Copyright (C) 2004 Grame
-
- 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 <fcntl.h>
-#include <cerrno>
-
-#include "midi++/coremidi_midiport.h"
-#include "midi++/types.h"
-#include <mach/mach_time.h>
-
-#include "pbd/pthread_utils.h"
-
-using namespace std;
-using namespace MIDI;
-
-MIDITimeStamp CoreMidi_MidiPort::MIDIGetCurrentHostTime()
-{
- return mach_absolute_time();
-}
-
-CoreMidi_MidiPort::CoreMidi_MidiPort (const XMLNode& node) : Port (node)
-{
- Descriptor desc (node);
-
- firstrecv = true;
- int err;
- if (0 == (err = Open(desc))) {
- _ok = true;
- }
-}
-
-CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
-
-void CoreMidi_MidiPort::Close ()
-{
- if (midi_destination) MIDIEndpointDispose(midi_destination);
- if (midi_source) MIDIEndpointDispose(midi_source);
- if (midi_client) MIDIClientDispose(midi_client);
-}
-
-int CoreMidi_MidiPort::write (byte *msg, size_t msglen, timestamp_t ignored)
-{
- OSStatus err;
- MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
- MIDIPacket* packet = MIDIPacketListInit(pktlist);
- packet = MIDIPacketListAdd(pktlist,sizeof(midi_buffer),packet,MIDIGetCurrentHostTime(),msglen,msg);
-
- if (packet) {
-
- err = MIDIReceived(midi_source,pktlist);
- if (err != noErr) {
- //error << "MIDIReceived error" << err << endmsg.
- }
-
- bytes_written += msglen;
- return msglen;
- }else{
- return 0;
- }
-}
-
-int CoreMidi_MidiPort::Open (const Descriptor& desc)
-{
- OSStatus err;
- CFStringRef coutputStr;
- string str;
-
- coutputStr = CFStringCreateWithCString(0, desc.device.c_str(), CFStringGetSystemEncoding());
- err = MIDIClientCreate(coutputStr, 0, 0, &midi_client);
- CFRelease(coutputStr);
- if (!midi_client) {
- //error << "Cannot open CoreMidi client : " << err << endmsg.
- goto error;
- }
-
- str = desc.tag + string("_in");
- coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
- err = MIDIDestinationCreate(midi_client, coutputStr, read_proc, this, &midi_destination);
- CFRelease(coutputStr);
- if (!midi_destination) {
- //error << "Cannot create CoreMidi destination : " << err << endmsg.
- goto error;
- }
-
- str = desc.tag + string("_out");
- coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding());
- err = MIDISourceCreate(midi_client, coutputStr, &midi_source);
- CFRelease(coutputStr);
- if (!midi_source) {
- //error << "Cannot create CoreMidi source : " << err << endmsg.
- goto error;
- }
-
- return err;
-
-error:
- Close();
- return err;
-}
-
-void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
-{
- CoreMidi_MidiPort* driver = (CoreMidi_MidiPort*)refCon;
- MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
-
- if (driver->firstrecv) {
- driver->firstrecv = false;
- PBD::notify_gui_about_thread_creation ("gui", pthread_self(), "COREMIDI", 256);
- }
-
- for (unsigned int i = 0; i < pktlist->numPackets; ++i) {
-
- driver->bytes_read += packet->length;
-
- if (driver->input_parser) {
- //driver->input_parser->raw_preparse (*driver->input_parser, packet->data, packet->length);
-
- /* XXX This is technically the wrong timebase, since it is based on
- host time.
- */
- driver->input_parser->set_timestamp (packet->timestamp);
-
- for (int i = 0; i < packet->length; i++) {
- driver->input_parser->scanner (packet->data[i]);
- }
-
- //driver->input_parser->raw_postparse (*driver->input_parser, packet->data, packet->length);
- }
-
- packet = MIDIPacketNext(packet);
- }
-}
-
-int
-CoreMidi_MidiPort::discover (vector<PortSet>& ports)
-{
- /* XXX do dynamic port discovery here */
-
- return 0;
-}
diff --git a/libs/midi++2/factory.cc b/libs/midi++2/factory.cc
index 4c23a94671..73dfb6f69e 100644
--- a/libs/midi++2/factory.cc
+++ b/libs/midi++2/factory.cc
@@ -25,78 +25,13 @@
#include "midi++/types.h"
#include "midi++/factory.h"
-#include "midi++/fifomidi.h"
-#ifdef WITH_JACK_MIDI
#include "midi++/jack.h"
-std::string MIDI::JACK_MidiPort::typestring = "jack";
-#endif // WITH_JACK_MIDI
-
-std::string MIDI::FIFO_MidiPort::typestring = "fifo";
-
-#ifdef WITH_ALSA
-#include "midi++/alsa_sequencer.h"
-#include "midi++/alsa_rawmidi.h"
-
-std::string MIDI::ALSA_SequencerMidiPort::typestring = "alsa/sequencer";
-std::string MIDI::ALSA_RawMidiPort::typestring = "alsa/raw";
-
-#endif // WITH_ALSA
-
-#ifdef WITH_COREMIDI
-#include "midi++/coremidi_midiport.h"
-
-std::string MIDI::CoreMidi_MidiPort::typestring = "coremidi";
-
-#endif // WITH_COREMIDI
-
using namespace std;
using namespace MIDI;
using namespace PBD;
-// FIXME: void* data pointer, filthy
-Port *
-PortFactory::create_port (const XMLNode& node, void* data)
-
-{
- Port::Descriptor desc (node);
- Port *port;
-
- switch (desc.type) {
-#ifdef WITH_JACK_MIDI
- case Port::JACK_Midi:
- assert(data != NULL);
- port = new JACK_MidiPort (node, (jack_client_t*) data);
- break;
-#endif // WITH_JACK_MIDI
-
-#ifdef WITH_ALSA
- case Port::ALSA_RawMidi:
- port = new ALSA_RawMidiPort (node);
- break;
-
- case Port::ALSA_Sequencer:
- port = new ALSA_SequencerMidiPort (node);
- break;
-#endif // WITH_ALSA
-
-#ifdef WITH_COREMIDI
- case Port::CoreMidi_MidiPort:
- port = new CoreMidi_MidiPort (node);
- break;
-#endif // WITH_COREMIDI
-
- case Port::FIFO:
- port = new FIFO_MidiPort (node);
- break;
-
- default:
- return 0;
- }
-
- return port;
-}
bool
PortFactory::ignore_duplicate_devices (Port::Type type)
@@ -104,23 +39,10 @@ PortFactory::ignore_duplicate_devices (Port::Type type)
bool ret = false;
switch (type) {
-#ifdef WITH_ALSA
- case Port::ALSA_Sequencer:
- ret = true;
- break;
-#endif // WITH_ALSA
-#ifdef WITH_JACK_MIDI
case Port::JACK_Midi:
ret = true;
break;
-#endif // WITH_JACK_MIDI
-
-#ifdef WITH_COREMIDI
- case Port::CoreMidi_MidiPort:
- ret = true;
- break;
-#endif // WITH_COREMIDI
default:
break;
@@ -129,65 +51,17 @@ PortFactory::ignore_duplicate_devices (Port::Type type)
return ret;
}
-int
-#if defined (WITH_ALSA) || defined (WITH_COREMIDI)
-PortFactory::get_known_ports (vector<PortSet>& ports)
-#else
-PortFactory::get_known_ports (vector<PortSet>&)
-#endif
-{
- int n = 0;
-#ifdef WITH_ALSA
- n += ALSA_SequencerMidiPort::discover (ports);
-#endif // WITH_ALSA
-
-#ifdef WITH_COREMIDI
- n += CoreMidi_MidiPort::discover (ports);
-#endif // WITH_COREMIDI
-
- return n;
-}
-
std::string
PortFactory::default_port_type ()
{
-#ifdef WITH_JACK_MIDI
return "jack";
-#endif
-
-#ifdef WITH_ALSA
- return "alsa/sequencer";
-#endif
-
-#ifdef WITH_COREMIDI
- return "coremidi";
-#endif // WITH_COREMIDI
-
- PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg;
- /*NOTREACHED*/
- return "";
}
Port::Type
PortFactory::string_to_type (const string& xtype)
{
- if (0){
-#ifdef WITH_ALSA
- } else if (strings_equal_ignore_case (xtype, ALSA_RawMidiPort::typestring)) {
- return Port::ALSA_RawMidi;
- } else if (strings_equal_ignore_case (xtype, ALSA_SequencerMidiPort::typestring)) {
- return Port::ALSA_Sequencer;
-#endif
-#ifdef WITH_COREMIDI
- } else if (strings_equal_ignore_case (xtype, CoreMidi_MidiPort::typestring)) {
- return Port::CoreMidi_MidiPort;
-#endif
- } else if (strings_equal_ignore_case (xtype, FIFO_MidiPort::typestring)) {
- return Port::FIFO;
-#ifdef WITH_JACK_MIDI
- } else if (strings_equal_ignore_case (xtype, JACK_MidiPort::typestring)) {
+ if (strings_equal_ignore_case (xtype, JACK_MidiPort::typestring)) {
return Port::JACK_Midi;
-#endif
}
return Port::Unknown;
diff --git a/libs/midi++2/fd_midiport.cc b/libs/midi++2/fd_midiport.cc
deleted file mode 100644
index 9736d2b4da..0000000000
--- a/libs/midi++2/fd_midiport.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- Copyright (C) 1999 Paul Barton-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.
-
- $Id$
-*/
-
-#include <fcntl.h>
-#include <cerrno>
-#include <cstring>
-
-#include "pbd/error.h"
-#include "pbd/pathscanner.h"
-
-#include "midi++/types.h"
-#include "midi++/fd_midiport.h"
-
-using namespace std;
-using namespace MIDI;
-using namespace PBD;
-
-string *FD_MidiPort::midi_dirpath = 0;
-string *FD_MidiPort::midi_filename_pattern = 0;
-
-FD_MidiPort::FD_MidiPort (const XMLNode& node,
- const string &dirpath,
- const string &pattern)
- : Port (node)
-{
- Descriptor desc (node);
-
- open (desc);
-
- if (_fd < 0) {
- switch (errno) {
- case EBUSY:
- error << "MIDI: port device in use" << endmsg;
- break;
- case ENOENT:
- error << "MIDI: no such port device" << endmsg;
- break;
- case EACCES:
- error << "MIDI: access to port denied" << endmsg;
- break;
- default:
- break;
- }
- } else {
- _ok = true;
-
- if (midi_dirpath == 0) {
- midi_dirpath = new string (dirpath);
- midi_filename_pattern = new string (pattern);
- }
-
- if ((desc.mode & O_NONBLOCK) == 0) {
- /* we unconditionally set O_NONBLOCK during
- open, but the request didn't ask for it,
- so remove it.
- */
-
- int flags = fcntl (_fd, F_GETFL, 0);
- fcntl (_fd, F_SETFL, flags & ~(O_NONBLOCK));
- }
- }
-}
-
-void
-FD_MidiPort::open (const Descriptor& desc)
-
-{
- int mode = desc.mode | O_NONBLOCK;
- _fd = ::open (desc.device.c_str(), mode);
-}
-
-vector<string *> *
-FD_MidiPort::list_devices ()
-
-{
- PathScanner scanner;
-
- return scanner (*midi_dirpath, *midi_filename_pattern, false, true, false);
-}
-
-int
-FD_MidiPort::selectable () const
-
-{
- long flags;
-
- /* turn on non-blocking mode, since we plan to use select/poll
- to tell us when there is data to read.
- */
-
- flags = fcntl (_fd, F_GETFL);
- flags |= O_NONBLOCK;
-
- if (fcntl (_fd, F_SETFL, flags)) {
- error << "FD_MidiPort: could not turn on non-blocking mode"
- << " (" << strerror (errno)
- << ')'
- << endmsg;
-
- return -1;
- }
-
- return _fd;
-}
-
-
-int
-FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
-
-{
- size_t n;
- size_t i;
-
- for (n = 0; n < msglen; n++) {
-
- if (::write (_fd, &msg[n], 1) != 1) {
- break;
- }
-
- bytes_written++;
- for (i = 0; i < slowdown * 10000; i++) {}
- }
-
-
- if (n && output_parser) {
- output_parser->raw_preparse (*output_parser, msg, n);
- for (unsigned int i = 0; i < n; i++) {
- output_parser->scanner (msg[i]);
- }
- output_parser->raw_postparse (*output_parser, msg, n);
- }
-
- return n;
-}
-
-int
-FD_MidiPort::read (byte* buf, size_t max)
-{
- int nread;
-
- if ((_mode & O_ACCMODE) == O_WRONLY) {
- return -EACCES;
- }
-
- // cerr << "MIDI: read up to " << max << " from " << _fd << " (" << name() << ')' << endl;
-
- if ((nread = ::read (_fd, buf, max)) > 0) {
- bytes_read += nread;
-
- // cerr << " read " << nread << endl;
-
- if (input_parser) {
- input_parser->raw_preparse
- (*input_parser, buf, nread);
- for (int i = 0; i < nread; i++) {
- input_parser->scanner (buf[i]);
- }
- input_parser->raw_postparse
- (*input_parser, buf, nread);
- }
- }
-
- return nread;
-}
diff --git a/libs/midi++2/fifomidi.cc b/libs/midi++2/fifomidi.cc
deleted file mode 100644
index 3bf340f3d3..0000000000
--- a/libs/midi++2/fifomidi.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-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.
-
- $Id$
-*/
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "midi++/types.h"
-#include "midi++/fifomidi.h"
-
-using namespace MIDI;
-
-FIFO_MidiPort::FIFO_MidiPort (const XMLNode& node)
- : FD_MidiPort (node, ".", "midi")
-
-{
-}
-
-void
-FIFO_MidiPort::open (const Port::Descriptor& desc)
-
-{
- /* This is a placeholder for the fun-and-games I think we will
- need to do with FIFO's.
- */
-
- _fd = ::open (desc.device.c_str(), desc.mode|O_NDELAY);
-}
diff --git a/libs/midi++2/jack_midiport.cc b/libs/midi++2/jack_midiport.cc
deleted file mode 100644
index b55cf3adf6..0000000000
--- a/libs/midi++2/jack_midiport.cc
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- Copyright (C) 2006 Paul Davis
- Written by Dave Robillard
-
- 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 <fcntl.h>
-#include <cerrno>
-#include <cassert>
-#include <cstring>
-#include <cstdlib>
-
-#include "pbd/error.h"
-#include "pbd/compose.h"
-#include "pbd/strsplit.h"
-
-#include "midi++/types.h"
-#include "midi++/jack.h"
-
-using namespace std;
-using namespace MIDI;
-using namespace PBD;
-
-pthread_t JACK_MidiPort::_process_thread;
-
-Signal0<void> JACK_MidiPort::JackHalted;
-Signal0<void> JACK_MidiPort::MakeConnections;
-
-JACK_MidiPort::JACK_MidiPort(const XMLNode& node, jack_client_t* jack_client)
- : Port(node)
- , _jack_client(jack_client)
- , _jack_input_port(NULL)
- , _jack_output_port(NULL)
- , _last_read_index(0)
- , output_fifo (512)
- , input_fifo (1024)
-{
- if (!create_ports (node)) {
- _ok = true;
- }
-
- MakeConnections.connect_same_thread (connect_connection, boost::bind (&JACK_MidiPort::make_connections, this));
- JackHalted.connect_same_thread (halt_connection, boost::bind (&JACK_MidiPort::jack_halted, this));
-
- set_state (node);
-}
-
-JACK_MidiPort::~JACK_MidiPort()
-{
- if (_jack_input_port) {
- if (_jack_client) {
- jack_port_unregister (_jack_client, _jack_input_port);
- }
- _jack_input_port = 0;
- }
-
- if (_jack_output_port) {
- if (_jack_client) {
- jack_port_unregister (_jack_client, _jack_input_port);
- }
- _jack_input_port = 0;
- }
-}
-
-void
-JACK_MidiPort::jack_halted ()
-{
- _jack_client = 0;
- _jack_input_port = 0;
- _jack_output_port = 0;
-}
-
-void
-JACK_MidiPort::cycle_start (nframes_t nframes)
-{
- Port::cycle_start(nframes);
- assert(_nframes_this_cycle == 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);
- jack_midi_clear_buffer (buffer);
- flush (buffer);
- }
-
- if (_jack_input_port != 0) {
- // input
- void* jack_buffer = jack_port_get_buffer(_jack_input_port, nframes);
- const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
-
- jack_midi_event_t ev;
- timestamp_t cycle_start_frame = jack_last_frame_time (_jack_client);
-
- for (nframes_t i = 0; i < event_count; ++i) {
- jack_midi_event_get (&ev, jack_buffer, i);
- input_fifo.write (cycle_start_frame + ev.time, (Evoral::EventType) 0, ev.size, ev.buffer);
- }
-
- if (event_count) {
- xthread.wakeup ();
- }
- }
-}
-
-void
-JACK_MidiPort::cycle_end ()
-{
- if (_jack_output_port != 0) {
- flush (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle));
- }
-
- Port::cycle_end();
-}
-
-int
-JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
-{
- int ret = 0;
-
- if (!_jack_output_port) {
- return ret;
- }
-
- if (!is_process_thread()) {
-
- Glib::Mutex::Lock lm (output_fifo_lock);
- RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} };
-
- output_fifo.get_write_vector (&vec);
-
- if (vec.len[0] + vec.len[1] < 1) {
- error << "no space in FIFO for non-process thread MIDI write" << endmsg;
- return 0;
- }
-
- if (vec.len[0]) {
- if (!vec.buf[0]->owns_buffer()) {
- vec.buf[0]->set_buffer (0, 0, true);
- }
- vec.buf[0]->set (msg, msglen, timestamp);
- } else {
- if (!vec.buf[1]->owns_buffer()) {
- vec.buf[1]->set_buffer (0, 0, true);
- }
- vec.buf[1]->set (msg, msglen, timestamp);
- }
-
- output_fifo.increment_write_idx (1);
-
- ret = msglen;
-
- } else {
-
- // XXX This had to be temporarily commented out to make export work again
- if (!(timestamp < _nframes_this_cycle)) {
- std::cerr << "assertion timestamp < _nframes_this_cycle failed!" << std::endl;
- }
-
- if (_currently_in_cycle) {
- if (timestamp == 0) {
- timestamp = _last_write_timestamp;
- }
-
- if (jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle),
- timestamp, msg, msglen) == 0) {
- ret = msglen;
- _last_write_timestamp = 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))
- << endl;
- }
- } else {
- cerr << "write to JACK midi port failed: not currently in a process cycle." << endl;
- }
- }
-
- if (ret > 0 && output_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]);
- }
- // ardour doesn't care about this and neither should your app, probably
- // output_parser->raw_postparse (*output_parser, msg, ret);
- }
-
- return ret;
-}
-
-void
-JACK_MidiPort::flush (void* jack_port_buffer)
-{
- RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0 } };
- size_t written;
-
- output_fifo.get_read_vector (&vec);
-
- if (vec.len[0] + vec.len[1]) {
- // cerr << "Flush " << vec.len[0] + vec.len[1] << " events from non-process FIFO\n";
- }
-
- if (vec.len[0]) {
- Evoral::Event<double>* evp = vec.buf[0];
-
- for (size_t n = 0; n < vec.len[0]; ++n, ++evp) {
- jack_midi_event_write (jack_port_buffer,
- (timestamp_t) evp->time(), evp->buffer(), evp->size());
- }
- }
-
- if (vec.len[1]) {
- Evoral::Event<double>* evp = vec.buf[1];
-
- for (size_t n = 0; n < vec.len[1]; ++n, ++evp) {
- jack_midi_event_write (jack_port_buffer,
- (timestamp_t) evp->time(), evp->buffer(), evp->size());
- }
- }
-
- if ((written = vec.len[0] + vec.len[1]) != 0) {
- output_fifo.increment_read_idx (written);
- }
-}
-
-int
-JACK_MidiPort::read (byte *, size_t)
-{
- 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]);
- }
- }
- }
-
- return 0;
-}
-
-int
-JACK_MidiPort::create_ports(const XMLNode& node)
-{
- Descriptor desc (node);
-
- assert(!_jack_input_port);
- assert(!_jack_output_port);
-
- if (desc.mode == O_RDWR || desc.mode == O_WRONLY) {
- _jack_output_port_name = string(desc.tag).append ("_out");
- }
-
- if (desc.mode == O_RDWR || desc.mode == O_RDONLY) {
- _jack_input_port_name = string(desc.tag).append ("_in");
- }
-
- return create_ports ();
-}
-
-int
-JACK_MidiPort::create_ports ()
-{
- 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);
- }
-
- return ret ? 0 : -1;
-}
-
-XMLNode&
-JACK_MidiPort::get_state () const
-{
- XMLNode& root (Port::get_state ());
-
- if (_jack_output_port) {
-
- const char** jc = jack_port_get_connections (_jack_output_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 ("outbound", 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);
- }
- }
-
- return root;
-}
-
-void
-JACK_MidiPort::set_state (const XMLNode& node)
-{
- Port::set_state (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();
- }
-}
-
-void
-JACK_MidiPort::make_connections ()
-{
- if (!_inbound_connections.empty()) {
- vector<string> ports;
- split (_inbound_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));
- /* 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 ();
-}
-
-void
-JACK_MidiPort::set_process_thread (pthread_t thr)
-{
- _process_thread = thr;
-}
-
-bool
-JACK_MidiPort::is_process_thread()
-{
- return (pthread_self() == _process_thread);
-}
-
-void
-JACK_MidiPort::reestablish (void* jack)
-{
- _jack_client = static_cast<jack_client_t*> (jack);
- int const r = create_ports ();
-
- if (r) {
- PBD::error << "could not reregister ports for " << name() << endmsg;
- }
-}
-
-void
-JACK_MidiPort::reconnect ()
-{
- make_connections ();
-}
diff --git a/libs/midi++2/manager.cc b/libs/midi++2/manager.cc
index a84b5ab68a..5c464fa060 100644
--- a/libs/midi++2/manager.cc
+++ b/libs/midi++2/manager.cc
@@ -25,8 +25,8 @@
#include "midi++/types.h"
#include "midi++/manager.h"
-#include "midi++/factory.h"
#include "midi++/channel.h"
+#include "midi++/port.h"
using namespace std;
using namespace MIDI;
@@ -60,7 +60,6 @@ Port *
Manager::add_port (const XMLNode& node)
{
Port::Descriptor desc (node);
- PortFactory factory;
Port *port;
PortList::iterator p;
@@ -68,29 +67,15 @@ Manager::add_port (const XMLNode& node)
if (desc.tag == (*p)->name()) {
break;
- }
-
- if (!PortFactory::ignore_duplicate_devices (desc.type)) {
- if (desc.device == (*p)->device()) {
- /* If the existing is duplex, and this request
- is not, then fail, because most drivers won't
- allow opening twice with duplex and non-duplex
- operation.
- */
-
- if ((desc.mode == O_RDWR && (*p)->mode() != O_RDWR) ||
- (desc.mode != O_RDWR && (*p)->mode() == O_RDWR)) {
- break;
- }
- }
}
+
}
if (p != _ports.end()) {
return 0;
}
- port = factory.create_port (node, api_data);
+ port = new Port (node, (jack_client_t *) api_data);
if (port == 0) {
return 0;
@@ -228,13 +213,6 @@ Manager::cycle_end()
}
}
-
-int
-Manager::get_known_ports (vector<PortSet>& ports)
-{
- return PortFactory::get_known_ports (ports);
-}
-
/** Re-register ports that disappear on JACK shutdown */
void
Manager::reestablish (void* a)
diff --git a/libs/midi++2/midi++/alsa_rawmidi.h b/libs/midi++2/midi++/alsa_rawmidi.h
deleted file mode 100644
index 5c0c0ff0ea..0000000000
--- a/libs/midi++2/midi++/alsa_rawmidi.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-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.
-
-*/
-
-#ifndef __alsa_rawmidi_h__
-#define __alsa_rawmidi_h__
-
-#include <vector>
-#include <string>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "midi++/port.h"
-#include "midi++/fd_midiport.h"
-
-namespace MIDI {
-
-class ALSA_RawMidiPort : public MIDI::FD_MidiPort
-
-{
- public:
- ALSA_RawMidiPort (const XMLNode& node)
- : FD_MidiPort (node, "/dev/snd", "midi") {}
- virtual ~ALSA_RawMidiPort () {}
-
- static std::string typestring;
-
- protected:
- std::string get_typestring () const {
- return typestring;
- }
-};
-
-}
-
-#endif // __alsa_rawmidi_h__
-
diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h
deleted file mode 100644
index 889dd972b8..0000000000
--- a/libs/midi++2/midi++/alsa_sequencer.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (C) 2004 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.
-
-*/
-
-#ifndef __alsa_sequencer_midiport_h__
-#define __alsa_sequencer_midiport_h__
-
-#include <vector>
-#include <string>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <alsa/asoundlib.h>
-#include "midi++/port.h"
-
-namespace MIDI {
-
-class ALSA_SequencerMidiPort : public Port
-
-{
- public:
- ALSA_SequencerMidiPort (const XMLNode&);
- virtual ~ALSA_SequencerMidiPort ();
-
- int write (byte *msg, size_t msglen, timestamp_t timestamp);
- int read (byte *buf, size_t max);
-
- /* select(2)/poll(2)-based I/O */
-
- virtual int selectable() const;
-
- static int discover (std::vector<PortSet>&);
- static std::string typestring;
-
- XMLNode& get_state() const;
- void set_state (const XMLNode&);
-
- protected:
-
- std::string get_typestring () const {
- return typestring;
- }
-
- private:
- snd_midi_event_t *decoder, *encoder;
- int port_id;
- snd_seq_event_t SEv;
-
- int create_ports (const Port::Descriptor&);
-
- static int init_client (std::string name);
- static snd_seq_t* seq;
-
- typedef std::pair<int,int> SequencerPortAddress;
- void get_connections (std::vector<SequencerPortAddress>&, int dir) const;
-};
-
-}; /* namespace MIDI */
-
-#endif // __alsa_sequencer_midiport_h__
-
diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h
deleted file mode 100644
index 74207238ad..0000000000
--- a/libs/midi++2/midi++/coremidi_midiport.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Copyright (C) 2004 Paul Davis
- Copyright (C) 2004 Grame
- 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.
-
- */
-
-#ifndef __coremidi_midiport_h__
-#define __coremidi_midiport_h__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "midi++/port.h"
-
-#include <CoreMIDI/CoreMIDI.h>
-
-namespace MIDI {
-
- class CoreMidi_MidiPort:public Port {
- public:
- CoreMidi_MidiPort(const XMLNode& node);
- virtual ~ CoreMidi_MidiPort();
-
- int write (byte * msg, size_t msglen, timestamp_t timestamp);
- int read (byte * buf, size_t max) {
- return 0;
- }
-
- virtual int selectable() const {
- return -1;
- }
-
- static int discover (std::vector<PortSet>&);
- static std::string typestring;
-
- protected:
-
- /* CoreMidi callback */
- static void read_proc(const MIDIPacketList * pktlist,
- void *refCon, void *connRefCon);
-
- std::string get_typestring () const {
- return typestring;
- }
-
- private:
- byte midi_buffer[1024];
- MIDIClientRef midi_client;
- MIDIEndpointRef midi_destination;
- MIDIEndpointRef midi_source;
-
- int Open(const Port::Descriptor&);
- void Close();
- static MIDITimeStamp MIDIGetCurrentHostTime();
-
- bool firstrecv;
-
- };
-
-} // namespace MIDI
-
-#endif // __coremidi_midiport_h__
diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h
deleted file mode 100644
index 3f130c41a7..0000000000
--- a/libs/midi++2/midi++/factory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-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.
-
-*/
-
-#ifndef __midi_factory_h__
-#define __midi_factory_h__
-
-#include <vector>
-#include <string>
-
-#include "midi++/port.h"
-
-namespace MIDI {
-
-class PortFactory {
- public:
- Port *create_port (const XMLNode&, void* data);
-
- static bool ignore_duplicate_devices (Port::Type);
- static int get_known_ports (std::vector<PortSet>&);
- static std::string default_port_type ();
- static Port::Type string_to_type (const std::string&);
- static std::string mode_to_string (int);
- static int string_to_mode (const std::string&);
-};
-
-} // namespace MIDI
-
-#endif // __midi_factory_h__
diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h
deleted file mode 100644
index 673037cc5d..0000000000
--- a/libs/midi++2/midi++/fd_midiport.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 1999 Paul Barton-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.
-
-*/
-
-#ifndef __fd_midiport_h__
-#define __fd_midiport_h__
-
-#include <vector>
-#include <string>
-#include <cerrno>
-
-#include <cerrno>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "midi++/port.h"
-
-namespace MIDI {
-
-class FD_MidiPort : public Port
-
-{
- public:
- FD_MidiPort (const XMLNode& node,
- const std::string &dirpath,
- const std::string &pattern);
-
- virtual ~FD_MidiPort () {
- ::close (_fd);
- }
-
- virtual int selectable() const;
-
- static std::vector<std::string *> *list_devices ();
-
- protected:
- int _fd;
- virtual void open (const Port::Descriptor&);
-
- virtual int write (byte *msg, size_t msglen, timestamp_t) {
- int nwritten;
-
- if ((_mode & O_ACCMODE) == O_RDONLY) {
- return -EACCES;
- }
-
- if (slowdown) {
- return do_slow_write (msg, msglen);
- }
-
- if ((nwritten = ::write (_fd, msg, msglen)) > 0) {
- bytes_written += nwritten;
-
- if (output_parser) {
- output_parser->raw_preparse (*output_parser, msg, nwritten);
- for (int i = 0; i < nwritten; i++) {
- output_parser->scanner (msg[i]);
- }
- output_parser->raw_postparse (*output_parser, msg, nwritten);
- }
- }
- return nwritten;
- }
-
- int read (byte *buf, size_t max);
-
- private:
- static std::string *midi_dirpath;
- static std::string *midi_filename_pattern;
-
- int do_slow_write (byte *msg, unsigned int msglen);
-};
-
-} // namespace MIDI
-
-#endif // __fd_midiport_h__
diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h
deleted file mode 100644
index 022d055d92..0000000000
--- a/libs/midi++2/midi++/fifomidi.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-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.
-
-*/
-
-#ifndef __fifomidi_h__
-#define __fifomidi_h__
-
-#include <fcntl.h>
-#include <vector>
-#include <string>
-#include <unistd.h>
-
-#include "midi++/port.h"
-#include "midi++/fd_midiport.h"
-
-namespace MIDI {
-
-class FIFO_MidiPort : public MIDI::FD_MidiPort
-
-{
- public:
- FIFO_MidiPort (const XMLNode&);
- ~FIFO_MidiPort () {};
-
- static std::string typestring;
-
- protected:
- std::string get_typestring () const {
- return typestring;
- }
-
- private:
- void open (const Port::Descriptor&);
-};
-
-} // namespace MIDI
-
-#endif // __fifomidi_h__
diff --git a/libs/midi++2/midi++/jack.h b/libs/midi++2/midi++/jack.h
deleted file mode 100644
index 099bc4e639..0000000000
--- a/libs/midi++2/midi++/jack.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Copyright (C) 2006 Paul Davis
- Written by Dave Robillard
-
- 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.
-
- $Id: jack.h 4 2005-05-13 20:47:18Z taybin $
-*/
-
-#ifndef __jack_midiport_h__
-#define __jack_midiport_h__
-
-#include <vector>
-#include <string>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <glibmm/thread.h>
-
-#include <jack/weakjack.h>
-#include <jack/jack.h>
-#include <jack/midiport.h>
-
-#include "pbd/ringbuffer.h"
-#include "pbd/signals.h"
-#include "pbd/crossthread.h"
-#include "evoral/EventRingBuffer.hpp"
-
-#include "midi++/port.h"
-#include "midi++/event.h"
-
-namespace MIDI
-{
-
-class JACK_MidiPort : public Port
-{
-public:
- JACK_MidiPort (const XMLNode& node, jack_client_t* jack_client);
- virtual ~JACK_MidiPort ();
-
- int write(byte *msg, size_t msglen, timestamp_t timestamp);
- int read(byte *buf, size_t max);
-
- int selectable() const { return xthread.selectable(); }
- bool must_drain_selectable() const { return true; }
-
- void cycle_start(nframes_t nframes);
- void cycle_end();
-
- static std::string typestring;
-
- XMLNode& get_state () const;
- void set_state (const XMLNode&);
-
- static void set_process_thread (pthread_t);
- static pthread_t get_process_thread () { return _process_thread; }
- static bool is_process_thread();
-
- nframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
-
- void reestablish (void *);
- void reconnect ();
-
- static PBD::Signal0<void> MakeConnections;
- static PBD::Signal0<void> JackHalted;
-
- protected:
- std::string get_typestring () const {
- return typestring;
- }
-
-private:
- int create_ports(const XMLNode&);
- int create_ports ();
-
- 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;
- nframes_t _last_read_index;
- timestamp_t _last_write_timestamp;
- CrossThreadChannel xthread;
- std::string _inbound_connections;
- std::string _outbound_connections;
- PBD::ScopedConnection connect_connection;
- PBD::ScopedConnection halt_connection;
- void flush (void* jack_port_buffer);
- void jack_halted ();
- void make_connections();
-
- static pthread_t _process_thread;
-
- RingBuffer< Evoral::Event<double> > output_fifo;
- Evoral::EventRingBuffer<timestamp_t> input_fifo;
-
- Glib::Mutex output_fifo_lock;
-};
-
-
-} /* namespace MIDI */
-
-#endif // __jack_midiport_h__
-
diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h
index 33835a05bf..563062aaea 100644
--- a/libs/midi++2/midi++/manager.h
+++ b/libs/midi++2/midi++/manager.h
@@ -81,8 +81,6 @@ class Manager {
return theManager;
}
- int get_known_ports (std::vector<PortSet>&);
-
void reestablish (void *);
void reconnect ();
diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h
deleted file mode 100644
index 0ed221a78d..0000000000
--- a/libs/midi++2/midi++/nullmidi.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-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.
-
-*/
-
-#ifndef __nullmidi_h__
-#define __nullmidi_h__
-
-#include <fcntl.h>
-#include <vector>
-#include <string>
-
-#include "midi++/port.h"
-
-namespace MIDI {
-
-class Null_MidiPort : public Port
-
-{
- public:
- Null_MidiPort (PortRequest &req)
- : Port (req) {
-
- /* reset devname and tagname */
-
- _devname = "nullmidi";
- _tagname = "null";
- _type = Port::Null;
- _ok = true;
- }
-
- virtual ~Null_MidiPort () {};
-
- /* Direct I/O */
- int write (byte *msg, size_t msglen, timestamp_t timestamp) {
- return msglen;
- }
-
- int read (byte *buf, size_t max) {
- return 0;
- }
-
- virtual int selectable() const { return -1; }
-
- static std::string typestring;
-
- protected:
- std::string get_typestring () const {
- return typestring;
- }
-};
-
-} // namespace MIDI
-
-#endif // __nullmidi_h__
diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h
index c45f5ba2fc..8c875a6615 100644
--- a/libs/midi++2/midi++/port.h
+++ b/libs/midi++2/midi++/port.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1998-99 Paul Barton-Davis
+ Copyright (C) 1998-2010 Paul Barton-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
@@ -22,7 +22,15 @@
#include <string>
#include <iostream>
+#include <jack/types.h>
+
#include "pbd/xml++.h"
+#include "pbd/crossthread.h"
+#include "pbd/signals.h"
+#include "pbd/ringbuffer.h"
+
+#include "evoral/Event.hpp"
+#include "evoral/EventRingBuffer.hpp"
#include "midi++/types.h"
#include "midi++/parser.h"
@@ -34,29 +42,18 @@ class PortRequest;
class Port {
public:
- enum Type {
- Unknown,
- JACK_Midi,
- ALSA_RawMidi,
- ALSA_Sequencer,
- CoreMidi_MidiPort,
- Null,
- FIFO
- };
-
+ Port (const XMLNode&, jack_client_t *);
+ ~Port ();
- Port (const XMLNode&);
- virtual ~Port ();
-
- virtual XMLNode& get_state () const;
- virtual void set_state (const XMLNode&);
+ XMLNode& get_state () const;
+ void set_state (const XMLNode&);
// FIXME: make Manager a friend of port so these can be hidden?
/* Only for use by MidiManager. Don't ever call this. */
- virtual void cycle_start(nframes_t nframes);
+ void cycle_start(nframes_t nframes);
/* Only for use by MidiManager. Don't ever call this. */
- virtual void cycle_end();
+ void cycle_end();
/** Write a message to port.
* @param msg Raw MIDI message to send
@@ -64,14 +61,14 @@ class Port {
* @param timestamp Time stamp in frames of this message (relative to cycle start)
* @return number of bytes successfully written
*/
- virtual int write (byte *msg, size_t msglen, timestamp_t timestamp) = 0;
+ int write (byte *msg, size_t msglen, timestamp_t timestamp);
/** Read raw bytes from a port.
* @param buf memory to store read data in
* @param bufsize size of @a buf
* @return number of bytes successfully read, negative if error
*/
- virtual int read (byte *buf, size_t bufsize) = 0;
+ int read (byte *buf, size_t bufsize);
void parse (nframes_t timestamp);
@@ -83,103 +80,90 @@ class Port {
return !(write (msg, len, timestamp) == (int) len);
}
- int three_byte_msg (byte a, byte b, byte c, timestamp_t timestamp) {
- byte msg[3];
-
- msg[0] = a;
- msg[1] = b;
- msg[2] = c;
-
- return !(write (msg, 3, timestamp) == 3);
- }
-
bool clock (timestamp_t timestamp);
-
- /* slowdown i/o to a loop of single byte emissions
- interspersed with a busy loop of 10000 * this value.
-
- This may be ignored by a particular instance
- of this virtual class. See FD_MidiPort for an
- example of where it used.
- */
-
- void set_slowdown (size_t n) { slowdown = n; }
/* select(2)/poll(2)-based I/O */
/** Get the file descriptor for port.
* @return File descriptor, or -1 if not selectable.
*/
- virtual int selectable() const = 0;
- virtual bool must_drain_selectable() const { return false; }
+ int selectable () const {
+ return xthread.selectable();
+ }
- static void gtk_read_callback (void *ptr, int fd, int cond);
- static void write_callback (byte *msg, unsigned int len, void *);
-
Channel *channel (channel_t chn) {
return _channel[chn&0x7F];
}
Parser *input() { return input_parser; }
Parser *output() { return output_parser; }
-
- void iostat (int *written, int *read,
- const size_t **in_counts,
- const size_t **out_counts) {
-
- *written = bytes_written;
- *read = bytes_read;
- if (input_parser) {
- *in_counts = input_parser->message_counts();
- } else {
- *in_counts = 0;
- }
- if (output_parser) {
- *out_counts = output_parser->message_counts();
- } else {
- *out_counts = 0;
- }
- }
- const char *device () const { return _devname.c_str(); }
const char *name () const { return _tagname.c_str(); }
- Type type () const { return _type; }
int mode () const { return _mode; }
bool ok () const { return _ok; }
struct Descriptor {
std::string tag;
- std::string device;
int mode;
- Port::Type type;
Descriptor (const XMLNode&);
XMLNode& get_state();
};
- virtual void reestablish (void *) {}
- virtual void reconnect () {}
+ nframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
- protected:
+ void reestablish (void *);
+ void reconnect ();
+
+ static void set_process_thread (pthread_t);
+ static pthread_t get_process_thread () { return _process_thread; }
+ static bool is_process_thread();
+
+ static PBD::Signal0<void> MakeConnections;
+ static PBD::Signal0<void> JackHalted;
+
+private:
bool _ok;
bool _currently_in_cycle;
nframes_t _nframes_this_cycle;
- Type _type;
- std::string _devname;
std::string _tagname;
int _mode;
size_t _number;
Channel *_channel[16];
- unsigned int bytes_written;
- unsigned int bytes_read;
Parser *input_parser;
Parser *output_parser;
- size_t slowdown;
-
- virtual std::string get_typestring () const = 0;
- private:
static size_t nports;
+
+ int create_ports(const XMLNode&);
+ int create_ports ();
+
+ 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;
+ 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;
+ PBD::ScopedConnection connect_connection;
+ PBD::ScopedConnection halt_connection;
+ void flush (void* jack_port_buffer);
+ void jack_halted ();
+ void make_connections();
+
+ static pthread_t _process_thread;
+
+ RingBuffer< Evoral::Event<double> > output_fifo;
+ Evoral::EventRingBuffer<timestamp_t> input_fifo;
+
+ Glib::Mutex output_fifo_lock;
+
};
struct PortSet {
diff --git a/libs/midi++2/port.cc b/libs/midi++2/port.cc
index 6694249b61..457ff1c358 100644
--- a/libs/midi++2/port.cc
+++ b/libs/midi++2/port.cc
@@ -22,24 +22,37 @@
#include <fcntl.h>
#include <errno.h>
+#include <jack/jack.h>
+#include <jack/midiport.h>
+
#include "pbd/xml++.h"
#include "pbd/error.h"
#include "pbd/failed_constructor.h"
+#include "pbd/convert.h"
+#include "pbd/strsplit.h"
#include "midi++/types.h"
#include "midi++/port.h"
#include "midi++/channel.h"
-#include "midi++/factory.h"
using namespace MIDI;
using namespace std;
using namespace PBD;
size_t Port::nports = 0;
-
-Port::Port (const XMLNode& node)
- : _currently_in_cycle(false)
- , _nframes_this_cycle(0)
+pthread_t Port::_process_thread;
+Signal0<void> Port::JackHalted;
+Signal0<void> Port::MakeConnections;
+
+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)
+ , _last_read_index (0)
+ , output_fifo (512)
+ , input_fifo (1024)
{
Descriptor desc (node);
@@ -47,13 +60,9 @@ Port::Port (const XMLNode& node)
succeeds.
*/
- bytes_written = 0;
- bytes_read = 0;
input_parser = 0;
output_parser = 0;
- slowdown = 0;
- _devname = desc.device;
_tagname = desc.tag;
_mode = desc.mode;
@@ -80,6 +89,15 @@ Port::Port (const XMLNode& node)
_channel[i]->connect_output_signals ();
}
}
+
+ if (!create_ports (node)) {
+ _ok = true;
+ }
+
+ MakeConnections.connect_same_thread (connect_connection, boost::bind (&Port::make_connections, this));
+ JackHalted.connect_same_thread (halt_connection, boost::bind (&Port::jack_halted, this));
+
+ set_state (node);
}
@@ -88,6 +106,20 @@ Port::~Port ()
for (int i = 0; i < 16; i++) {
delete _channel[i];
}
+
+ if (_jack_input_port) {
+ if (_jack_client) {
+ jack_port_unregister (_jack_client, _jack_input_port);
+ }
+ _jack_input_port = 0;
+ }
+
+ if (_jack_output_port) {
+ if (_jack_client) {
+ jack_port_unregister (_jack_client, _jack_input_port);
+ }
+ _jack_input_port = 0;
+ }
}
void
@@ -149,24 +181,293 @@ Port::cycle_start (nframes_t nframes)
{
_currently_in_cycle = true;
_nframes_this_cycle = nframes;
+
+ assert(_nframes_this_cycle == 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);
+ jack_midi_clear_buffer (buffer);
+ flush (buffer);
+ }
+
+ if (_jack_input_port != 0) {
+ // input
+ void* jack_buffer = jack_port_get_buffer(_jack_input_port, nframes);
+ const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
+
+ jack_midi_event_t ev;
+ timestamp_t cycle_start_frame = jack_last_frame_time (_jack_client);
+
+ for (nframes_t i = 0; i < event_count; ++i) {
+ jack_midi_event_get (&ev, jack_buffer, i);
+ input_fifo.write (cycle_start_frame + ev.time, (Evoral::EventType) 0, ev.size, ev.buffer);
+ }
+
+ if (event_count) {
+ xthread.wakeup ();
+ }
+ }
}
void
Port::cycle_end ()
{
+ if (_jack_output_port != 0) {
+ flush (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle));
+ }
+
_currently_in_cycle = false;
_nframes_this_cycle = 0;
}
-XMLNode&
+std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
+{
+ using namespace std;
+ os << "MIDI::Port { ";
+ os << "name: " << port.name();
+ os << "; ";
+ os << "mode: " << port.mode();
+ os << "; ";
+ os << "ok: " << port.ok();
+ os << "; ";
+ os << " }";
+ return os;
+}
+
+Port::Descriptor::Descriptor (const XMLNode& node)
+{
+ const XMLProperty *prop;
+ bool have_tag = false;
+ bool have_mode = false;
+
+ if ((prop = node.property ("tag")) != 0) {
+ tag = prop->value();
+ have_tag = true;
+ }
+
+ 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;
+ } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
+ mode = O_RDONLY;
+ }
+
+ have_mode = true;
+ }
+
+ if (!have_tag || !have_mode) {
+ throw failed_constructor();
+ }
+}
+
+void
+Port::jack_halted ()
+{
+ _jack_client = 0;
+ _jack_input_port = 0;
+ _jack_output_port = 0;
+}
+
+int
+Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
+{
+ int ret = 0;
+
+ if (!_jack_output_port) {
+ return ret;
+ }
+
+ if (!is_process_thread()) {
+
+ Glib::Mutex::Lock lm (output_fifo_lock);
+ RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} };
+
+ output_fifo.get_write_vector (&vec);
+
+ if (vec.len[0] + vec.len[1] < 1) {
+ error << "no space in FIFO for non-process thread MIDI write" << endmsg;
+ return 0;
+ }
+
+ if (vec.len[0]) {
+ if (!vec.buf[0]->owns_buffer()) {
+ vec.buf[0]->set_buffer (0, 0, true);
+ }
+ vec.buf[0]->set (msg, msglen, timestamp);
+ } else {
+ if (!vec.buf[1]->owns_buffer()) {
+ vec.buf[1]->set_buffer (0, 0, true);
+ }
+ vec.buf[1]->set (msg, msglen, timestamp);
+ }
+
+ output_fifo.increment_write_idx (1);
+
+ ret = msglen;
+
+ } else {
+
+ // XXX This had to be temporarily commented out to make export work again
+ if (!(timestamp < _nframes_this_cycle)) {
+ std::cerr << "assertion timestamp < _nframes_this_cycle failed!" << std::endl;
+ }
+
+ if (_currently_in_cycle) {
+ if (timestamp == 0) {
+ timestamp = _last_write_timestamp;
+ }
+
+ if (jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle),
+ timestamp, msg, msglen) == 0) {
+ ret = msglen;
+ _last_write_timestamp = 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))
+ << endl;
+ }
+ } else {
+ cerr << "write to JACK midi port failed: not currently in a process cycle." << endl;
+ }
+ }
+
+ if (ret > 0 && output_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]);
+ }
+ // ardour doesn't care about this and neither should your app, probably
+ // output_parser->raw_postparse (*output_parser, msg, ret);
+ }
+
+ return ret;
+}
+
+void
+Port::flush (void* jack_port_buffer)
+{
+ RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0 } };
+ size_t written;
+
+ output_fifo.get_read_vector (&vec);
+
+ if (vec.len[0] + vec.len[1]) {
+ // cerr << "Flush " << vec.len[0] + vec.len[1] << " events from non-process FIFO\n";
+ }
+
+ if (vec.len[0]) {
+ Evoral::Event<double>* evp = vec.buf[0];
+
+ for (size_t n = 0; n < vec.len[0]; ++n, ++evp) {
+ jack_midi_event_write (jack_port_buffer,
+ (timestamp_t) evp->time(), evp->buffer(), evp->size());
+ }
+ }
+
+ if (vec.len[1]) {
+ Evoral::Event<double>* evp = vec.buf[1];
+
+ for (size_t n = 0; n < vec.len[1]; ++n, ++evp) {
+ jack_midi_event_write (jack_port_buffer,
+ (timestamp_t) evp->time(), evp->buffer(), evp->size());
+ }
+ }
+
+ if ((written = vec.len[0] + vec.len[1]) != 0) {
+ output_fifo.increment_read_idx (written);
+ }
+}
+
+int
+Port::read (byte *, size_t)
+{
+ 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]);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+Port::create_ports(const XMLNode& node)
+{
+ Descriptor desc (node);
+
+ assert(!_jack_input_port);
+ assert(!_jack_output_port);
+
+ if (desc.mode == O_RDWR || desc.mode == O_WRONLY) {
+ _jack_output_port_name = string(desc.tag).append ("_out");
+ }
+
+ if (desc.mode == O_RDWR || desc.mode == O_RDONLY) {
+ _jack_input_port_name = string(desc.tag).append ("_in");
+ }
+
+ return create_ports ();
+}
+
+int
+Port::create_ports ()
+{
+ 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);
+ }
+
+ return ret ? 0 : -1;
+}
+
+XMLNode&
Port::get_state () const
{
- XMLNode* node = new XMLNode ("MIDI-port");
- node->add_property ("tag", _tagname);
- node->add_property ("device", _devname);
- node->add_property ("mode", PortFactory::mode_to_string (_mode));
- node->add_property ("type", get_typestring());
+ XMLNode* root = new XMLNode ("MIDI-port");
+ root->add_property ("tag", _tagname);
+ if (_mode == O_RDONLY) {
+ root->add_property ("mode", "input");
+ } else if (_mode == O_WRONLY) {
+ root->add_property ("mode", "output");
+ } else {
+ root->add_property ("mode", "duplex");
+ }
+
#if 0
byte device_inquiry[6];
@@ -180,76 +481,121 @@ Port::get_state () const
write (device_inquiry, sizeof (device_inquiry), 0);
#endif
- return *node;
+ if (_jack_output_port) {
+
+ const char** jc = jack_port_get_connections (_jack_output_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 ("outbound", 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);
+ }
+ }
+
+ return *root;
}
void
-Port::set_state (const XMLNode& /*node*/)
+Port::set_state (const XMLNode& node)
{
- // relax
+ 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();
+ }
}
void
-Port::gtk_read_callback (void *ptr, int /*fd*/, int /*cond*/)
+Port::make_connections ()
{
- byte buf[64];
- ((Port *)ptr)->read (buf, sizeof (buf));
+ if (!_inbound_connections.empty()) {
+ vector<string> ports;
+ split (_inbound_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));
+ /* 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 ();
}
void
-Port::write_callback (byte *msg, unsigned int len, void *ptr)
+Port::set_process_thread (pthread_t thr)
{
- ((Port *)ptr)->write (msg, len, 0);
+ _process_thread = thr;
}
-std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
+bool
+Port::is_process_thread()
{
- using namespace std;
- os << "MIDI::Port { ";
- os << "device: " << port.device();
- os << "; ";
- os << "name: " << port.name();
- os << "; ";
- os << "type: " << port.type();
- os << "; ";
- os << "mode: " << port.mode();
- os << "; ";
- os << "ok: " << port.ok();
- os << "; ";
- os << " }";
- return os;
+ return (pthread_self() == _process_thread);
}
-Port::Descriptor::Descriptor (const XMLNode& node)
+void
+Port::reestablish (void* jack)
{
- const XMLProperty *prop;
- bool have_tag = false;
- bool have_device = false;
- bool have_type = false;
- bool have_mode = false;
-
- if ((prop = node.property ("tag")) != 0) {
- tag = prop->value();
- have_tag = true;
- }
+ _jack_client = static_cast<jack_client_t*> (jack);
+ int const r = create_ports ();
- if ((prop = node.property ("device")) != 0) {
- device = prop->value();
- have_device = true;
- }
-
- if ((prop = node.property ("type")) != 0) {
- type = PortFactory::string_to_type (prop->value());
- have_type = true;
- }
-
- if ((prop = node.property ("mode")) != 0) {
- mode = PortFactory::string_to_mode (prop->value());
- have_mode = true;
- }
-
- if (!have_tag || !have_device || !have_type || !have_mode) {
- throw failed_constructor();
+ if (r) {
+ PBD::error << "could not reregister ports for " << name() << endmsg;
}
}
+void
+Port::reconnect ()
+{
+ make_connections ();
+}
diff --git a/libs/midi++2/wscript b/libs/midi++2/wscript
index 60ac03d77a..aa6f8a67ca 100644
--- a/libs/midi++2/wscript
+++ b/libs/midi++2/wscript
@@ -45,11 +45,8 @@ def build(bld):
# Library
obj = bld.new_task_gen('cxx', 'shlib')
obj.source = '''
- fd_midiport.cc
- fifomidi.cc
midi.cc
channel.cc
- factory.cc
manager.cc
parser.cc
port.cc
@@ -59,21 +56,12 @@ def build(bld):
version.cc
'''
# everybody loves JACK
- obj.source += ' jack_midiport.cc '
obj.cxxflags = [ '-DWITH_JACK_MIDI' ]
- if bld.env['HAVE_COREAUDIO'] and bld.env['COREAUDIO']:
- # OS X
- obj.source += ' coremidi_midiport.cc '
- obj.cxxflags += [ '-DWITH_COREMIDI' ]
- elif sys.platform == 'linux':
- # linux
- obj.source += ' alsa_sequencer_midiport.cc '
- obj.cxxflags += [ '-DWITH_ALSA' ]
obj.export_incdirs = ['.']
obj.includes = ['.', '../surfaces/control_protocol']
obj.name = 'libmidipp'
obj.target = 'midipp'
- obj.uselib = 'GLIBMM SIGCPP XML JACK OSX COREAUDIO'
+ obj.uselib = 'GLIBMM SIGCPP XML JACK OSX'
obj.uselib_local = 'libpbd libevoral'
obj.vnum = LIBMIDIPP_LIB_VERSION
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 3fa1686d9b..a49c67acc5 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -563,20 +563,14 @@ MackieControlProtocol::connect_session_signals()
void
MackieControlProtocol::add_port (MIDI::Port & midi_port, int number)
{
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1,%2,%3\n", midi_port.name(), midi_port.device(), midi_port.type()));
-
- if (string (midi_port.device()) == string ("ardour") && midi_port.type() == MIDI::Port::ALSA_Sequencer) {
- throw MackieControlException ("The Mackie MCU driver will not use a port with device=ardour");
- } else if (midi_port.type() == MIDI::Port::ALSA_Sequencer) {
- throw MackieControlException ("alsa/sequencer ports don't work with the Mackie MCU driver right now");
- } else {
- MackiePort * sport = new MackiePort (*this, midi_port, number);
- _ports.push_back (sport);
-
- sport->init_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
- sport->active_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_active, this, sport));
- sport->inactive_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_inactive, this, sport));
- }
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1\n", midi_port.name()));
+
+ MackiePort * sport = new MackiePort (*this, midi_port, number);
+ _ports.push_back (sport);
+
+ sport->init_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
+ sport->active_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_active, this, sport));
+ sport->inactive_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_inactive, this, sport));
}
void
diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc
index 8aaea1d5ba..9dd456157e 100644
--- a/libs/surfaces/mackie/surface_port.cc
+++ b/libs/surfaces/mackie/surface_port.cc
@@ -173,8 +173,6 @@ void SurfacePort::write_sysex( MIDI::byte msg )
ostream & Mackie::operator << ( ostream & os, const SurfacePort & port )
{
os << "{ ";
- os << "device: " << port.port().device();
- os << "; ";
os << "name: " << port.port().name();
os << "; ";
os << " }";