Wrap MusicalTime in a class.
[ardour.git] / libs / midi++2 / port.cc
index 6694249b6101bb25f11adc7d1beca59a252ace79..90ec260eae1cb8822a0e12f2bfdbb66d715d2275 100644 (file)
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
+    $Id: port.cc 11871 2012-04-10 16:27:01Z paul $
 */
 #include <iostream>
 #include <cstdio>
 #include "pbd/xml++.h"
 #include "pbd/error.h"
 #include "pbd/failed_constructor.h"
+#include "pbd/convert.h"
+#include "pbd/strsplit.h"
+#include "pbd/stacktrace.h"
 
 #include "midi++/types.h"
 #include "midi++/port.h"
 #include "midi++/channel.h"
-#include "midi++/factory.h"
 
 using namespace MIDI;
 using namespace std;
 using namespace PBD;
 
-size_t Port::nports = 0;
+string Port::state_node_name = "MIDI-port";
+
+Port::Port (string const & name, Flags flags)
+       : _flags (flags)
+       , _centrally_parsed (true)
+{
+       init (name, flags);
+}
 
 Port::Port (const XMLNode& node)
-       : _currently_in_cycle(false)
-       , _nframes_this_cycle(0)
+       : _centrally_parsed (true)
 {
        Descriptor desc (node);
 
+       init (desc.tag, desc.flags);
+
+       /* derived class must call ::set_state() */
+}
+
+void
+Port::init (string const & name, Flags flags)
+{
        _ok = false;  /* derived class must set to true if constructor
                         succeeds.
                      */
 
-       bytes_written = 0;
-       bytes_read = 0;
-       input_parser = 0;
-       output_parser = 0;
-       slowdown = 0;
-
-       _devname = desc.device;
-       _tagname = desc.tag;
-       _mode = desc.mode;
+       _parser = 0;
 
-       if (_mode == O_RDONLY || _mode == O_RDWR) {
-               input_parser = new Parser (*this);
-       } else {
-               input_parser = 0;
-       }
+       _tagname = name;
+       _flags = flags;
 
-       if (_mode == O_WRONLY || _mode == O_RDWR) {
-               output_parser = new Parser (*this);
-       } else {
-               output_parser = 0;
-       }
+       _parser = new Parser ();
 
        for (int i = 0; i < 16; i++) {
-               _channel[i] =  new Channel (i, *this);
-
-               if (input_parser) {
-                       _channel[i]->connect_input_signals ();
-               }
-
-               if (output_parser) {
-                       _channel[i]->connect_output_signals ();
-               }
+               _channel[i] = new Channel (i, *this);
+               _channel[i]->connect_signals ();
        }
 }
 
-
 Port::~Port ()
 {
        for (int i = 0; i < 16; i++) {
@@ -90,45 +83,6 @@ Port::~Port ()
        }
 }
 
-void
-Port::parse (nframes_t timestamp)
-{
-       byte buf[512];
-
-       /* NOTE: parsing is done (if at all) by initiating a read from 
-          the port. Each port implementation calls on the parser
-          once it has data ready.
-       */
-       
-       if (input_parser) {
-               input_parser->set_timestamp (timestamp);
-       }
-
-       while (1) {
-               
-               // cerr << "+++ READ ON " << name() << endl;
-
-               int nread = read (buf, sizeof (buf));
-
-               // cerr << "-- READ (" << nread << " ON " << name() << endl;
-               
-               if (nread > 0) {
-                       if ((size_t) nread < sizeof (buf)) {
-                               break;
-                       } else {
-                               continue;
-                       }
-               } else if (nread == 0) {
-                       break;
-               } else if (errno == EAGAIN) {
-                       break;
-               } else {
-                       fatal << "Error reading from MIDI port " << name() << endmsg;
-                       /*NOTREACHED*/
-               }
-       }
-}
-
 /** Send a clock tick message.
  * \return true on success.
  */
@@ -137,83 +91,19 @@ Port::clock (timestamp_t timestamp)
 {
        static byte clockmsg = 0xf8;
        
-       if (_mode != O_RDONLY) {
+       if (sends_output()) {
                return midimsg (&clockmsg, 1, timestamp);
        }
        
        return false;
 }
 
-void
-Port::cycle_start (nframes_t nframes)
-{
-       _currently_in_cycle = true;
-       _nframes_this_cycle = nframes;
-}
-
-void
-Port::cycle_end ()
-{
-       _currently_in_cycle = false;
-       _nframes_this_cycle = 0;
-}
-
-XMLNode&
-Port::get_state () const
-{
-       XMLNode* node = new XMLNode ("MIDI-port");
-       node->add_property ("tag", _tagname);
-       node->add_property ("device", _devname);
-       node->add_property ("mode", PortFactory::mode_to_string (_mode));
-       node->add_property ("type", get_typestring());
-
-#if 0
-       byte device_inquiry[6];
-
-       device_inquiry[0] = 0xf0;
-       device_inquiry[0] = 0x7e;
-       device_inquiry[0] = 0x7f;
-       device_inquiry[0] = 0x06;
-       device_inquiry[0] = 0x02;
-       device_inquiry[0] = 0xf7;
-       
-       write (device_inquiry, sizeof (device_inquiry), 0);
-#endif
-
-       return *node;
-}
-
-void
-Port::set_state (const XMLNode& /*node*/)
-{
-       // relax
-}
-
-void
-Port::gtk_read_callback (void *ptr, int /*fd*/, int /*cond*/)
-{
-       byte buf[64];
-       ((Port *)ptr)->read (buf, sizeof (buf));
-}
-
-void
-Port::write_callback (byte *msg, unsigned int len, void *ptr)
-{
-       ((Port *)ptr)->write (msg, len, 0);
-}
-
 std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
 {
        using namespace std;
        os << "MIDI::Port { ";
-       os << "device: " << port.device();
-       os << "; ";
        os << "name: " << port.name();
        os << "; ";
-       os << "type: " << port.type();
-       os << "; ";
-       os << "mode: " << port.mode();
-       os << "; ";
        os << "ok: " << port.ok();
        os << "; ";
        os << " }";
@@ -224,8 +114,6 @@ Port::Descriptor::Descriptor (const XMLNode& node)
 {
        const XMLProperty *prop;
        bool have_tag = false;
-       bool have_device = false;
-       bool have_type = false;
        bool have_mode = false;
 
        if ((prop = node.property ("tag")) != 0) {
@@ -233,23 +121,62 @@ Port::Descriptor::Descriptor (const XMLNode& node)
                have_tag = true;
        }
 
-       if ((prop = node.property ("device")) != 0) {
-               device = prop->value();
-               have_device = true;
-       }
+       if ((prop = node.property ("mode")) != 0) {
 
-       if ((prop = node.property ("type")) != 0) {
-               type = PortFactory::string_to_type (prop->value());
-               have_type = true;
-       }
+               if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
+                       flags = IsOutput;
+               } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
+                       flags = IsInput;
+               }
 
-       if ((prop = node.property ("mode")) != 0) {
-               mode = PortFactory::string_to_mode (prop->value());
                have_mode = true;
        }
 
-       if (!have_tag || !have_device || !have_type || !have_mode) {
+       if (!have_tag || !have_mode) {
                throw failed_constructor();
        }
 }
 
+XMLNode& 
+Port::get_state () const
+{
+       XMLNode* root = new XMLNode (state_node_name);
+       root->add_property ("tag", _tagname);
+
+       if (_flags == IsInput) {
+               root->add_property ("mode", "input");
+       } else {
+               root->add_property ("mode", "output");
+       }
+       
+#if 0
+       byte device_inquiry[6];
+
+       device_inquiry[0] = 0xf0;
+       device_inquiry[0] = 0x7e;
+       device_inquiry[0] = 0x7f;
+       device_inquiry[0] = 0x06;
+       device_inquiry[0] = 0x02;
+       device_inquiry[0] = 0xf7;
+       
+       write (device_inquiry, sizeof (device_inquiry), 0);
+#endif
+
+       return *root;
+}
+
+void
+Port::set_state (const XMLNode& node)
+{
+       const XMLProperty* prop;
+
+       if ((prop = node.property ("tag")) == 0 || prop->value() != _tagname) {
+               return;
+       }
+}
+
+bool
+Port::centrally_parsed() const
+{
+       return _centrally_parsed;
+}