save and restore all ardour-owned MIDI ports

still need to check on MCU port status
This commit is contained in:
Paul Davis 2013-08-13 21:59:05 -04:00
parent e87424f514
commit 07c63fb2d7
6 changed files with 136 additions and 35 deletions

View File

@ -41,11 +41,6 @@ class MidiPortManager {
MidiPortManager();
virtual ~MidiPortManager ();
MidiPort* add_port (MidiPort *);
void remove_port (MidiPort *);
MidiPort* port (const std::string&);
/* Ports used for control. These are read/written to outside of the
* process callback (asynchronously with respect to when data
* actually arrives).
@ -70,7 +65,8 @@ class MidiPortManager {
boost::shared_ptr<MidiPort> midi_clock_input_port() const { return _midi_clock_input_port; }
boost::shared_ptr<MidiPort> midi_clock_output_port() const { return _midi_clock_output_port; }
void set_port_states (std::list<XMLNode*>);
void set_midi_port_states ();
std::list<XMLNode*> get_midi_port_states () const;
PBD::Signal0<void> PortsChanged;
@ -80,6 +76,9 @@ class MidiPortManager {
MIDI::Port* _midi_output_port;
MIDI::Port* _mmc_input_port;
MIDI::Port* _mmc_output_port;
/* these point to the same objects as the 4 members above,
but cast to their ARDOUR::Port base class
*/
boost::shared_ptr<Port> _midi_in;
boost::shared_ptr<Port> _midi_out;
boost::shared_ptr<Port> _mmc_in;

View File

@ -135,6 +135,11 @@ public:
virtual void increment_port_buffer_offset (pframes_t n);
virtual XMLNode& get_state (void) const;
virtual int set_state (const XMLNode&, int version);
static std::string state_node_name;
protected:
Port (std::string const &, DataType, PortFlags);

View File

@ -53,6 +53,7 @@ class RCConfiguration : public Configuration
XMLNode* control_protocol_state () { return _control_protocol_state; }
std::list<XMLNode*> midi_port_states () { return _midi_port_states; }
std::list<XMLNode*> old_midi_port_states () { return _old_midi_port_states; }
/* define accessor methods */
@ -86,6 +87,7 @@ class RCConfiguration : public Configuration
state once the audio engine and hence ports are up.
*/
std::list<XMLNode*> _midi_port_states;
std::list<XMLNode*> _old_midi_port_states;
};
/* XXX: rename this */

View File

@ -20,6 +20,7 @@
#include "ardour/audioengine.h"
#include "ardour/async_midi_port.h"
#include "ardour/midiport_manager.h"
#include "ardour/rc_configuration.h"
#include "i18n.h"
@ -56,13 +57,6 @@ MidiPortManager::~MidiPortManager ()
}
MidiPort*
MidiPortManager::port (string const & n)
{
boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (AudioEngine::instance()->get_port_by_name (n));
return mp.get();
}
void
MidiPortManager::create_ports ()
{
@ -116,19 +110,65 @@ MidiPortManager::create_ports ()
_mtc_output_port->set_always_parse (true);
_midi_clock_input_port->set_always_parse (true);
_midi_clock_output_port->set_always_parse (true);
set_midi_port_states ();
}
void
MidiPortManager::set_port_states (list<XMLNode*> s)
MidiPortManager::set_midi_port_states ()
{
PortManager::PortList pl;
list<XMLNode*> nodes;
XMLProperty* prop;
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
PortMap ports;
const int version = 0;
AudioEngine::instance()->get_ports (DataType::MIDI, pl);
nodes = Config->midi_port_states ();
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
for (list<XMLNode*>::iterator i = s.begin(); i != s.end(); ++i) {
for (PortManager::PortList::const_iterator j = pl.begin(); j != pl.end(); ++j) {
// (*j)->set_state (**i);
for (list<XMLNode*>::iterator n = nodes.begin(); n != nodes.end(); ++n) {
if ((prop = (*n)->property (X_("name"))) == 0) {
continue;
}
PortMap::iterator p = ports.find (prop->value());
if (p == ports.end()) {
continue;
}
p->second->set_state (**n, version);
}
}
list<XMLNode*>
MidiPortManager::get_midi_port_states () const
{
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
PortMap ports;
list<XMLNode*> s;
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
for (PortMap::const_iterator p = ports.begin(); p != ports.end(); ++p) {
s.push_back (&p->second->get_state());
}
return s;
}

View File

@ -44,6 +44,7 @@ PBD::Signal0<void> Port::PortDrop;
bool Port::_connecting_blocked = false;
pframes_t Port::_global_port_buffer_offset = 0;
pframes_t Port::_cycle_nframes = 0;
std::string Port::state_node_name = X_("Port");
/* a handy define to shorten what would otherwise be a needlessly verbose
* repeated phrase
@ -453,3 +454,61 @@ Port::physically_connected () const
return port_engine.physically_connected (_port_handle);
}
XMLNode&
Port::get_state () const
{
XMLNode* root = new XMLNode (state_node_name);
root->add_property (X_("name"), AudioEngine::instance()->make_port_name_relative (name()));
if (receives_input()) {
root->add_property (X_("direction"), X_("input"));
} else {
root->add_property (X_("direction"), X_("output"));
}
vector<string> c;
get_connections (c);
for (vector<string>::const_iterator i = c.begin(); i != c.end(); ++i) {
XMLNode* child = new XMLNode (X_("Connection"));
child->add_property (X_("other"), *i);
root->add_child_nocopy (*child);
}
return *root;
}
int
Port::set_state (const XMLNode& node, int)
{
const XMLProperty* prop;
if (node.name() != state_node_name) {
return -1;
}
if ((prop = node.property (X_("name"))) != 0) {
set_name (prop->value());
}
const XMLNodeList& children (node.children());
_connections.clear ();
for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
if ((*c)->name() != X_("Connection")) {
continue;
}
if ((prop = (*c)->property (X_("other"))) == 0) {
continue;
}
_connections.insert (prop->value());
}
return 0;
}

View File

@ -27,12 +27,13 @@
#include "pbd/xml++.h"
#include "pbd/file_utils.h"
#include "ardour/audioengine.h"
#include "ardour/control_protocol_manager.h"
#include "ardour/diskstream.h"
#include "ardour/filesystem_paths.h"
#include "ardour/port.h"
#include "ardour/rc_configuration.h"
#include "ardour/session_metadata.h"
#include "ardour/midiport_manager.h"
#include "i18n.h"
@ -62,9 +63,12 @@ RCConfiguration::RCConfiguration ()
{
}
RCConfiguration::~RCConfiguration ()
{
for (list<XMLNode*>::iterator i = _old_midi_port_states.begin(); i != _old_midi_port_states.end(); ++i) {
delete *i;
}
for (list<XMLNode*>::iterator i = _midi_port_states.begin(); i != _midi_port_states.end(); ++i) {
delete *i;
}
@ -176,20 +180,10 @@ RCConfiguration::get_state ()
root = new XMLNode("Ardour");
/* XXX
* GET STATE OF MIDI::Port HERE
*/
#if 0
MidiPortManager* mm = MidiPortManager::instance();
if (mm) {
boost::shared_ptr<const MidiPortManager::PortList> ports = mm->get_midi_ports();
for (MidiPortManager::PortList::const_iterator i = ports->begin(); i != ports->end(); ++i) {
// root->add_child_nocopy ((*i)->get_state());
}
}
#endif
list<XMLNode*> midi_port_nodes = AudioEngine::instance()->get_midi_port_states();
for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
root->add_child_nocopy (**n);
}
root->add_child_nocopy (get_variables ());
@ -255,6 +249,8 @@ RCConfiguration::set_state (const XMLNode& root, int version)
} else if (node->name() == ControlProtocolManager::state_node_name) {
_control_protocol_state = new XMLNode (*node);
} else if (node->name() == MIDI::Port::state_node_name) {
_old_midi_port_states.push_back (new XMLNode (*node));
} else if (node->name() == ARDOUR::Port::state_node_name) {
_midi_port_states.push_back (new XMLNode (*node));
}
}