save and restore all ardour-owned MIDI ports
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 14 Aug 2013 01:59:05 +0000 (21:59 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 14 Aug 2013 01:59:05 +0000 (21:59 -0400)
still need to check on MCU port status

libs/ardour/ardour/midiport_manager.h
libs/ardour/ardour/port.h
libs/ardour/ardour/rc_configuration.h
libs/ardour/midiport_manager.cc
libs/ardour/port.cc
libs/ardour/rc_configuration.cc

index df33038f2b24e71103bc98620e462062293b0c98..9a32bfe4755e5ebee43a94dd3400bb3c35b20272 100644 (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;
index 06175de6732a69418676705b0d9b79d4d63da8f7..77bf2b6f71c6fbbf6d964ad62d02050cf4ed81fa 100644 (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);
index ff1c5f035c7582033e153fff6969760ce7f0194f..9943821d61acc8a7d261ee053585627e8b6a948c 100644 (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 */
index 5d4e8e37f64642e3f08e470281791c2fa7cee1d7..7abd47580b85ca5d2d002d1f3efe27a4bb5e2a23 100644 (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;
-
-       AudioEngine::instance()->get_ports (DataType::MIDI, pl);
+       list<XMLNode*> nodes;
+       XMLProperty* prop;
+       typedef map<std::string,boost::shared_ptr<Port> > PortMap;
+       PortMap ports;
+       const int version = 0;
+
+       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;
+}
+
+
index 3aaa371f168297750038eaaeb2cfb46f408e5c69..8fadad4fcc91f81e340b039da540db0278c6e5cc 100644 (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;
+}
index 007d6041dbddbf5e9d68bf20a9f81a389f371656..773ecf7d857b51f2e4c486eb84df0f58e5cd74ed 100644 (file)
 #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));
                }
        }