mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
reinstate Ye Olde MIDI (input) thread; fix up a few startup warnings
git-svn-id: svn://localhost/ardour2/branches/3.0@3156 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
eb4a1fdbb8
commit
3a29796405
19 changed files with 98 additions and 286 deletions
|
|
@ -375,10 +375,6 @@
|
|||
<separator/>
|
||||
<menuitem action='ToggleTapeMachineMode'/>
|
||||
</menu>
|
||||
<menu action='Plugins'>
|
||||
<menuitem action='DisableAllPlugins'/>
|
||||
<menuitem action='ABAllPlugins'/>
|
||||
</menu>
|
||||
<menu action='Metering'>
|
||||
<menu action='MeteringFallOffRate'>
|
||||
<menuitem action='MeterFalloffOff'/>
|
||||
|
|
|
|||
|
|
@ -620,8 +620,6 @@ Editor::update_ruler_visibility ()
|
|||
frames_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion));
|
||||
minsec_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion));
|
||||
|
||||
ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START));
|
||||
|
||||
smpte_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll));
|
||||
bbt_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll));
|
||||
frames_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll));
|
||||
|
|
|
|||
|
|
@ -771,10 +771,6 @@ class Session : public PBD::StatefulDestructible
|
|||
bool get_trace_midi_input(MIDI::Port *port = 0);
|
||||
bool get_trace_midi_output(MIDI::Port *port = 0);
|
||||
|
||||
void send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
|
||||
|
||||
void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
|
||||
|
||||
void set_mmc_receive_device_id (uint32_t id);
|
||||
void set_mmc_send_device_id (uint32_t id);
|
||||
|
||||
|
|
@ -1255,7 +1251,7 @@ class Session : public PBD::StatefulDestructible
|
|||
void remove_empty_sounds ();
|
||||
|
||||
void setup_midi_control ();
|
||||
//int midi_read (MIDI::Port *);
|
||||
int midi_read (MIDI::Port *);
|
||||
|
||||
void enable_record ();
|
||||
|
||||
|
|
@ -1286,8 +1282,6 @@ class Session : public PBD::StatefulDestructible
|
|||
/* MIDI Machine Control */
|
||||
|
||||
void deliver_mmc (MIDI::MachineControl::Command, nframes_t);
|
||||
//void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
|
||||
//void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
|
||||
|
||||
void spp_start (MIDI::Parser&);
|
||||
void spp_continue (MIDI::Parser&);
|
||||
|
|
@ -1353,52 +1347,29 @@ class Session : public PBD::StatefulDestructible
|
|||
struct MIDIRequest {
|
||||
|
||||
enum Type {
|
||||
SendFullMTC,
|
||||
SendMTC,
|
||||
SendMMC,
|
||||
PortChange,
|
||||
SendMessage,
|
||||
Deliver,
|
||||
Quit
|
||||
};
|
||||
|
||||
Type type;
|
||||
MIDI::MachineControl::Command mmc_cmd;
|
||||
nframes_t locate_frame;
|
||||
|
||||
// for SendMessage type
|
||||
|
||||
MIDI::Port * port;
|
||||
MIDI::channel_t chan;
|
||||
union {
|
||||
MIDI::EventTwoBytes data;
|
||||
MIDI::byte* buf;
|
||||
};
|
||||
|
||||
union {
|
||||
MIDI::eventType ev;
|
||||
int32_t size;
|
||||
};
|
||||
|
||||
MIDIRequest () {}
|
||||
|
||||
void *operator new(size_t ignored) {
|
||||
return pool.alloc ();
|
||||
};
|
||||
|
||||
void operator delete(void *ptr, size_t size) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
static MultiAllocSingleReleasePool pool;
|
||||
};
|
||||
|
||||
mutable gint butler_active;
|
||||
Glib::Mutex midi_lock;
|
||||
pthread_t midi_thread;
|
||||
int midi_request_pipe[2];
|
||||
RingBuffer<MIDIRequest*> midi_requests;
|
||||
|
||||
int start_midi_thread ();
|
||||
void terminate_midi_thread ();
|
||||
void poke_midi_thread ();
|
||||
static void *_midi_thread_work (void *arg);
|
||||
void midi_thread_work ();
|
||||
void change_midi_ports ();
|
||||
int use_config_midi_ports ();
|
||||
|
||||
mutable gint butler_active;
|
||||
bool waiting_to_start;
|
||||
|
||||
void set_play_loop (bool yn);
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ Session::Session (AudioEngine &eng,
|
|||
_midi_port (default_midi_port),
|
||||
_session_dir (new SessionDirectory(fullpath)),
|
||||
pending_events (2048),
|
||||
//midi_requests (128), // the size of this should match the midi request pool size
|
||||
post_transport_work((PostTransportWork)0),
|
||||
midi_requests (128),
|
||||
_send_smpte_update (false),
|
||||
diskstreams (new DiskstreamList),
|
||||
routes (new RouteList),
|
||||
|
|
@ -199,7 +199,8 @@ Session::Session (AudioEngine &eng,
|
|||
_midi_port (default_midi_port),
|
||||
_session_dir ( new SessionDirectory(fullpath)),
|
||||
pending_events (2048),
|
||||
//midi_requests (16),
|
||||
post_transport_work((PostTransportWork)0),
|
||||
midi_requests (16),
|
||||
_send_smpte_update (false),
|
||||
diskstreams (new DiskstreamList),
|
||||
routes (new RouteList),
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ using namespace MIDI;
|
|||
MachineControl::CommandSignature MMC_CommandSignature;
|
||||
MachineControl::ResponseSignature MMC_ResponseSignature;
|
||||
|
||||
MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
|
||||
|
||||
int
|
||||
Session::use_config_midi_ports ()
|
||||
{
|
||||
|
|
@ -262,7 +260,6 @@ Session::set_midi_port (string port_tag)
|
|||
void
|
||||
Session::set_trace_midi_input (bool yn, MIDI::Port* port)
|
||||
{
|
||||
#if 0
|
||||
MIDI::Parser* input_parser;
|
||||
|
||||
if (port) {
|
||||
|
|
@ -289,7 +286,6 @@ Session::set_trace_midi_input (bool yn, MIDI::Port* port)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Config->set_trace_midi_input (yn);
|
||||
}
|
||||
|
|
@ -297,7 +293,6 @@ Session::set_trace_midi_input (bool yn, MIDI::Port* port)
|
|||
void
|
||||
Session::set_trace_midi_output (bool yn, MIDI::Port* port)
|
||||
{
|
||||
#if 0
|
||||
MIDI::Parser* output_parser;
|
||||
|
||||
if (port) {
|
||||
|
|
@ -324,7 +319,6 @@ Session::set_trace_midi_output (bool yn, MIDI::Port* port)
|
|||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
Config->set_trace_midi_output (yn);
|
||||
}
|
||||
|
|
@ -332,7 +326,6 @@ Session::set_trace_midi_output (bool yn, MIDI::Port* port)
|
|||
bool
|
||||
Session::get_trace_midi_input(MIDI::Port *port)
|
||||
{
|
||||
#if 0
|
||||
MIDI::Parser* input_parser;
|
||||
if (port) {
|
||||
if ((input_parser = port->input()) != 0) {
|
||||
|
|
@ -358,7 +351,6 @@ Session::get_trace_midi_input(MIDI::Port *port)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -366,7 +358,6 @@ Session::get_trace_midi_input(MIDI::Port *port)
|
|||
bool
|
||||
Session::get_trace_midi_output(MIDI::Port *port)
|
||||
{
|
||||
#if 0
|
||||
MIDI::Parser* output_parser;
|
||||
if (port) {
|
||||
if ((output_parser = port->output()) != 0) {
|
||||
|
|
@ -392,7 +383,6 @@ Session::get_trace_midi_output(MIDI::Port *port)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
||||
|
|
@ -423,46 +413,6 @@ Session::setup_midi_control ()
|
|||
mtc_msg[14] = 0xf1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
Session::midi_read (MIDI::Port* port)
|
||||
{
|
||||
MIDI::byte buf[512];
|
||||
|
||||
/* reading from the MIDI port activates the Parser
|
||||
that in turn generates signals that we care
|
||||
about. the port is already set to NONBLOCK so that
|
||||
can read freely here.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
|
||||
// cerr << "+++ READ ON " << port->name() << endl;
|
||||
|
||||
int nread = port->read (buf, sizeof (buf));
|
||||
|
||||
// cerr << "-- READ (" << nread << " ON " << port->name() << endl;
|
||||
|
||||
if (nread > 0) {
|
||||
if ((size_t) nread < sizeof (buf)) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else if (nread == 0) {
|
||||
break;
|
||||
} else if (errno == EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Session::spp_start (Parser& ignored)
|
||||
{
|
||||
|
|
@ -712,26 +662,21 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Session::change_midi_ports ()
|
||||
{
|
||||
/*
|
||||
MIDIRequest* request = new MIDIRequest;
|
||||
|
||||
request->type = MIDIRequest::PortChange;
|
||||
midi_requests.write (&request, 1);
|
||||
poke_midi_thread ();
|
||||
*/
|
||||
}
|
||||
|
||||
/** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
|
||||
* This resets the MTC code, the next quarter frame message that is sent will be
|
||||
* the first one with the beginning of this cycle as the new start point.
|
||||
*
|
||||
* Audio thread only, realtime safe. MIDI::Manager::cycle_start must
|
||||
* have been called with the appropriate nframes parameter this cycle.
|
||||
*/
|
||||
|
||||
int
|
||||
Session::send_full_time_code(nframes_t nframes)
|
||||
{
|
||||
|
|
@ -905,25 +850,6 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
|
|||
/***********************************************************************
|
||||
OUTBOUND MMC STUFF
|
||||
**********************************************************************/
|
||||
/*
|
||||
void
|
||||
Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
|
||||
{
|
||||
MIDIRequest* request;
|
||||
|
||||
if (_mtc_port == 0 || !session_send_mmc) {
|
||||
return;
|
||||
}
|
||||
|
||||
request = new MIDIRequest;
|
||||
request->type = MIDIRequest::SendMMC;
|
||||
request->mmc_cmd = cmd;
|
||||
request->locate_frame = target_frame;
|
||||
|
||||
midi_requests.write (&request, 1);
|
||||
poke_midi_thread ();
|
||||
}
|
||||
*/
|
||||
|
||||
/** Send an MMC command at the given absolute timestamp (@a where).
|
||||
*
|
||||
|
|
@ -990,8 +916,7 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
|
|||
|
||||
assert(where >= _transport_frame);
|
||||
|
||||
// FIXME: timestamp correct? [DR]
|
||||
if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), where - _transport_frame)) {
|
||||
if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), 0)) {
|
||||
error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
|
||||
} /*else {
|
||||
cerr << "Sending MMC\n";
|
||||
|
|
@ -1028,80 +953,10 @@ Session::mmc_step_timeout ()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
||||
{
|
||||
// in another thread, really
|
||||
/*
|
||||
MIDIRequest* request = new MIDIRequest;
|
||||
|
||||
request->type = MIDIRequest::SendMessage;
|
||||
request->port = port;
|
||||
request->ev = ev;
|
||||
request->chan = ch;
|
||||
request->data = data;
|
||||
|
||||
midi_requests.write (&request, 1);
|
||||
poke_midi_thread ();
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
|
||||
{
|
||||
// in another thread, really
|
||||
/*
|
||||
MIDIRequest* request = new MIDIRequest;
|
||||
|
||||
request->type = MIDIRequest::Deliver;
|
||||
request->port = port;
|
||||
request->buf = buf;
|
||||
request->size = bufsize;
|
||||
|
||||
midi_requests.write (&request, 1);
|
||||
poke_midi_thread ();
|
||||
*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
This is aaalll gone.
|
||||
|
||||
|
||||
void
|
||||
Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
||||
{
|
||||
if (port == 0 || ev == MIDI::none) {
|
||||
return;
|
||||
}
|
||||
|
||||
midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
|
||||
midi_msg[1] = data.controller_number;
|
||||
midi_msg[2] = data.value;
|
||||
|
||||
port->write (midi_msg, 3);
|
||||
}
|
||||
|
||||
void
|
||||
Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
|
||||
{
|
||||
if (port) {
|
||||
port->write (buf, size);
|
||||
}
|
||||
|
||||
/* this is part of the semantics of the Deliver request */
|
||||
|
||||
delete [] buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
MIDI THREAD
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
int
|
||||
Session::start_midi_thread ()
|
||||
{
|
||||
|
|
@ -1125,8 +980,6 @@ Session::start_midi_thread ()
|
|||
return -1;
|
||||
}
|
||||
|
||||
// pthread_detach (midi_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1134,6 +987,7 @@ void
|
|||
Session::terminate_midi_thread ()
|
||||
{
|
||||
if (midi_thread) {
|
||||
|
||||
MIDIRequest* request = new MIDIRequest;
|
||||
void* status;
|
||||
|
||||
|
|
@ -1190,10 +1044,7 @@ Session::midi_thread_work ()
|
|||
|
||||
/* set up the port vector; 4 is the largest possible size for now */
|
||||
|
||||
ports.push_back (0);
|
||||
ports.push_back (0);
|
||||
ports.push_back (0);
|
||||
ports.push_back (0);
|
||||
ports.assign (4, (MIDI::Port*) 0);
|
||||
|
||||
while (1) {
|
||||
|
||||
|
|
@ -1203,10 +1054,6 @@ Session::midi_thread_work ()
|
|||
pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||
nfds++;
|
||||
|
||||
/* if we are using MMC control, we obviously have to listen
|
||||
on the appropriate port.
|
||||
*/
|
||||
|
||||
if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
|
||||
pfd[nfds].fd = _mmc_port->selectable();
|
||||
pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||
|
|
@ -1226,6 +1073,10 @@ Session::midi_thread_work ()
|
|||
nfds++;
|
||||
}
|
||||
|
||||
/* if we are using MMC control, we obviously have to listen
|
||||
the relevant port.
|
||||
*/
|
||||
|
||||
if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
|
||||
pfd[nfds].fd = _midi_port->selectable();
|
||||
pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||
|
|
@ -1254,7 +1105,6 @@ Session::midi_thread_work ()
|
|||
// cerr << "MIDI thread wakes at " << get_cycles () << endl;
|
||||
|
||||
fds_ready = 0;
|
||||
restart = false;
|
||||
|
||||
/* check the transport request pipe */
|
||||
|
||||
|
|
@ -1294,37 +1144,6 @@ Session::midi_thread_work ()
|
|||
while (midi_requests.read (&request, 1) == 1) {
|
||||
|
||||
switch (request->type) {
|
||||
|
||||
case MIDIRequest::SendFullMTC:
|
||||
// cerr << "send full MTC\n";
|
||||
send_full_time_code ();
|
||||
// cerr << "... done\n";
|
||||
break;
|
||||
|
||||
case MIDIRequest::SendMTC:
|
||||
// cerr << "send qtr MTC\n";
|
||||
send_midi_time_code ();
|
||||
// cerr << "... done\n";
|
||||
break;
|
||||
|
||||
case MIDIRequest::SendMMC:
|
||||
// cerr << "send MMC\n";
|
||||
deliver_mmc (request->mmc_cmd, request->locate_frame);
|
||||
// cerr << "... done\n";
|
||||
break;
|
||||
|
||||
case MIDIRequest::SendMessage:
|
||||
// cerr << "send Message\n";
|
||||
deliver_midi_message (request->port, request->ev, request->chan, request->data);
|
||||
// cerr << "... done\n";
|
||||
break;
|
||||
|
||||
case MIDIRequest::Deliver:
|
||||
// cerr << "deliver\n";
|
||||
deliver_data (_midi_port, request->buf, request->size);
|
||||
// cerr << "... done\n";
|
||||
break;
|
||||
|
||||
case MIDIRequest::PortChange:
|
||||
/* restart poll with new ports */
|
||||
// cerr << "rebind\n";
|
||||
|
|
@ -1361,7 +1180,7 @@ Session::midi_thread_work ()
|
|||
|
||||
if (pfd[p].revents & POLLIN) {
|
||||
fds_ready++;
|
||||
midi_read (ports[p]);
|
||||
ports[p]->parse ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1384,5 +1203,4 @@ Session::midi_thread_work ()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -296,9 +296,9 @@ Session::second_stage_init (bool new_session)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*if (start_midi_thread ()) {
|
||||
if (start_midi_thread ()) {
|
||||
return -1;
|
||||
}*/
|
||||
}
|
||||
|
||||
// set_state() will call setup_raid_path(), but if it's a new session we need
|
||||
// to call setup_raid_path() here.
|
||||
|
|
|
|||
|
|
@ -459,12 +459,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
_requested_return_frame = -1;
|
||||
}
|
||||
|
||||
/* MISSING IN 3.0 ... move into realtime_stop() */
|
||||
// send_full_time_code ();
|
||||
// deliver_mmc (MIDI::MachineControl::cmdStop, 0);
|
||||
// deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
|
||||
/* END WHY */
|
||||
|
||||
if (did_record) {
|
||||
|
||||
/* XXX its a little odd that we're doing this here
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t ignored)
|
|||
}
|
||||
|
||||
int
|
||||
ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t ignored)
|
||||
ALSA_SequencerMidiPort::read (byte *buf, size_t max)
|
||||
{
|
||||
TR_FN();
|
||||
int err;
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
|
|||
}
|
||||
|
||||
int
|
||||
FD_MidiPort::read (byte* buf, size_t max, timestamp_t ignored)
|
||||
FD_MidiPort::read (byte* buf, size_t max)
|
||||
{
|
||||
int nread;
|
||||
|
||||
|
|
|
|||
|
|
@ -140,10 +140,9 @@ JACK_MidiPort::flush (void* jack_port_buffer)
|
|||
}
|
||||
|
||||
int
|
||||
JACK_MidiPort::read(byte * buf, size_t max, timestamp_t timestamp)
|
||||
JACK_MidiPort::read(byte * buf, size_t bufsize)
|
||||
{
|
||||
assert(_currently_in_cycle);
|
||||
assert(timestamp < _nframes_this_cycle);
|
||||
assert(_jack_input_port);
|
||||
|
||||
jack_midi_event_t ev;
|
||||
|
|
@ -152,9 +151,12 @@ JACK_MidiPort::read(byte * buf, size_t max, timestamp_t timestamp)
|
|||
jack_port_get_buffer(_jack_input_port, _nframes_this_cycle),
|
||||
_last_read_index++);
|
||||
|
||||
// XXX this doesn't handle ev.size > max
|
||||
|
||||
if (!err) {
|
||||
memcpy(buf, ev.buffer, ev.size);
|
||||
return ev.size;
|
||||
size_t limit = min (bufsize, ev.size);
|
||||
memcpy(buf, ev.buffer, limit);
|
||||
return limit;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ class ALSA_SequencerMidiPort : public Port
|
|||
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;
|
||||
|
|
@ -48,10 +51,6 @@ class ALSA_SequencerMidiPort : public Port
|
|||
void set_state (const XMLNode&);
|
||||
|
||||
protected:
|
||||
/* Direct I/O */
|
||||
|
||||
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
||||
int read (byte *buf, size_t max, timestamp_t timestamp);
|
||||
|
||||
std::string get_typestring () const {
|
||||
return typestring;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ namespace MIDI {
|
|||
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;
|
||||
}
|
||||
|
|
@ -46,12 +51,6 @@ namespace MIDI {
|
|||
static std::string typestring;
|
||||
|
||||
protected:
|
||||
/* Direct I/O */
|
||||
int write (byte * msg, size_t msglen, timestamp_t timestamp);
|
||||
|
||||
int read (byte * buf, size_t max, timestamp_t timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CoreMidi callback */
|
||||
static void read_proc(const MIDIPacketList * pktlist,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class FD_MidiPort : public Port
|
|||
return nwritten;
|
||||
}
|
||||
|
||||
virtual int read (byte *buf, size_t max, timestamp_t ignored);
|
||||
int read (byte *buf, size_t max);
|
||||
|
||||
private:
|
||||
static std::string *midi_dirpath;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ 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);
|
||||
|
||||
/* No select(2)/poll(2)-based I/O */
|
||||
virtual int selectable() const { return -1; }
|
||||
|
||||
|
|
@ -63,11 +66,6 @@ public:
|
|||
return typestring;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Direct I/O */
|
||||
int write(byte *msg, size_t msglen, timestamp_t timestamp);
|
||||
int read(byte *buf, size_t max, timestamp_t timestamp);
|
||||
|
||||
private:
|
||||
int create_ports(const XMLNode&);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class Null_MidiPort : public Port
|
|||
return msglen;
|
||||
}
|
||||
|
||||
int read (byte *buf, size_t max, timestamp_t timestamp) {
|
||||
int read (byte *buf, size_t max) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,13 +67,14 @@ class Port : public sigc::trackable {
|
|||
*/
|
||||
virtual int write (byte *msg, size_t msglen, timestamp_t timestamp) = 0;
|
||||
|
||||
/** Read a message from port.
|
||||
* @param buf Raw MIDI message to send
|
||||
* @param max Max size to write to @a buf
|
||||
* @param timestamp Time stamp in frames of this message (relative to cycle start)
|
||||
* @return number of bytes successfully written to \a buf
|
||||
/** 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 max, timestamp_t timestamp) = 0;
|
||||
virtual int read (byte *buf, size_t bufsize) = 0;
|
||||
|
||||
void parse ();
|
||||
|
||||
/** Write a message to port.
|
||||
* @return true on success.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@
|
|||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/failed_constructor.h>
|
||||
|
||||
#include <midi++/types.h>
|
||||
|
|
@ -31,6 +33,7 @@
|
|||
|
||||
using namespace MIDI;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
size_t Port::nports = 0;
|
||||
|
||||
|
|
@ -87,6 +90,40 @@ Port::~Port ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Port::parse ()
|
||||
{
|
||||
byte buf[512];
|
||||
|
||||
/* parsing is done (if at all) by initiating a read from
|
||||
the port.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
|
||||
// cerr << "+++ READ ON " << name() << endl;
|
||||
|
||||
int nread = read (buf, sizeof (buf));
|
||||
|
||||
// cerr << "-- READ (" << nread << " ON " << name() << endl;
|
||||
|
||||
if (nread > 0) {
|
||||
if ((size_t) nread < sizeof (buf)) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else if (nread == 0) {
|
||||
break;
|
||||
} else if (errno == EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
fatal << "Error reading from MIDI port " << name() << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Send a clock tick message.
|
||||
* \return true on success.
|
||||
*/
|
||||
|
|
@ -138,13 +175,11 @@ void
|
|||
Port::gtk_read_callback (void *ptr, int fd, int cond)
|
||||
{
|
||||
byte buf[64];
|
||||
|
||||
((Port *)ptr)->read (buf, sizeof (buf), 0);
|
||||
((Port *)ptr)->read (buf, sizeof (buf));
|
||||
}
|
||||
|
||||
void
|
||||
Port::write_callback (byte *msg, unsigned int len, void *ptr)
|
||||
|
||||
{
|
||||
((Port *)ptr)->write (msg, len, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ MidiByteArray SurfacePort::read()
|
|||
if ( !active() ) return retval;
|
||||
|
||||
// read port and copy to return value
|
||||
int nread = port().read( buf, sizeof (buf), 0 );
|
||||
int nread = port().read (buf, sizeof (buf));
|
||||
|
||||
if (nread >= 0) {
|
||||
retval.copy( nread, buf );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue