X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmanager.cc;h=822c74e1254ae1d5d48daebfe59345c78d3807d4;hb=99c1aacc236fcba1f297804baf9f5d1b0825e2ee;hp=a84b5ab68a759d60640d519ea531bf285fed8458;hpb=df2298c846527e71a794b957baec7684fabe46aa;p=ardour.git diff --git a/libs/midi++2/manager.cc b/libs/midi++2/manager.cc index a84b5ab68a..822c74e125 100644 --- a/libs/midi++2/manager.cc +++ b/libs/midi++2/manager.cc @@ -25,29 +25,38 @@ #include "midi++/types.h" #include "midi++/manager.h" -#include "midi++/factory.h" #include "midi++/channel.h" +#include "midi++/port.h" +#include "midi++/jack_midi_port.h" +#include "midi++/mmc.h" using namespace std; using namespace MIDI; using namespace PBD; -/* XXX check for strdup leaks */ - Manager *Manager::theManager = 0; -Manager::Manager () +Manager::Manager (jack_client_t* jack) + : _ports (new PortList) { - inputPort = 0; - outputPort = 0; - inputChannelNumber = 0; - outputChannelNumber = 0; - api_data = 0; + _mmc = new MachineControl (this, jack); + + _mtc_input_port = add_port (new MIDI::JackMIDIPort ("MTC in", Port::IsInput, jack)); + _mtc_output_port = add_port (new MIDI::JackMIDIPort ("MTC out", Port::IsOutput, jack)); + _midi_input_port = add_port (new MIDI::JackMIDIPort ("MIDI control in", Port::IsInput, jack)); + _midi_output_port = add_port (new MIDI::JackMIDIPort ("MIDI control out", Port::IsOutput, jack)); + _midi_clock_input_port = add_port (new MIDI::JackMIDIPort ("MIDI clock in", Port::IsInput, jack)); + _midi_clock_output_port = add_port (new MIDI::JackMIDIPort ("MIDI clock out", Port::IsOutput, jack)); } Manager::~Manager () { - for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) { + delete _mmc; + + /* This will delete our MTC etc. ports */ + + boost::shared_ptr pr = _ports.reader (); + for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) { delete *p; } @@ -57,198 +66,118 @@ Manager::~Manager () } Port * -Manager::add_port (const XMLNode& node) +Manager::add_port (Port* p) { - Port::Descriptor desc (node); - PortFactory factory; - Port *port; - PortList::iterator p; - - for (p = _ports.begin(); p != _ports.end(); ++p) { - - if (desc.tag == (*p)->name()) { - break; - } - - 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. - */ - - if ((desc.mode == O_RDWR && (*p)->mode() != O_RDWR) || - (desc.mode != O_RDWR && (*p)->mode() == O_RDWR)) { - break; - } - } - } - } - - if (p != _ports.end()) { - return 0; - } - - port = factory.create_port (node, api_data); - - if (port == 0) { - return 0; - } - - if (!port->ok()) { - delete port; - return 0; - } - - _ports.push_back (port); - - /* first port added becomes the default input - port. - */ - - if (inputPort == 0) { - inputPort = port; - } - - if (outputPort == 0) { - outputPort = port; + { + RCUWriter writer (_ports); + boost::shared_ptr pw = writer.get_copy (); + pw->push_back (p); } PortsChanged (); /* EMIT SIGNAL */ - return port; + return p; } -int -Manager::remove_port (Port* port) +void +Manager::remove_port (Port* p) { - if (inputPort == port) { - inputPort = 0; - } - - if (outputPort == port) { - outputPort = 0; + { + RCUWriter writer (_ports); + boost::shared_ptr pw = writer.get_copy (); + pw->remove (p); } - _ports.remove (port); - delete port; - PortsChanged (); /* EMIT SIGNAL */ - - return 0; } -int -Manager::set_input_port (string tag) +void +Manager::cycle_start (pframes_t nframes) { - for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) { - if ((*p)->name() == tag) { - inputPort = (*p); - return 0; - } + boost::shared_ptr pr = _ports.reader (); + + for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) { + (*p)->cycle_start (nframes); } - - return -1; } -int -Manager::set_output_port (string tag) +void +Manager::cycle_end() { - PortList::iterator p; - - for (p = _ports.begin(); p != _ports.end(); ++p) { - if ((*p)->name() == tag) { - inputPort = (*p); - break; - } - } - - if (p == _ports.end()) { - return -1; - } - - // XXX send a signal to say we're about to change output ports - - if (outputPort) { - for (channel_t chan = 0; chan < 16; chan++) { - outputPort->channel (chan)->all_notes_off (0); - } - } + boost::shared_ptr pr = _ports.reader (); - outputPort = (*p); - - // XXX send a signal to say we've changed output ports - - return 0; + for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) { + (*p)->cycle_end (); + } } -Port * -Manager::port (string name) +/** Re-register ports that disappear on JACK shutdown */ +void +Manager::reestablish (jack_client_t* jack) { - for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) { - if (name == (*p)->name()) { - return (*p); + boost::shared_ptr pr = _ports.reader (); + + for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) { + JackMIDIPort* pp = dynamic_cast (*p); + if (pp) { + pp->reestablish (jack); } } - - return 0; } -int -Manager::foreach_port (int (*func)(const Port &, size_t, void *), - void *arg) +/** Re-connect ports after a reestablish () */ +void +Manager::reconnect () { - int n = 0; - - for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p, ++n) { - int retval; + boost::shared_ptr pr = _ports.reader (); - if ((retval = func (**p, n, arg)) != 0) { - return retval; + for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) { + JackMIDIPort* pp = dynamic_cast (*p); + if (pp) { + pp->reconnect (); } } - - return 0; } -void -Manager::cycle_start(nframes_t nframes) +Port* +Manager::port (string const & n) { - for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) { - (*p)->cycle_start (nframes); + boost::shared_ptr pr = _ports.reader (); + + PortList::const_iterator p = pr->begin(); + while (p != pr->end() && (*p)->name() != n) { + ++p; } -} -void -Manager::cycle_end() -{ - for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) { - (*p)->cycle_end (); + if (p == pr->end()) { + return 0; } -} + return *p; +} -int -Manager::get_known_ports (vector& ports) +void +Manager::create (jack_client_t* jack) { - return PortFactory::get_known_ports (ports); + assert (theManager == 0); + theManager = new Manager (jack); } -/** Re-register ports that disappear on JACK shutdown */ void -Manager::reestablish (void* a) +Manager::set_port_states (list s) { - for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p) { - (*p)->reestablish (a); + boost::shared_ptr pr = _ports.reader (); + + for (list::iterator i = s.begin(); i != s.end(); ++i) { + for (PortList::const_iterator j = pr->begin(); j != pr->end(); ++j) { + (*j)->set_state (**i); + } } } -/** Re-connect ports after a reestablish () */ void -Manager::reconnect () +Manager::destroy () { - for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p) { - (*p)->reconnect (); - } + delete theManager; + theManager = 0; }