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:
Paul Davis 2008-03-19 17:25:37 +00:00
parent eb4a1fdbb8
commit 3a29796405
19 changed files with 98 additions and 286 deletions

View file

@ -375,10 +375,6 @@
<separator/> <separator/>
<menuitem action='ToggleTapeMachineMode'/> <menuitem action='ToggleTapeMachineMode'/>
</menu> </menu>
<menu action='Plugins'>
<menuitem action='DisableAllPlugins'/>
<menuitem action='ABAllPlugins'/>
</menu>
<menu action='Metering'> <menu action='Metering'>
<menu action='MeteringFallOffRate'> <menu action='MeteringFallOffRate'>
<menuitem action='MeterFalloffOff'/> <menuitem action='MeterFalloffOff'/>

View file

@ -504,10 +504,10 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_toggle_action (option_actions, X_("ShowSoloMutes"), _("Show solo muting"), mem_fun (*this, &ARDOUR_UI::toggle_ShowSoloMutes)); act = ActionManager::register_toggle_action (option_actions, X_("ShowSoloMutes"), _("Show solo muting"), mem_fun (*this, &ARDOUR_UI::toggle_ShowSoloMutes));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
/*act = ActionManager::register_action (option_actions, X_("DisableAllPlugins"), _("Disable All Plugins"), mem_fun (*this, &ARDOUR_UI::disable_all_plugins)); /* act = ActionManager::register_action (option_actions, X_("DisableAllPlugins"), _("Disable All Plugins"), mem_fun (*this, &ARDOUR_UI::disable_all_plugins));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (option_actions, X_("ABAllPlugins"), _("A/B All Plugins"), mem_fun (*this, &ARDOUR_UI::ab_all_plugins)); act = ActionManager::register_action (option_actions, X_("ABAllPlugins"), _("A/B All Plugins"), mem_fun (*this, &ARDOUR_UI::ab_all_plugins));
ActionManager::session_sensitive_actions.push_back (act);*/ ActionManager::session_sensitive_actions.push_back (act); */
/* !!! REMEMBER THAT RADIO ACTIONS HAVE TO BE HANDLED WITH MORE FINESSE THAN SIMPLE TOGGLES !!! */ /* !!! REMEMBER THAT RADIO ACTIONS HAVE TO BE HANDLED WITH MORE FINESSE THAN SIMPLE TOGGLES !!! */

View file

@ -620,8 +620,6 @@ Editor::update_ruler_visibility ()
frames_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion)); 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)); 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)); smpte_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll));
bbt_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)); frames_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll));

View file

@ -771,10 +771,6 @@ class Session : public PBD::StatefulDestructible
bool get_trace_midi_input(MIDI::Port *port = 0); bool get_trace_midi_input(MIDI::Port *port = 0);
bool get_trace_midi_output(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_receive_device_id (uint32_t id);
void set_mmc_send_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 remove_empty_sounds ();
void setup_midi_control (); void setup_midi_control ();
//int midi_read (MIDI::Port *); int midi_read (MIDI::Port *);
void enable_record (); void enable_record ();
@ -1286,8 +1282,6 @@ class Session : public PBD::StatefulDestructible
/* MIDI Machine Control */ /* MIDI Machine Control */
void deliver_mmc (MIDI::MachineControl::Command, nframes_t); 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_start (MIDI::Parser&);
void spp_continue (MIDI::Parser&); void spp_continue (MIDI::Parser&);
@ -1353,52 +1347,29 @@ class Session : public PBD::StatefulDestructible
struct MIDIRequest { struct MIDIRequest {
enum Type { enum Type {
SendFullMTC,
SendMTC,
SendMMC,
PortChange, PortChange,
SendMessage,
Deliver,
Quit Quit
}; };
Type type; 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 () {} 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 (); void change_midi_ports ();
int use_config_midi_ports (); int use_config_midi_ports ();
mutable gint butler_active;
bool waiting_to_start; bool waiting_to_start;
void set_play_loop (bool yn); void set_play_loop (bool yn);

View file

@ -129,8 +129,8 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port), _midi_port (default_midi_port),
_session_dir (new SessionDirectory(fullpath)), _session_dir (new SessionDirectory(fullpath)),
pending_events (2048), pending_events (2048),
//midi_requests (128), // the size of this should match the midi request pool size
post_transport_work((PostTransportWork)0), post_transport_work((PostTransportWork)0),
midi_requests (128),
_send_smpte_update (false), _send_smpte_update (false),
diskstreams (new DiskstreamList), diskstreams (new DiskstreamList),
routes (new RouteList), routes (new RouteList),
@ -199,7 +199,8 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port), _midi_port (default_midi_port),
_session_dir ( new SessionDirectory(fullpath)), _session_dir ( new SessionDirectory(fullpath)),
pending_events (2048), pending_events (2048),
//midi_requests (16), post_transport_work((PostTransportWork)0),
midi_requests (16),
_send_smpte_update (false), _send_smpte_update (false),
diskstreams (new DiskstreamList), diskstreams (new DiskstreamList),
routes (new RouteList), routes (new RouteList),

View file

@ -52,8 +52,6 @@ using namespace MIDI;
MachineControl::CommandSignature MMC_CommandSignature; MachineControl::CommandSignature MMC_CommandSignature;
MachineControl::ResponseSignature MMC_ResponseSignature; MachineControl::ResponseSignature MMC_ResponseSignature;
MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
int int
Session::use_config_midi_ports () Session::use_config_midi_ports ()
{ {
@ -262,7 +260,6 @@ Session::set_midi_port (string port_tag)
void void
Session::set_trace_midi_input (bool yn, MIDI::Port* port) Session::set_trace_midi_input (bool yn, MIDI::Port* port)
{ {
#if 0
MIDI::Parser* input_parser; MIDI::Parser* input_parser;
if (port) { if (port) {
@ -289,7 +286,6 @@ Session::set_trace_midi_input (bool yn, MIDI::Port* port)
} }
} }
} }
#endif
Config->set_trace_midi_input (yn); Config->set_trace_midi_input (yn);
} }
@ -297,7 +293,6 @@ Session::set_trace_midi_input (bool yn, MIDI::Port* port)
void void
Session::set_trace_midi_output (bool yn, MIDI::Port* port) Session::set_trace_midi_output (bool yn, MIDI::Port* port)
{ {
#if 0
MIDI::Parser* output_parser; MIDI::Parser* output_parser;
if (port) { if (port) {
@ -324,7 +319,6 @@ Session::set_trace_midi_output (bool yn, MIDI::Port* port)
} }
} }
#endif
Config->set_trace_midi_output (yn); Config->set_trace_midi_output (yn);
} }
@ -332,7 +326,6 @@ Session::set_trace_midi_output (bool yn, MIDI::Port* port)
bool bool
Session::get_trace_midi_input(MIDI::Port *port) Session::get_trace_midi_input(MIDI::Port *port)
{ {
#if 0
MIDI::Parser* input_parser; MIDI::Parser* input_parser;
if (port) { if (port) {
if ((input_parser = port->input()) != 0) { if ((input_parser = port->input()) != 0) {
@ -358,7 +351,6 @@ Session::get_trace_midi_input(MIDI::Port *port)
} }
} }
} }
#endif
return false; return false;
} }
@ -366,7 +358,6 @@ Session::get_trace_midi_input(MIDI::Port *port)
bool bool
Session::get_trace_midi_output(MIDI::Port *port) Session::get_trace_midi_output(MIDI::Port *port)
{ {
#if 0
MIDI::Parser* output_parser; MIDI::Parser* output_parser;
if (port) { if (port) {
if ((output_parser = port->output()) != 0) { if ((output_parser = port->output()) != 0) {
@ -392,7 +383,6 @@ Session::get_trace_midi_output(MIDI::Port *port)
} }
} }
} }
#endif
return false; return false;
@ -423,46 +413,6 @@ Session::setup_midi_control ()
mtc_msg[14] = 0xf1; 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 void
Session::spp_start (Parser& ignored) Session::spp_start (Parser& ignored)
{ {
@ -712,26 +662,21 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
} }
} }
void void
Session::change_midi_ports () Session::change_midi_ports ()
{ {
/*
MIDIRequest* request = new MIDIRequest; MIDIRequest* request = new MIDIRequest;
request->type = MIDIRequest::PortChange; request->type = MIDIRequest::PortChange;
midi_requests.write (&request, 1); midi_requests.write (&request, 1);
poke_midi_thread (); poke_midi_thread ();
*/
} }
/** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle. /** 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 * 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. * 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 int
Session::send_full_time_code(nframes_t nframes) 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 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). /** 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); assert(where >= _transport_frame);
// FIXME: timestamp correct? [DR] if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), 0)) {
if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), where - _transport_frame)) {
error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg; error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
} /*else { } /*else {
cerr << "Sending MMC\n"; cerr << "Sending MMC\n";
@ -1028,80 +953,10 @@ Session::mmc_step_timeout ()
return true; 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 MIDI THREAD
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#if 0
int int
Session::start_midi_thread () Session::start_midi_thread ()
{ {
@ -1125,8 +980,6 @@ Session::start_midi_thread ()
return -1; return -1;
} }
// pthread_detach (midi_thread);
return 0; return 0;
} }
@ -1134,6 +987,7 @@ void
Session::terminate_midi_thread () Session::terminate_midi_thread ()
{ {
if (midi_thread) { if (midi_thread) {
MIDIRequest* request = new MIDIRequest; MIDIRequest* request = new MIDIRequest;
void* status; void* status;
@ -1141,7 +995,7 @@ Session::terminate_midi_thread ()
midi_requests.write (&request, 1); midi_requests.write (&request, 1);
poke_midi_thread (); poke_midi_thread ();
pthread_join (midi_thread, &status); pthread_join (midi_thread, &status);
} }
} }
@ -1190,10 +1044,7 @@ Session::midi_thread_work ()
/* set up the port vector; 4 is the largest possible size for now */ /* set up the port vector; 4 is the largest possible size for now */
ports.push_back (0); ports.assign (4, (MIDI::Port*) 0);
ports.push_back (0);
ports.push_back (0);
ports.push_back (0);
while (1) { while (1) {
@ -1203,10 +1054,6 @@ Session::midi_thread_work ()
pfd[nfds].events = POLLIN|POLLHUP|POLLERR; pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
nfds++; 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) { if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
pfd[nfds].fd = _mmc_port->selectable(); pfd[nfds].fd = _mmc_port->selectable();
pfd[nfds].events = POLLIN|POLLHUP|POLLERR; pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
@ -1226,6 +1073,10 @@ Session::midi_thread_work ()
nfds++; 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) { 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].fd = _midi_port->selectable();
pfd[nfds].events = POLLIN|POLLHUP|POLLERR; pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
@ -1254,7 +1105,6 @@ Session::midi_thread_work ()
// cerr << "MIDI thread wakes at " << get_cycles () << endl; // cerr << "MIDI thread wakes at " << get_cycles () << endl;
fds_ready = 0; fds_ready = 0;
restart = false;
/* check the transport request pipe */ /* check the transport request pipe */
@ -1294,37 +1144,6 @@ Session::midi_thread_work ()
while (midi_requests.read (&request, 1) == 1) { while (midi_requests.read (&request, 1) == 1) {
switch (request->type) { 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: case MIDIRequest::PortChange:
/* restart poll with new ports */ /* restart poll with new ports */
// cerr << "rebind\n"; // cerr << "rebind\n";
@ -1361,7 +1180,7 @@ Session::midi_thread_work ()
if (pfd[p].revents & POLLIN) { if (pfd[p].revents & POLLIN) {
fds_ready++; fds_ready++;
midi_read (ports[p]); ports[p]->parse ();
} }
} }
@ -1384,5 +1203,4 @@ Session::midi_thread_work ()
} }
} }
} }
#endif

View file

@ -296,9 +296,9 @@ Session::second_stage_init (bool new_session)
return -1; return -1;
} }
/*if (start_midi_thread ()) { if (start_midi_thread ()) {
return -1; return -1;
}*/ }
// set_state() will call setup_raid_path(), but if it's a new session we need // set_state() will call setup_raid_path(), but if it's a new session we need
// to call setup_raid_path() here. // to call setup_raid_path() here.

View file

@ -459,12 +459,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
_requested_return_frame = -1; _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) { if (did_record) {
/* XXX its a little odd that we're doing this here /* XXX its a little odd that we're doing this here

View file

@ -137,7 +137,7 @@ ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t ignored)
} }
int int
ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t ignored) ALSA_SequencerMidiPort::read (byte *buf, size_t max)
{ {
TR_FN(); TR_FN();
int err; int err;

View file

@ -150,7 +150,7 @@ FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
} }
int int
FD_MidiPort::read (byte* buf, size_t max, timestamp_t ignored) FD_MidiPort::read (byte* buf, size_t max)
{ {
int nread; int nread;

View file

@ -140,21 +140,23 @@ JACK_MidiPort::flush (void* jack_port_buffer)
} }
int 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(_currently_in_cycle);
assert(timestamp < _nframes_this_cycle);
assert(_jack_input_port); assert(_jack_input_port);
jack_midi_event_t ev; jack_midi_event_t ev;
int err = jack_midi_event_get (&ev, int err = jack_midi_event_get (&ev,
jack_port_get_buffer(_jack_input_port, _nframes_this_cycle), jack_port_get_buffer(_jack_input_port, _nframes_this_cycle),
_last_read_index++); _last_read_index++);
// XXX this doesn't handle ev.size > max
if (!err) { if (!err) {
memcpy(buf, ev.buffer, ev.size); size_t limit = min (bufsize, ev.size);
return ev.size; memcpy(buf, ev.buffer, limit);
return limit;
} else { } else {
return 0; return 0;
} }

View file

@ -37,6 +37,9 @@ class ALSA_SequencerMidiPort : public Port
ALSA_SequencerMidiPort (const XMLNode&); ALSA_SequencerMidiPort (const XMLNode&);
virtual ~ALSA_SequencerMidiPort (); 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 */ /* select(2)/poll(2)-based I/O */
virtual int selectable() const; virtual int selectable() const;
@ -48,10 +51,6 @@ class ALSA_SequencerMidiPort : public Port
void set_state (const XMLNode&); void set_state (const XMLNode&);
protected: 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 { std::string get_typestring () const {
return typestring; return typestring;

View file

@ -38,6 +38,11 @@ namespace MIDI {
CoreMidi_MidiPort(const XMLNode& node); CoreMidi_MidiPort(const XMLNode& node);
virtual ~ CoreMidi_MidiPort(); 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 { virtual int selectable() const {
return -1; return -1;
} }
@ -46,12 +51,6 @@ namespace MIDI {
static std::string typestring; static std::string typestring;
protected: 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 */ /* CoreMidi callback */
static void read_proc(const MIDIPacketList * pktlist, static void read_proc(const MIDIPacketList * pktlist,

View file

@ -79,7 +79,7 @@ class FD_MidiPort : public Port
return nwritten; return nwritten;
} }
virtual int read (byte *buf, size_t max, timestamp_t ignored); int read (byte *buf, size_t max);
private: private:
static std::string *midi_dirpath; static std::string *midi_dirpath;

View file

@ -46,6 +46,9 @@ public:
JACK_MidiPort (const XMLNode& node, jack_client_t* jack_client); JACK_MidiPort (const XMLNode& node, jack_client_t* jack_client);
virtual ~JACK_MidiPort (); 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 */ /* No select(2)/poll(2)-based I/O */
virtual int selectable() const { return -1; } virtual int selectable() const { return -1; }
@ -63,11 +66,6 @@ public:
return typestring; 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: private:
int create_ports(const XMLNode&); int create_ports(const XMLNode&);

View file

@ -49,7 +49,7 @@ class Null_MidiPort : public Port
return msglen; return msglen;
} }
int read (byte *buf, size_t max, timestamp_t timestamp) { int read (byte *buf, size_t max) {
return 0; return 0;
} }

View file

@ -67,14 +67,15 @@ class Port : public sigc::trackable {
*/ */
virtual int write (byte *msg, size_t msglen, timestamp_t timestamp) = 0; virtual int write (byte *msg, size_t msglen, timestamp_t timestamp) = 0;
/** Read a message from port. /** Read raw bytes from a port.
* @param buf Raw MIDI message to send * @param buf memory to store read data in
* @param max Max size to write to @a buf * @param bufsize size of @a buf
* @param timestamp Time stamp in frames of this message (relative to cycle start) * @return number of bytes successfully read, negative if error
* @return number of bytes successfully written to \a buf
*/ */
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. /** Write a message to port.
* @return true on success. * @return true on success.
* FIXME: describe semantics here * FIXME: describe semantics here

View file

@ -20,8 +20,10 @@
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include <pbd/xml++.h> #include <pbd/xml++.h>
#include <pbd/error.h>
#include <pbd/failed_constructor.h> #include <pbd/failed_constructor.h>
#include <midi++/types.h> #include <midi++/types.h>
@ -31,6 +33,7 @@
using namespace MIDI; using namespace MIDI;
using namespace std; using namespace std;
using namespace PBD;
size_t Port::nports = 0; 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. /** Send a clock tick message.
* \return true on success. * \return true on success.
*/ */
@ -138,13 +175,11 @@ void
Port::gtk_read_callback (void *ptr, int fd, int cond) Port::gtk_read_callback (void *ptr, int fd, int cond)
{ {
byte buf[64]; byte buf[64];
((Port *)ptr)->read (buf, sizeof (buf));
((Port *)ptr)->read (buf, sizeof (buf), 0);
} }
void void
Port::write_callback (byte *msg, unsigned int len, void *ptr) Port::write_callback (byte *msg, unsigned int len, void *ptr)
{ {
((Port *)ptr)->write (msg, len, 0); ((Port *)ptr)->write (msg, len, 0);
} }

View file

@ -79,7 +79,7 @@ MidiByteArray SurfacePort::read()
if ( !active() ) return retval; if ( !active() ) return retval;
// read port and copy to return value // 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) { if (nread >= 0) {
retval.copy( nread, buf ); retval.copy( nread, buf );