summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-11-01 00:49:24 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-11-01 00:49:24 +0000
commit4d6bfdabdb8bf2f5fd0bafe03198a0f003380754 (patch)
tree2c5b4f729b8f8d8b70342b925d7d7fad9f8791e5 /libs
parent5d0fbaeae73a2f1652c67e5aab73771edc0a20be (diff)
prevent double registration of ALSA sequencer MIDI ports
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4074 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/midi++2/alsa_sequencer_midiport.cc4
-rw-r--r--libs/midi++2/midimanager.cc41
2 files changed, 45 insertions, 0 deletions
diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc
index dc6ea9092f..f7ce4ad165 100644
--- a/libs/midi++2/alsa_sequencer_midiport.cc
+++ b/libs/midi++2/alsa_sequencer_midiport.cc
@@ -171,6 +171,8 @@ ALSA_SequencerMidiPort::create_ports (const Port::Descriptor& desc)
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;
+
+ cerr << "Create ALSA MIDI port for " << desc.tag << endl;
if (0 <= (err = snd_seq_create_simple_port (seq, desc.tag.c_str(), caps,
(SND_SEQ_PORT_TYPE_MIDI_GENERIC|
@@ -312,6 +314,8 @@ ALSA_SequencerMidiPort::get_connections (vector<SequencerPortAddress>& connectio
while (snd_seq_query_port_subscribers(seq, subs) >= 0) {
seq_addr = *snd_seq_query_subscribe_get_addr (subs);
+
+ cerr << _tagname << " is connected to " << seq_addr.client << "/" << seq_addr.port << endl;
connections.push_back (SequencerPortAddress (seq_addr.client,
seq_addr.port));
diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc
index 3791d409d7..7cfdb3bcdc 100644
--- a/libs/midi++2/midimanager.cc
+++ b/libs/midi++2/midimanager.cc
@@ -71,6 +71,47 @@ Manager::add_port (const XMLNode& node)
PortMap::iterator existing;
pair<string, Port *> newpair;
+ /* do not allow multiple ports with the same tag. if attempted, just return the existing
+ port with the same tag. XXX this is really caused by the mess of setup_midi() being
+ called twice in Ardour, once in the global init() function and once after the user RC file
+ has been loaded (there may be extra ports in it).
+ */
+
+ if ((existing = ports_by_tag.find (desc.tag)) != ports_by_tag.end()) {
+
+ port = (*existing).second;
+
+ if (port->mode() == desc.mode) {
+
+ /* Same mode - reuse the port, and just
+ create a new tag entry.
+ */
+
+ newpair.first = desc.tag;
+ newpair.second = port;
+
+ ports_by_tag.insert (newpair);
+ return port;
+ }
+
+ /* 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 && port->mode() != O_RDWR) ||
+ (desc.mode != O_RDWR && port->mode() == O_RDWR)) {
+ error << "MIDIManager: port tagged \""
+ << desc.tag
+ << "\" cannot be opened duplex and non-duplex"
+ << endmsg;
+ return 0;
+ }
+
+ /* modes must be different or complementary */
+ }
+
if (!PortFactory::ignore_duplicate_devices (desc.type)) {
if ((existing = ports_by_device.find (desc.device)) != ports_by_device.end()) {