[Scummvm-cvs-logs] SF.net SVN: scummvm:[51380] scummvm/trunk/backends/midi/alsa.cpp

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Tue Jul 27 19:18:03 CEST 2010


Revision: 51380
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51380&view=rev
Author:   eriktorbjorn
Date:     2010-07-27 17:18:02 +0000 (Tue, 27 Jul 2010)

Log Message:
-----------
ALSA: Be more intelligent when picking MIDI port

Often, a client has more than one available port. Pick the first one
that isn't already in use. For instance, on my computer client 17 is
the "Emu10k1 WaveTable", and it has four available ports. If, say,
aplaymidi is already playing on port 17:0, ScummVM will use port 17:1
instead. Otherwise the two programs will mess up each others
instruments and controller settings.

Of course, in reality I doubt that anyone will run two different MIDI
playing applications at once.

Modified Paths:
--------------
    scummvm/trunk/backends/midi/alsa.cpp

Modified: scummvm/trunk/backends/midi/alsa.cpp
===================================================================
--- scummvm/trunk/backends/midi/alsa.cpp	2010-07-27 17:14:33 UTC (rev 51379)
+++ scummvm/trunk/backends/midi/alsa.cpp	2010-07-27 17:18:02 UTC (rev 51380)
@@ -48,6 +48,17 @@
 #define my_snd_seq_open(seqp) snd_seq_open(seqp, SND_SEQ_OPEN)
 #endif
 
+#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
+
+static int check_permission(snd_seq_port_info_t *pinfo)
+{
+	if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) {
+		if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT))
+			return 1;
+	}
+	return 0;
+}
+
 /*
  * parse address string
  */
@@ -109,7 +120,41 @@
 	}
 
 	if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) {
-		// subscribe to MIDI port
+		// Subscribe to MIDI port. Prefer one that doesn't already have
+		// any connections, unless we've forced a port number already.
+		if (seq_port == -1) {
+			snd_seq_client_info_t *cinfo;
+			snd_seq_port_info_t *pinfo;
+
+			snd_seq_client_info_alloca(&cinfo);
+			snd_seq_port_info_alloca(&pinfo);
+
+			snd_seq_get_any_client_info(seq_handle, seq_client, cinfo);
+
+			int first_port = -1;
+			int found_port = -1;
+
+			snd_seq_port_info_set_client(pinfo, seq_client);
+			snd_seq_port_info_set_port(pinfo, -1);
+			while (found_port == -1 && snd_seq_query_next_port(seq_handle, pinfo) >= 0) {
+				if (check_permission(pinfo)) {
+					if (first_port == -1)
+						first_port = snd_seq_port_info_get_port(pinfo);
+					if (found_port == -1 && snd_seq_port_info_get_write_use(pinfo) == 0)
+						found_port = snd_seq_port_info_get_port(pinfo);
+				}
+			}
+
+			if (found_port == -1) {
+				// Should we abort here? For now, use the first
+				// available port.
+				seq_port = first_port;
+				warning("MidiDriver_ALSA: All ports on client %d (%s) are already in use", seq_client, snd_seq_client_info_get_name(cinfo));
+			} else {
+				seq_port = found_port;
+			}
+		}
+
 		if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) {
 			error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port);
 		}
@@ -217,23 +262,21 @@
 
 class AlsaDevice {
 public:
-	AlsaDevice(Common::String name, MusicType mt, int client, int port);
+	AlsaDevice(Common::String name, MusicType mt, int client);
 	Common::String getName();
 	MusicType getType();
 	int getClient();
-	int getPort();
 
 private:
 	Common::String _name;
 	MusicType _type;
 	int _client;
-	int _port;
 };
 
 typedef Common::List<AlsaDevice> AlsaDevices;
 
-AlsaDevice::AlsaDevice(Common::String name, MusicType mt, int client, int port)
-	: _name(name), _type(mt), _client(client), _port(port) {
+AlsaDevice::AlsaDevice(Common::String name, MusicType mt, int client)
+	: _name(name), _type(mt), _client(client) {
 }
 
 Common::String AlsaDevice::getName() {
@@ -248,10 +291,6 @@
 	return _client;
 }
 
-int AlsaDevice::getPort() {
-	return _port;
-}
-
 class AlsaMusicPlugin : public MusicPluginObject {
 public:
 	const char *getName() const {
@@ -270,17 +309,6 @@
 	static int parse_addr(const char *arg, int *client, int *port);
 };
 
-#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
-
-static int check_permission(snd_seq_port_info_t *pinfo)
-{
-	if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) {
-		if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT))
-			return 1;
-	}
-	return 0;
-}
-
 AlsaDevices AlsaMusicPlugin::getAlsaDevices() const {
 	AlsaDevices devices;
 	snd_seq_t *seq_handle;
@@ -306,9 +334,7 @@
 				// TODO: Can we figure out the appropriate music type?
 				MusicType type = MT_GM;
 				int client = snd_seq_client_info_get_client(cinfo);
-				int port = snd_seq_port_info_get_port(pinfo);
-
-				devices.push_back(AlsaDevice(name, type, client, port));
+				devices.push_back(AlsaDevice(name, type, client));
 			}
 		}
 	}
@@ -395,7 +421,7 @@
 			if (device.getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) {
 				found = true;
 				seq_client = d->getClient();
-				seq_port = d->getPort();
+				seq_port = -1;
 				break;
 			}
 		}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list