summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-11-13 19:50:39 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-11-13 19:50:39 +0000
commit67601c6c50ac6506c1c6f87be1c726bd1fa4241b (patch)
tree9b29e7718238fd0f6ebb992ece10a87d65b654a0
parentff9ddf510065305e13d169d35f9b4e6b88ce76d7 (diff)
fix stupid MIDI::Manager design to properly handle multiple MIDI ports with the same "device" specification
git-svn-id: svn://localhost/ardour2/branches/3.0@6079 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/keyboard.cc2
-rw-r--r--gtk2_ardour/rc_option_editor.cc26
-rw-r--r--libs/ardour/globals.cc7
-rw-r--r--libs/ardour/rc_configuration.cc7
-rw-r--r--libs/midi++2/manager.cc195
-rw-r--r--libs/midi++2/midi++/manager.h14
6 files changed, 78 insertions, 173 deletions
diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc
index 6094e3502e..200a666fea 100644
--- a/gtk2_ardour/keyboard.cc
+++ b/gtk2_ardour/keyboard.cc
@@ -197,7 +197,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
uint32_t keyval;
bool ret = false;
-#if 1
+#if 0
cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type
<< " state " << std::hex << event->state << std::dec
<< endl;
diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc
index 1ce53e80aa..507cd7ae41 100644
--- a/gtk2_ardour/rc_option_editor.cc
+++ b/gtk2_ardour/rc_option_editor.cc
@@ -170,36 +170,36 @@ private:
void setup_ports_combo (ComboBoxText& c)
{
c.clear_items ();
- MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
- for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
- c.append_text (i->first);
+ MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
+ for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
+ c.append_text ((*i)->name());
}
}
void ports_changed ()
{
/* XXX: why is this coming from here? */
- MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
+ MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
_store->clear ();
- for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
+ for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
TreeModel::Row r = *_store->append ();
- r[_model.name] = i->first;
+ r[_model.name] = (*i)->name();
- if (i->second->input()) {
- r[_model.online] = !i->second->input()->offline();
- i->second->input()->OfflineStatusChanged.connect (bind (mem_fun (*this, &MIDIPorts::port_offline_changed), i->second));
- r[_model.trace_input] = i->second->input()->tracing();
+ if ((*i)->input()) {
+ r[_model.online] = !(*i)->input()->offline();
+ (*i)->input()->OfflineStatusChanged.connect (bind (mem_fun (*this, &MIDIPorts::port_offline_changed), (*i)));
+ r[_model.trace_input] = (*i)->input()->tracing();
}
- if (i->second->output()) {
- r[_model.trace_output] = i->second->output()->tracing();
+ if ((*i)->output()) {
+ r[_model.trace_output] = (*i)->output()->tracing();
}
- r[_model.port] = i->second;
+ r[_model.port] = (*i);
}
setup_ports_combo (_mtc_combo);
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 8efb72cc8c..ac7eb8605d 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -136,12 +136,11 @@ ARDOUR::setup_midi ()
}
MIDI::Port* first;
- const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
-
+ const MIDI::Manager::PortList& ports = MIDI::Manager::instance()->get_midi_ports();
if (ports.size() > 1) {
- first = ports.begin()->second;
+ first = ports.front();
/* More than one port, so try using specific names for each port */
@@ -170,7 +169,7 @@ ARDOUR::setup_midi ()
} else if (ports.size() == 1) {
- first = ports.begin()->second;
+ first = ports.front();
/* Only one port described, so use it for both MTC and MMC */
diff --git a/libs/ardour/rc_configuration.cc b/libs/ardour/rc_configuration.cc
index f613ae1ecc..e187622757 100644
--- a/libs/ardour/rc_configuration.cc
+++ b/libs/ardour/rc_configuration.cc
@@ -200,11 +200,10 @@ RCConfiguration::get_state ()
root = new XMLNode("Ardour");
- MIDI::Manager::PortMap::const_iterator i;
- const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
+ const MIDI::Manager::PortList& ports = MIDI::Manager::instance()->get_midi_ports();
- for (i = ports.begin(); i != ports.end(); ++i) {
- root->add_child_nocopy(i->second->get_state());
+ for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
+ root->add_child_nocopy((*i)->get_state());
}
root->add_child_nocopy (get_variables ());
diff --git a/libs/midi++2/manager.cc b/libs/midi++2/manager.cc
index ab37073afd..7cd03a6311 100644
--- a/libs/midi++2/manager.cc
+++ b/libs/midi++2/manager.cc
@@ -47,15 +47,10 @@ Manager::Manager ()
Manager::~Manager ()
{
- PortMap::iterator i;
-
- for (i = ports_by_device.begin(); i != ports_by_device.end(); i++) {
- delete (*i).second;
+ for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ delete *p;
}
- ports_by_device.erase (ports_by_device.begin(), ports_by_device.end());
- ports_by_tag.erase (ports_by_tag.begin(), ports_by_tag.end());
-
if (theManager == this) {
theManager = 0;
}
@@ -67,84 +62,35 @@ Manager::add_port (const XMLNode& node)
Port::Descriptor desc (node);
PortFactory factory;
Port *port;
- PortMap::iterator existing;
- pair<string, Port *> newpair;
-
- if ((existing = ports_by_tag.find (desc.tag)) != ports_by_tag.end()) {
+ PortList::iterator p;
- 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 */
- }
+ for (p = _ports.begin(); p != _ports.end(); ++p) {
- if (!PortFactory::ignore_duplicate_devices (desc.type)) {
+ if (desc.tag == (*p)->name()) {
+ break;
+ }
- if ((existing = ports_by_device.find (desc.device)) != ports_by_device.end()) {
-
- port = (*existing).second;
-
- if (port->mode() == desc.mode) {
-
- /* Same mode - reuse the port, and just
- create a new tag entry.
+ if (!PortFactory::ignore_duplicate_devices (desc.type)) {
+ if (desc.device == (*p)->device()) {
+ /* 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.
*/
-
- 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;
+
+ if ((desc.mode == O_RDWR && port->mode() != O_RDWR) ||
+ (desc.mode != O_RDWR && port->mode() == O_RDWR)) {
+ break;
+ }
}
-
- /* modes must be different or complementary */
}
}
+
+ if (p != _ports.end()) {
+ return 0;
+ }
port = factory.create_port (node, api_data);
-
if (port == 0) {
return 0;
@@ -155,13 +101,7 @@ Manager::add_port (const XMLNode& node)
return 0;
}
- newpair.first = port->name();
- newpair.second = port;
- ports_by_tag.insert (newpair);
-
- newpair.first = port->device();
- newpair.second = port;
- ports_by_device.insert (newpair);
+ _ports.push_back (port);
/* first port added becomes the default input
port.
@@ -181,71 +121,43 @@ Manager::add_port (const XMLNode& node)
int
Manager::remove_port (Port* port)
{
- PortMap::iterator res;
-
- for (res = ports_by_device.begin(); res != ports_by_device.end(); ) {
- PortMap::iterator tmp;
- tmp = res;
- ++tmp;
- if (res->second == port) {
- ports_by_device.erase (res);
- }
- res = tmp;
+ if (inputPort == port) {
+ inputPort = 0;
}
-
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); ) {
- PortMap::iterator tmp;
- tmp = res;
- ++tmp;
- if (res->second == port) {
- ports_by_tag.erase (res);
- }
- res = tmp;
+ if (outputPort == port) {
+ outputPort = 0;
}
-
+ _ports.remove (port);
delete port;
-
return 0;
}
int
Manager::set_input_port (string tag)
{
- PortMap::iterator res;
- bool found = false;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if (tag == (*res).first) {
- found = true;
- break;
+ for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ if ((*p)->name() == tag) {
+ inputPort = (*p);
+ return 0;
}
}
-
- if (!found) {
- return -1;
- }
-
- inputPort = (*res).second;
- return 0;
+ return -1;
}
int
Manager::set_output_port (string tag)
-
{
- PortMap::iterator res;
- bool found = false;
+ PortList::iterator p;
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if (tag == (*res).first) {
- found = true;
+ for (p = _ports.begin(); p != _ports.end(); ++p) {
+ if ((*p)->name() == tag) {
+ inputPort = (*p);
break;
}
}
-
- if (!found) {
+
+ if (p == _ports.end()) {
return -1;
}
@@ -256,7 +168,8 @@ Manager::set_output_port (string tag)
outputPort->channel (chan)->all_notes_off (0);
}
}
- outputPort = (*res).second;
+
+ outputPort = (*p);
// XXX send a signal to say we've changed output ports
@@ -266,11 +179,9 @@ Manager::set_output_port (string tag)
Port *
Manager::port (string name)
{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if (name == (*res).first) {
- return (*res).second;
+ for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ if (name == (*p)->name()) {
+ return (*p);
}
}
@@ -281,14 +192,12 @@ int
Manager::foreach_port (int (*func)(const Port &, size_t, void *),
void *arg)
{
- PortMap::const_iterator i;
- int retval;
- int n;
+ int n = 0;
- for (n = 0, i = ports_by_device.begin();
- i != ports_by_device.end(); i++, n++) {
+ for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p, ++n) {
+ int retval;
- if ((retval = func (*((*i).second), n, arg)) != 0) {
+ if ((retval = func (**p, n, arg)) != 0) {
return retval;
}
}
@@ -299,16 +208,16 @@ Manager::foreach_port (int (*func)(const Port &, size_t, void *),
void
Manager::cycle_start(nframes_t nframes)
{
- for (PortMap::iterator i = ports_by_device.begin(); i != ports_by_device.end(); i++) {
- (*i).second->cycle_start (nframes);
+ for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ (*p)->cycle_start (nframes);
}
}
void
Manager::cycle_end()
{
- for (PortMap::iterator i = ports_by_device.begin(); i != ports_by_device.end(); i++) {
- (*i).second->cycle_end ();
+ for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ (*p)->cycle_end ();
}
}
diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h
index 43da0d3fd2..0698e969c0 100644
--- a/libs/midi++2/midi++/manager.h
+++ b/libs/midi++2/midi++/manager.h
@@ -20,7 +20,7 @@
#ifndef __midi_manager_h__
#define __midi_manager_h__
-#include <map>
+#include <list>
#include <vector>
#include <string>
@@ -54,7 +54,7 @@ class Manager {
Port *port (std::string name);
- size_t nports () { return ports_by_device.size(); }
+ size_t nports () const { return _ports.size(); }
/* defaults for clients who are not picky */
@@ -68,12 +68,11 @@ class Manager {
int set_input_channel (channel_t);
int set_output_channel (channel_t);
- int foreach_port (int (*func)(const Port &, size_t n, void *),
- void *arg);
+ int foreach_port (int (*func)(const Port &, size_t n, void *), void *arg);
- typedef std::map<std::string, Port *> PortMap;
+ typedef std::list<Port *> PortList;
- const PortMap& get_midi_ports() const { return ports_by_tag; }
+ const PortList& get_midi_ports() const { return _ports; }
static Manager *instance () {
if (theManager == 0) {
@@ -90,8 +89,7 @@ class Manager {
Manager ();
static Manager *theManager;
- PortMap ports_by_device; /* canonical */
- PortMap ports_by_tag; /* may contain duplicate Ports */
+ std::list<Port*> _ports;
void* api_data;