summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-10-04 20:10:21 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-10-04 20:10:21 +0000
commit73d0f4b9f5029e9ca33843bb2d65ab2ba0aee3f2 (patch)
treeb5c83722f4b14de5bfce0f7d4f609c368e86f776 /libs
parentf5a5889f18451f2d77762e807e51d78b1cd2c411 (diff)
use new ALSA sequencer port tweaks when handling incoming MIDI data
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@13203 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/session_midi.cc122
1 files changed, 68 insertions, 54 deletions
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index bfb6bddf42..bb161b625c 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -1143,14 +1143,18 @@ void
Session::midi_thread_work ()
{
MIDIRequest* request;
- struct pollfd pfd[4];
- int nfds = 0;
+ struct pollfd *pfd = 0;
+ size_t pfd_size = 0;
+ size_t nfds = 0;
int timeout;
int fds_ready;
struct sched_param rtparam;
int x;
bool restart;
- vector<MIDI::Port*> ports;
+ set<int> fds_used;
+ vector<MIDI::Port*> ports;
+ bool port_assign_required = true;
+ size_t n;
PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048);
@@ -1158,56 +1162,54 @@ Session::midi_thread_work ()
rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
- // do we care? not particularly.
+ // failure ... do we care? not particularly.
}
- /* 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);
-
while (1) {
+ const MIDI::Manager::PortMap& pm = MIDI::Manager::instance()->get_midi_ports ();
+
+ if (port_assign_required || (pm.size() != (pfd_size - 1))) {
+
+ delete [] pfd;
+
+ ports.clear ();
+
+ for (MIDI::Manager::PortMap::const_iterator i = pm.begin(); i != pm.end(); ++i) {
+ ports.push_back (i->second);
+ }
+
+ pfd_size = ports.size() + 1;
+ pfd = new pollfd[pfd_size];
+ port_assign_required = false;
+ }
+
nfds = 0;
+ fds_used.clear ();
pfd[nfds].fd = midi_request_pipe[0];
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;
- ports[nfds] = _mmc_port;
- //cerr << "MIDI port " << nfds << " = MMC @ " << _mmc_port << endl;
- nfds++;
- }
-
- /* if MTC is being handled on a different port from MMC
- or we are not handling MMC at all, poll
- the relevant port.
- */
-
- if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
- pfd[nfds].fd = _mtc_port->selectable();
- pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
- ports[nfds] = _mtc_port;
- //cerr << "MIDI port " << nfds << " = MTC @ " << _mtc_port << endl;
- nfds++;
- }
-
- 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;
- ports[nfds] = _midi_port;
- // cerr << "MIDI port " << nfds << " = MIDI @ " << _midi_port << endl;
- nfds++;
- }
+ /* only poll ports if we're meant to be busy */
+
+ vector<MIDI::Port*>::const_iterator p;
+ size_t n;
+
+ for (p = ports.begin(), n = 1; p != ports.end() && n < pfd_size; ++n, ++p) {
+
+ int fd = (*p)->selectable();
+
+ if (fds_used.find (fd) != fds_used.end()) {
+ continue;
+ }
+
+ fds_used.insert (fd);
+
+ pfd[n].fd = fd;
+ pfd[n].events = POLLIN|POLLHUP|POLLERR;
+ nfds++;
+ }
if (!midi_timeouts.empty()) {
timeout = 100; /* 10msecs */
@@ -1305,6 +1307,7 @@ Session::midi_thread_work ()
/* restart poll with new ports */
// cerr << "rebind\n";
restart = true;
+ port_assign_required = true;
break;
case MIDIRequest::Quit:
@@ -1327,17 +1330,26 @@ Session::midi_thread_work ()
continue;
}
- /* now read the rest of the ports */
-
- for (int p = 1; p < nfds; ++p) {
- if ((pfd[p].revents & ~POLLIN)) {
- // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
- break;
- }
-
- if (pfd[p].revents & POLLIN) {
- fds_ready++;
- midi_read (ports[p]);
+ /* now check all sequencer related fds, and do port i/o if any data is necessary.
+ */
+
+ MIDI::Manager::PreRead(); /* EMIT SIGNAL */
+
+ for (n = 1; n < nfds; ++n) {
+
+ if (pfd[n].revents & ~POLLIN) {
+ // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
+ break;
+
+ } else if (pfd[n].revents & POLLIN) {
+
+ /* note for ALSA sequencer ports, this can be wierd, since there may only
+ be 1 selectable/pollable fd for multiple ports. this will catch the "data
+ ready" condition for all of them, and then the ALSA specific port
+ code will figure out how to demux it across the relevant ports.
+ */
+
+ midi_read (ports[n]);
}
}
@@ -1359,5 +1371,7 @@ Session::midi_thread_work ()
}
}
}
+
+ delete [] pfd;
}