2 Copyright (C) 1998-99 Paul Barton-Davis
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "pbd/error.h"
26 #include "midi++/types.h"
27 #include "midi++/manager.h"
28 #include "midi++/factory.h"
29 #include "midi++/channel.h"
35 /* XXX check for strdup leaks */
37 Manager *Manager::theManager = 0;
43 inputChannelNumber = 0;
44 outputChannelNumber = 0;
50 for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
54 if (theManager == this) {
60 Manager::add_port (const XMLNode& node)
62 Port::Descriptor desc (node);
67 for (p = _ports.begin(); p != _ports.end(); ++p) {
69 if (desc.tag == (*p)->name()) {
73 if (!PortFactory::ignore_duplicate_devices (desc.type)) {
74 if (desc.device == (*p)->device()) {
75 /* If the existing is duplex, and this request
76 is not, then fail, because most drivers won't
77 allow opening twice with duplex and non-duplex
81 if ((desc.mode == O_RDWR && port->mode() != O_RDWR) ||
82 (desc.mode != O_RDWR && port->mode() == O_RDWR)) {
89 if (p != _ports.end()) {
93 port = factory.create_port (node, api_data);
104 _ports.push_back (port);
106 /* first port added becomes the default input
110 if (inputPort == 0) {
114 if (outputPort == 0) {
122 Manager::remove_port (Port* port)
124 if (inputPort == port) {
127 if (outputPort == port) {
130 _ports.remove (port);
136 Manager::set_input_port (string tag)
138 for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
139 if ((*p)->name() == tag) {
149 Manager::set_output_port (string tag)
151 PortList::iterator p;
153 for (p = _ports.begin(); p != _ports.end(); ++p) {
154 if ((*p)->name() == tag) {
160 if (p == _ports.end()) {
164 // XXX send a signal to say we're about to change output ports
167 for (channel_t chan = 0; chan < 16; chan++) {
168 outputPort->channel (chan)->all_notes_off (0);
174 // XXX send a signal to say we've changed output ports
180 Manager::port (string name)
182 for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
183 if (name == (*p)->name()) {
192 Manager::foreach_port (int (*func)(const Port &, size_t, void *),
197 for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p, ++n) {
200 if ((retval = func (**p, n, arg)) != 0) {
209 Manager::cycle_start(nframes_t nframes)
211 for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
212 (*p)->cycle_start (nframes);
219 for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
226 Manager::get_known_ports (vector<PortSet>& ports)
228 return PortFactory::get_known_ports (ports);