Trim midi++ port code to either do in or out, but not both in the same object.
authorCarl Hetherington <carl@carlh.net>
Thu, 8 Jul 2010 01:00:46 +0000 (01:00 +0000)
committerCarl Hetherington <carl@carlh.net>
Thu, 8 Jul 2010 01:00:46 +0000 (01:00 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7391 d708f5d6-7413-0410-9779-e7cbd77b26cf

17 files changed:
gtk2_ardour/midi_tracer.cc
libs/ardour/midi_clock_slave.cc
libs/ardour/mtc_slave.cc
libs/ardour/session_state.cc
libs/midi++2/channel.cc
libs/midi++2/midi++/channel.h
libs/midi++2/midi++/port.h
libs/midi++2/mmc.cc
libs/midi++2/port.cc
libs/surfaces/generic_midi/midicontrollable.cc
libs/surfaces/generic_midi/midiinvokable.cc
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/mackie_port.cc
libs/surfaces/mackie/mackie_port.h
libs/surfaces/mackie/surface_port.cc
libs/surfaces/mackie/surface_port.h

index e40fbca5909ced28a71d9010aa8fc1e999224ed4..8a50a83314c0db38bae96cfe7d9418286be8d5dc 100644 (file)
@@ -134,8 +134,7 @@ MidiTracer::port_changed ()
        Port* p = Manager::instance()->port (_port_combo.get_active_text());
 
        if (p) {
-               Parser* parser = p->input() ? p->input() : p->output();
-               parser->any.connect_same_thread (_parser_connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
+               p->parser()->any.connect_same_thread (_parser_connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
        }
 }
 
index a1682127d87003d21fb39d5dfc2b3629553834e5..61c68609f9b0c24bb871c7e3325a79408c53df68 100644 (file)
@@ -77,11 +77,11 @@ MIDIClock_Slave::rebind (MIDI::Port& p)
 
        DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave: connecting to port %1\n", port->name()));
 
-       port->input()->timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
-       port->input()->start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
-       port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
-       port->input()->stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
-       port->input()->position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
+       port->parser()->timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
+       port->parser()->start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
+       port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
+       port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
+       port->parser()->position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
 }
 
 void
index 8aa91542dc15c1e1719e121e064de3ccf535cba3..a67bb7481d122dab27e391ed405897ab127ab57b 100644 (file)
@@ -95,9 +95,9 @@ MTC_Slave::rebind (MIDI::Port& p)
        
        port = &p;
        
-       port->input()->mtc_time.connect_same_thread (port_connections,  boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
-       port->input()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
-       port->input()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
+       port->parser()->mtc_time.connect_same_thread (port_connections,  boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
+       port->parser()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
+       port->parser()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
 }
 
 void
@@ -381,7 +381,7 @@ MTC_Slave::read_current (SafeTime *st) const
 bool
 MTC_Slave::locked () const
 {
-       return port->input()->mtc_locked();
+       return port->parser()->mtc_locked();
 }
 
 bool
@@ -543,7 +543,7 @@ MTC_Slave::reset_window (nframes64_t root)
           ahead of the window root (taking direction into account).
        */
 
-       switch (port->input()->mtc_running()) {
+       switch (port->parser()->mtc_running()) {
        case MTC_Forward:
                window_begin = root;
                if (session.slave_state() == Session::Running) {
index 76570cb64ac4219759a96e120f40ac11e38ccd4c..f6bdfdb4cc468026cf7a35f94c3ab4f2e25be536 100644 (file)
@@ -282,12 +282,12 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        MIDI::Manager* m = MIDI::Manager::instance ();
 
-       _mtc_input_port = m->add_port (new MIDI::Port ("MTC", O_RDONLY, _engine.jack()));
-       _mtc_output_port = m->add_port (new MIDI::Port ("MTC", O_WRONLY, _engine.jack()));
-       _midi_input_port = m->add_port (new MIDI::Port ("MIDI control", O_RDONLY, _engine.jack()));
-       _midi_output_port = m->add_port (new MIDI::Port ("MIDI control", O_WRONLY, _engine.jack()));
-       _midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock", O_RDONLY, _engine.jack()));
-       _midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock", O_WRONLY, _engine.jack()));
+       _mtc_input_port = m->add_port (new MIDI::Port ("MTC in", MIDI::Port::IsInput, _engine.jack()));
+       _mtc_output_port = m->add_port (new MIDI::Port ("MTC out", MIDI::Port::IsOutput, _engine.jack()));
+       _midi_input_port = m->add_port (new MIDI::Port ("MIDI control in", MIDI::Port::IsInput, _engine.jack()));
+       _midi_output_port = m->add_port (new MIDI::Port ("MIDI control out", MIDI::Port::IsOutput, _engine.jack()));
+       _midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock in", MIDI::Port::IsInput, _engine.jack()));
+       _midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock out", MIDI::Port::IsOutput, _engine.jack()));
 }
 
 int
index 2760e8ae5182576d1d41a25ceada837d74e7e574..e96a4b4edc88ce4fd211e623a34b4e864154f4c6 100644 (file)
@@ -33,31 +33,17 @@ Channel::Channel (byte channelnum, Port &p) : _port (p)
 }      
 
 void
-Channel::connect_input_signals ()
+Channel::connect_signals ()
 {
-       _port.input()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
-       _port.input()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
-       _port.input()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
-       _port.input()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
-       _port.input()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
-       _port.input()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
-       _port.input()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
-
-       _port.input()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
-}
-
-void
-Channel::connect_output_signals ()
-{
-       _port.output()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
-       _port.output()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
-       _port.output()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
-       _port.output()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
-       _port.output()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
-       _port.output()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
-       _port.output()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
-
-       _port.output()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
+       _port.parser()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
+       _port.parser()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
+       _port.parser()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
+       _port.parser()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
+       _port.parser()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
+       _port.parser()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
+       _port.parser()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
+
+       _port.parser()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
 }
 
 void
@@ -188,11 +174,8 @@ Channel::process_controller (Parser & /*parser*/, EventTwoBytes *tb)
 
        if (tb->controller_number == 0) {
                _bank_number = (unsigned short) _controller_val[0];
-               if (_port.input()) {
-                       _port.input()->bank_change (*_port.input(), _bank_number);
-                       _port.input()->channel_bank_change[_channel_number] 
-                               (*_port.input(), _bank_number);
-               }
+               _port.parser()->bank_change (*_port.parser(), _bank_number);
+               _port.parser()->channel_bank_change[_channel_number] (*_port.parser(), _bank_number);
        }
 
 }
index 470ccd447cfab54be705134a24c695605abdb520..7afaffb27494a4dd0f803f76748cb63e93320f58 100644 (file)
@@ -112,8 +112,7 @@ class Channel : public PBD::ScopedConnectionList {
 
   protected:
        friend class Port;
-       void connect_input_signals ();
-       void connect_output_signals ();
+       void connect_signals ();
 
   private:
        Port & _port;
index ca977fad2f44f03f1f5e3e9ce0e0551345da4714..6d1191866b82c8a98dd3b435328e07de33971f37 100644 (file)
@@ -42,7 +42,12 @@ class PortRequest;
 
 class Port {
   public:
-       Port (std::string const &, int, jack_client_t *);
+       enum Flags {
+               IsInput = JackPortIsInput,
+               IsOutput = JackPortIsOutput,
+       };
+       
+       Port (std::string const &, Flags, jack_client_t *);
        Port (const XMLNode&, jack_client_t *);
        ~Port ();
 
@@ -96,16 +101,24 @@ class Port {
                return _channel[chn&0x7F];
        }
        
-       Parser *input()     { return input_parser; }
-       Parser *output()    { return output_parser; }
+       Parser* parser () {
+               return _parser;
+       }
        
        const char *name () const   { return _tagname.c_str(); }
-       int    mode () const        { return _mode; }
        bool   ok ()   const        { return _ok; }
 
+       bool receives_input () const {
+               return _flags == IsInput;
+       }
+
+       bool sends_output () const {
+               return _flags == IsOutput;
+       }
+
        struct Descriptor {
            std::string tag;
-           int mode;
+           Flags flags;
 
            Descriptor (const XMLNode&);
            XMLNode& get_state();
@@ -128,36 +141,27 @@ private:
        bool             _currently_in_cycle;
        nframes_t        _nframes_this_cycle;
        std::string      _tagname;
-       int              _mode;
        size_t           _number;
        Channel          *_channel[16];
-       Parser           *input_parser;
-       Parser           *output_parser;
-
-       static size_t nports;
+       Parser           *_parser;
 
-       void create_port_names ();
-       int create_ports ();
+       int create_port ();
 
        jack_client_t* _jack_client;
-       std::string    _jack_input_port_name; /// input port name, or empty if there isn't one
-       jack_port_t*   _jack_input_port;
-       std::string    _jack_output_port_name; /// output port name, or empty if there isn't one
-       jack_port_t*   _jack_output_port;
+       jack_port_t*   _jack_port;
        nframes_t      _last_read_index;
        timestamp_t    _last_write_timestamp;
 
        /** Channel used to signal to the MidiControlUI that input has arrived */
        CrossThreadChannel xthread;
        
-       std::string    _inbound_connections;
-       std::string    _outbound_connections;
+       std::string _connections;
        PBD::ScopedConnection connect_connection;
        PBD::ScopedConnection halt_connection;
        void flush (void* jack_port_buffer);
        void jack_halted ();
-       void make_connections();
-       void init (std::string const &, int);
+       void make_connections ();
+       void init (std::string const &, Flags);
 
        static pthread_t _process_thread;
 
@@ -165,7 +169,8 @@ private:
        Evoral::EventRingBuffer<timestamp_t> input_fifo;
 
        Glib::Mutex output_fifo_lock;
-       
+
+       Flags _flags;
 };
 
 struct PortSet {
index 406fd0ef196d936e14f1478566dff37ac3ce50a5..69bdabf1e52f68fbaaf3482364919ca37152f459 100644 (file)
@@ -202,13 +202,13 @@ MachineControl::MachineControl (jack_client_t* jack)
        _receive_device_id = 0;
        _send_device_id = 0x7f;
 
-       _input_port = Manager::instance()->add_port (new Port ("MMC", O_RDONLY, jack));
-       _output_port = Manager::instance()->add_port (new Port ("MMC", O_WRONLY, jack));
+       _input_port = Manager::instance()->add_port (new Port ("MMC in", Port::IsInput, jack));
+       _output_port = Manager::instance()->add_port (new Port ("MMC out", Port::IsOutput, jack));
 
-       _input_port->input()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
-       _input_port->input()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
-       _input_port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
-       _input_port->input()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
+       _input_port->parser()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
+       _input_port->parser()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
+       _input_port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
+       _input_port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
 }
 
 void
index c2fd4c99e2e9b346beb529d8f395662d1bcfe4c2..a6097c89dceb032cc31d6445483d61c6a89153e6 100644 (file)
@@ -39,81 +39,59 @@ using namespace MIDI;
 using namespace std;
 using namespace PBD;
 
-size_t Port::nports = 0;
 pthread_t Port::_process_thread;
 Signal0<void> Port::JackHalted;
 Signal0<void> Port::MakeConnections;
 
-Port::Port (string const & name, int mode, jack_client_t* jack_client)
+Port::Port (string const & name, Flags flags, jack_client_t* jack_client)
        : _currently_in_cycle (false)
        , _nframes_this_cycle (0)
        , _jack_client (jack_client)
-       , _jack_input_port (0)
-       , _jack_output_port (0)
+       , _jack_port (0)
        , _last_read_index (0)
        , output_fifo (512)
        , input_fifo (1024)
+       , _flags (flags)
 {
-       init (name, mode);
+       init (name, flags);
 }
 
 Port::Port (const XMLNode& node, jack_client_t* jack_client)
        : _currently_in_cycle (false)
        , _nframes_this_cycle (0)
        , _jack_client (jack_client)
-       , _jack_input_port (0)
-       , _jack_output_port (0)
+       , _jack_port (0)
        , _last_read_index (0)
        , output_fifo (512)
        , input_fifo (1024)
 {
        Descriptor desc (node);
 
-       init (desc.tag, desc.mode);
+       init (desc.tag, desc.flags);
 
        set_state (node);
 }
 
 void
-Port::init (string const & name, int mode)
+Port::init (string const & name, Flags flags)
 {
        _ok = false;  /* derived class must set to true if constructor
                         succeeds.
                      */
 
-       input_parser = 0;
-       output_parser = 0;
+       _parser = 0;
 
        _tagname = name;
-       _mode = mode;
+       _flags = flags;
 
-       if (_mode == O_RDONLY || _mode == O_RDWR) {
-               input_parser = new Parser (*this);
-       } else {
-               input_parser = 0;
-       }
-
-       if (_mode == O_WRONLY || _mode == O_RDWR) {
-               output_parser = new Parser (*this);
-       } else {
-               output_parser = 0;
-       }
+       _parser = new Parser (*this);
 
        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 ();
        }
 
-       create_port_names ();
-       
-       if (!create_ports ()) {
+       if (!create_port ()) {
                _ok = true;
        }
 
@@ -128,18 +106,11 @@ Port::~Port ()
                delete _channel[i];
        }
 
-       if (_jack_input_port) {
-               if (_jack_client && _jack_input_port) {
-                       jack_port_unregister (_jack_client, _jack_input_port);
-               }
-               _jack_input_port = 0;
-       }
-
-       if (_jack_output_port) {
-               if (_jack_client && _jack_output_port) {
-                       jack_port_unregister (_jack_client, _jack_output_port);
+       if (_jack_port) {
+               if (_jack_client && _jack_port) {
+                       jack_port_unregister (_jack_client, _jack_port);
                }
-               _jack_output_port = 0;
+               _jack_port = 0;
        }
 }
 
@@ -153,9 +124,7 @@ Port::parse (nframes_t timestamp)
           once it has data ready.
        */
        
-       if (input_parser) {
-               input_parser->set_timestamp (timestamp);
-       }
+       _parser->set_timestamp (timestamp);
 
        while (1) {
                
@@ -190,7 +159,7 @@ Port::clock (timestamp_t timestamp)
 {
        static byte clockmsg = 0xf8;
        
-       if (_mode != O_RDONLY) {
+       if (sends_output()) {
                return midimsg (&clockmsg, 1, timestamp);
        }
        
@@ -207,16 +176,14 @@ Port::cycle_start (nframes_t nframes)
        _last_read_index = 0;
        _last_write_timestamp = 0;
 
-       if (_jack_output_port != 0) {
-               // output
-               void *buffer = jack_port_get_buffer (_jack_output_port, nframes);
+       if (sends_output()) {
+               void *buffer = jack_port_get_buffer (_jack_port, nframes);
                jack_midi_clear_buffer (buffer);
                flush (buffer); 
        }
        
-       if (_jack_input_port != 0) {
-               // input
-               void* jack_buffer = jack_port_get_buffer(_jack_input_port, nframes);
+       if (receives_input()) {
+               void* jack_buffer = jack_port_get_buffer(_jack_port, nframes);
                const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
 
                jack_midi_event_t ev;
@@ -236,8 +203,8 @@ Port::cycle_start (nframes_t nframes)
 void
 Port::cycle_end ()
 {
-       if (_jack_output_port != 0) {
-               flush (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle));
+       if (sends_output()) {
+               flush (jack_port_get_buffer (_jack_port, _nframes_this_cycle));
        }
 
        _currently_in_cycle = false;
@@ -250,8 +217,6 @@ std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
        os << "MIDI::Port { ";
        os << "name: " << port.name();
        os << "; ";
-       os << "mode: " << port.mode();
-       os << "; ";
        os << "ok: " << port.ok();
        os << "; ";
        os << " }";
@@ -271,12 +236,10 @@ Port::Descriptor::Descriptor (const XMLNode& node)
 
        if ((prop = node.property ("mode")) != 0) {
 
-               mode = O_RDWR;
-
                if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
-                       mode = O_WRONLY;
+                       flags = IsOutput;
                } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
-                       mode = O_RDONLY;
+                       flags = IsInput;
                }
 
                have_mode = true;
@@ -291,8 +254,7 @@ void
 Port::jack_halted ()
 {
        _jack_client = 0;
-       _jack_input_port = 0;
-       _jack_output_port = 0;
+       _jack_port = 0;
 }
 
 int
@@ -300,7 +262,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
 {
        int ret = 0;
 
-       if (!_jack_output_port) {
+       if (!sends_output()) {
                return ret;
        }
        
@@ -344,7 +306,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
                                timestamp = _last_write_timestamp;
                        } 
 
-                       if (jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle), 
+                       if (jack_midi_event_write (jack_port_get_buffer (_jack_port, _nframes_this_cycle), 
                                                timestamp, msg, msglen) == 0) {
                                ret = msglen;
                                _last_write_timestamp = timestamp;
@@ -352,7 +314,7 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
                        } else {
                                ret = 0;
                                cerr << "write of " << msglen << " failed, port holds "
-                                       << jack_midi_get_event_count (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle))
+                                       << jack_midi_get_event_count (jack_port_get_buffer (_jack_port, _nframes_this_cycle))
                                        << endl;
                        }
                } else {
@@ -360,11 +322,11 @@ Port::write(byte * msg, size_t msglen, timestamp_t timestamp)
                }
        }
 
-       if (ret > 0 && output_parser) {
+       if (ret > 0 && _parser) {
                // ardour doesn't care about this and neither should your app, probably
                // output_parser->raw_preparse (*output_parser, msg, ret);
                for (int i = 0; i < ret; i++) {
-                       output_parser->scanner (msg[i]);
+                       _parser->scanner (msg[i]);
                }
                // ardour doesn't care about this and neither should your app, probably
                // output_parser->raw_postparse (*output_parser, msg, ret);
@@ -411,64 +373,34 @@ Port::flush (void* jack_port_buffer)
 int
 Port::read (byte *, size_t)
 {
+       if (!receives_input()) {
+               return 0;
+       }
+       
        timestamp_t time;
        Evoral::EventType type;
        uint32_t size;
        byte buffer[input_fifo.capacity()];
 
        while (input_fifo.read (&time, &type, &size, buffer)) {
-               if (input_parser) {
-                       input_parser->set_timestamp (time);
-                       for (uint32_t i = 0; i < size; ++i) {
-                               input_parser->scanner (buffer[i]);
-                       }
+               _parser->set_timestamp (time);
+               for (uint32_t i = 0; i < size; ++i) {
+                       _parser->scanner (buffer[i]);
                }
        }
 
        return 0;
 }
 
-void
-Port::create_port_names ()
-{
-       assert(!_jack_input_port);
-       assert(!_jack_output_port);
-       
-       if (_mode == O_RDWR || _mode == O_WRONLY) {
-               _jack_output_port_name = _tagname.append ("_out");
-       }
-
-       if (_mode == O_RDWR || _mode == O_RDONLY) {
-               _jack_input_port_name = _tagname.append ("_in");
-       }
-}
-
 int
-Port::create_ports ()
+Port::create_port ()
 {
-       bool ret = true;
-
-       jack_nframes_t nframes = jack_get_buffer_size(_jack_client);
-
-       if (!_jack_output_port_name.empty()) {
-               _jack_output_port = jack_port_register(_jack_client, _jack_output_port_name.c_str(),
-                                                      JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
-               if (_jack_output_port) {
-                       jack_midi_clear_buffer(jack_port_get_buffer(_jack_output_port, nframes));
-               }
-               ret = ret && (_jack_output_port != NULL);
-       }
-       
-       if (!_jack_input_port_name.empty()) {
-               _jack_input_port = jack_port_register(_jack_client, _jack_input_port_name.c_str(),
-                                                     JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
-               if (_jack_input_port) {
-                       jack_midi_clear_buffer(jack_port_get_buffer(_jack_input_port, nframes));
-               }
-               ret = ret && (_jack_input_port != NULL);
+       _jack_port = jack_port_register(_jack_client, _tagname.c_str(), JACK_DEFAULT_MIDI_TYPE, _flags, 0);
+       if (_jack_port) {
+               jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, jack_get_buffer_size (_jack_client)));
        }
 
-       return ret ? 0 : -1;
+       return _jack_port == 0 ? -1 : 0;
 }
 
 XMLNode& 
@@ -477,12 +409,10 @@ Port::get_state () const
        XMLNode* root = new XMLNode ("MIDI-port");
        root->add_property ("tag", _tagname);
 
-       if (_mode == O_RDONLY) {
+       if (_flags == IsInput) {
                root->add_property ("mode", "input");
-       } else if (_mode == O_WRONLY) {
-               root->add_property ("mode", "output");
        } else {
-               root->add_property ("mode", "duplex");
+               root->add_property ("mode", "output");
        }
        
 #if 0
@@ -498,9 +428,9 @@ Port::get_state () const
        write (device_inquiry, sizeof (device_inquiry), 0);
 #endif
 
-       if (_jack_output_port) {
+       if (_jack_port) {
                
-               const char** jc = jack_port_get_connections (_jack_output_port);
+               const char** jc = jack_port_get_connections (_jack_port);
                string connection_string;
                if (jc) {
                        for (int i = 0; jc[i]; ++i) {
@@ -513,34 +443,11 @@ Port::get_state () const
                }
                
                if (!connection_string.empty()) {
-                       root->add_property ("outbound", connection_string);
+                       root->add_property ("connections", connection_string);
                }
        } else {
-               if (!_outbound_connections.empty()) {
-                       root->add_property ("outbound", _outbound_connections);
-               }
-       }
-
-       if (_jack_input_port) {
-
-               const char** jc = jack_port_get_connections (_jack_input_port);
-               string connection_string;
-               if (jc) {
-                       for (int i = 0; jc[i]; ++i) {
-                               if (i > 0) {
-                                       connection_string += ',';
-                               }
-                               connection_string += jc[i];
-                       }
-                       free (jc);
-               }
-
-               if (!connection_string.empty()) {
-                       root->add_property ("inbound", connection_string);
-               }
-       } else {
-               if (!_inbound_connections.empty()) {
-                       root->add_property ("inbound", _inbound_connections);
+               if (!_connections.empty()) {
+                       root->add_property ("connections", _connections);
                }
        }
 
@@ -552,39 +459,29 @@ Port::set_state (const XMLNode& node)
 {
        const XMLProperty* prop;
 
-       if ((prop = node.property ("inbound")) != 0 && _jack_input_port) {
-               _inbound_connections = prop->value ();
-       }
-
-       if ((prop = node.property ("outbound")) != 0 && _jack_output_port) {
-               _outbound_connections = prop->value();
+       if ((prop = node.property ("connections")) != 0 && _jack_port) {
+               _connections = prop->value ();
        }
 }
 
 void
 Port::make_connections ()
 {
-       if (!_inbound_connections.empty()) {
+       if (!_connections.empty()) {
                vector<string> ports;
-               split (_inbound_connections, ports, ',');
+               split (_connections, ports, ',');
                for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
                        if (_jack_client) {
-                               jack_connect (_jack_client, (*x).c_str(), jack_port_name (_jack_input_port));
+                               if (receives_input()) {
+                                       jack_connect (_jack_client, (*x).c_str(), jack_port_name (_jack_port));
+                               } else {
+                                       jack_connect (_jack_client, jack_port_name (_jack_port), (*x).c_str());
+                               }
                                /* ignore failures */
                        }
                }
        }
 
-       if (!_outbound_connections.empty()) {
-               vector<string> ports;
-               split (_outbound_connections, ports, ',');
-               for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
-                       if (_jack_client) {
-                               jack_connect (_jack_client, jack_port_name (_jack_output_port), (*x).c_str());
-                               /* ignore failures */
-                       }
-               }
-       }
        connect_connection.disconnect ();
 }
 
@@ -604,7 +501,7 @@ void
 Port::reestablish (void* jack)
 {
        _jack_client = static_cast<jack_client_t*> (jack);
-       int const r = create_ports ();
+       int const r = create_port ();
 
        if (r) {
                PBD::error << "could not reregister ports for " << name() << endmsg;
index 32b6ff8fe17cf9aa4e50259e2da24d426f8b723e..aa8ac6ae35f9cbcb518883c69d74f3e7bb0d05a1 100644 (file)
@@ -124,7 +124,7 @@ void
 MIDIControllable::learn_about_external_control ()
 {
        drop_external_control ();
-       _port.input()->any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
+       _port.parser()->any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
 }
 
 void
@@ -268,7 +268,7 @@ MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/)
 
        /* if the our port doesn't do input anymore, forget it ... */
 
-       if (!_port.input()) {
+       if (!_port.parser()) {
                return;
        }
 
@@ -288,11 +288,11 @@ MIDIControllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
        control_channel = chn;
        control_additional = additional;
 
-       if (_port.input() == 0) {
+       if (_port.parser() == 0) {
                return;
        }
 
-       Parser& p = *_port.input();
+       Parser& p = *_port.parser();
 
        int chn_i = chn;
        switch (ev) {
index a77335fa7a890dacb2b590f039335bb2ee1844b0..79835835a4b652842e43303a3208666633dd9b5f 100644 (file)
@@ -127,11 +127,11 @@ MIDIInvokable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
        control_channel = chn;
        control_additional = additional;
 
-       if (_port.input() == 0) {
+       if (_port.parser() == 0) {
                return;
        }
 
-       Parser& p = *_port.input();
+       Parser& p = *_port.parser();
 
        int chn_i = chn;
 
index f25b31439d2dff30cded8913793b3cff1f5f3621..073d0c475fac7030526da8505a795d0b2e6c4cca 100644 (file)
@@ -563,11 +563,11 @@ MackieControlProtocol::connect_session_signals()
 }
 
 void 
-MackieControlProtocol::add_port (MIDI::Port & midi_port, int number)
+MackieControlProtocol::add_port (MIDI::Port & midi_input_port, MIDI::Port & midi_output_port, int number)
 {
-       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1\n", midi_port.name()));
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1 %2\n", midi_input_port.name(), midi_output_port.name()));
 
-       MackiePort * sport = new MackiePort (*this, midi_port, number);
+       MackiePort * sport = new MackiePort (*this, midi_input_port, midi_output_port, number);
        _ports.push_back (sport);
        
        sport->init_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
@@ -579,18 +579,19 @@ void
 MackieControlProtocol::create_ports()
 {
        MIDI::Manager * mm = MIDI::Manager::instance();
-       MIDI::Port * midi_port = mm->add_port (new MIDI::Port (default_port_name, O_RDWR, session->engine().jack()));
+       MIDI::Port * midi_input_port = mm->add_port (new MIDI::Port (default_port_name, MIDI::Port::IsInput, session->engine().jack()));
+       MIDI::Port * midi_output_port = mm->add_port (new MIDI::Port (default_port_name, MIDI::Port::IsOutput, session->engine().jack()));
 
        // open main port               
 
-       if (!midi_port->ok()) {
+       if (!midi_input_port->ok() || !midi_output_port->ok()) {
                ostringstream os;
-               os << string_compose (_("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name);
+               os << _("Mackie control MIDI ports could not be created; Mackie control disabled");
                error << os.str() << endmsg;
                throw MackieControlException (os.str());
        }
 
-       add_port (*midi_port, 0);
+       add_port (*midi_input_port, *midi_output_port, 0);
 
        // open extender ports. Up to 9. Should be enough.
        // could also use mm->get_midi_ports()
@@ -600,9 +601,10 @@ MackieControlProtocol::create_ports()
        for (int index = 1; index <= 9; ++index) {
                ostringstream os;
                os << ext_port_base << index;
-               MIDI::Port * midi_port = mm->add_port (new MIDI::Port (os.str(), O_RDWR, session->engine().jack()));
-               if (midi_port->ok()) {
-                       add_port (*midi_port, index);
+               MIDI::Port * midi_input_port = mm->add_port (new MIDI::Port (os.str(), MIDI::Port::IsInput, session->engine().jack()));
+               MIDI::Port * midi_output_port = mm->add_port (new MIDI::Port (os.str(), MIDI::Port::IsOutput, session->engine().jack()));
+               if (midi_input_port->ok() && midi_output_port->ok()) {
+                       add_port (*midi_input_port, *midi_output_port, index);
                }
        }
 }
index d920173eca854f7372f719e41a5a9dbe8479c2ba..f84530c733d623e8b65e93be46dd4db9711a7856 100644 (file)
@@ -266,7 +266,7 @@ class MackieControlProtocol
        */
        bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
 
-       void add_port(MIDI::Port &, int number);
+       void add_port (MIDI::Port &, MIDI::Port &, int number);
 
        /**
           Read session data and send to surface. Includes
index 5d8ea56a690062d45125613a557e4b716e80d3c3..1443aaa425514fca64ea5fce4e280fdf0af10466 100644 (file)
@@ -48,12 +48,12 @@ MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
 // The MCU extender sysex header
 MidiByteArray mackie_sysex_hdr_xt ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x11 );
 
-MackiePort::MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t port_type )
-  : SurfacePort( port, number )
-  , _mcp( mcp )
-  , _port_type( port_type )
-  , _emulation( none )
-  , _initialising( true )
+MackiePort::MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t port_type)
+       : SurfacePort (input_port, output_port, number)
+       , _mcp( mcp )
+       , _port_type( port_type )
+       , _emulation( none )
+       , _initialising( true )
 {
        DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::MackiePort\n");
 }
@@ -91,7 +91,7 @@ void MackiePort::open()
 {
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::open %1\n", *this));
        
-       port().input()->sysex.connect_same_thread (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
+       input_port().parser()->sysex.connect_same_thread (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
                     
        // make sure the device is connected
        init();
@@ -147,7 +147,7 @@ MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
        {
                finalise_init( false );
                ostringstream os;
-               os << "expecting 18 bytes, read " << bytes << " from " << port().name();
+               os << "expecting 18 bytes, read " << bytes << " from " << input_port().name();
                throw MackieControlException( os.str() );
        }
 
@@ -169,7 +169,7 @@ MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & by
        {
                finalise_init( false );
                ostringstream os;
-               os << "expecting 14 bytes, read " << bytes << " from " << port().name();
+               os << "expecting 14 bytes, read " << bytes << " from " << input_port().name();
                throw MackieControlException( os.str() );
        }
        
@@ -273,7 +273,7 @@ void MackiePort::finalise_init( bool yn )
 void MackiePort::connect_any()
 {
        if (!any_connection.connected()) {
-               port().input()->any.connect_same_thread (any_connection, boost::bind (&MackiePort::handle_midi_any, this, _1, _2, _3));
+               input_port().parser()->any.connect_same_thread (any_connection, boost::bind (&MackiePort::handle_midi_any, this, _1, _2, _3));
        }
 }
 
index 292fc2ac13866862c557468d1baede77e1ee3103..65dcf850b1e640892305c71ecf6c4ae5cca5402c 100644 (file)
@@ -43,7 +43,7 @@ public:
        enum port_type_t { mcu, ext };
        enum emulation_t { none, mackie, bcf2000 };
        
-       MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t = mcu );
+       MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t = mcu);
        ~MackiePort();
 
        virtual void open();
index 9dd456157e291fe9d935d1ec25036bae1fa0d5c1..994fdfd50a4a9bd3ae075a92d3626389d63b66a6 100644 (file)
@@ -36,12 +36,12 @@ using namespace std;
 using namespace Mackie;
 
 SurfacePort::SurfacePort()
-: _port( 0 ), _number( 0 ), _active( false )
+       : _input_port (0), _output_port (0), _number (0), _active (false)
 {
 }
 
-SurfacePort::SurfacePort( MIDI::Port & port, int number )
-: _port( &port ), _number( number ), _active( false )
+SurfacePort::SurfacePort (MIDI::Port & input_port, MIDI::Port & output_port, int number)
+       : _input_port (&input_port), _output_port (&output_port), _number (number), _active (false)
 {
 }
 
@@ -90,7 +90,7 @@ MidiByteArray SurfacePort::read()
 #endif
        
        // read port and copy to return value
-       int nread = port().read( buf, sizeof (buf) );
+       int nread = input_port().read( buf, sizeof (buf) );
 
        if (nread >= 0) {
                retval.copy( nread, buf );
@@ -107,7 +107,7 @@ MidiByteArray SurfacePort::read()
                if ( errno != EAGAIN )
                {
                        ostringstream os;
-                       os << "Surface: error reading from port: " << port().name();
+                       os << "Surface: error reading from port: " << input_port().name();
                        os << ": " << errno << fetch_errmsg( errno );
 
                        cout << os.str() << endl;
@@ -134,17 +134,17 @@ void SurfacePort::write( const MidiByteArray & mba )
        Glib::RecMutex::Lock lock( _rwlock );
        if ( !active() ) return;
 
-       int count = port().write( mba.bytes().get(), mba.size(), 0);
+       int count = output_port().write( mba.bytes().get(), mba.size(), 0);
        if ( count != (int)mba.size() )
        {
                if ( errno == 0 )
                {
-                       cout << "port overflow on " << port().name() << ". Did not write all of " << mba << endl;
+                       cout << "port overflow on " << output_port().name() << ". Did not write all of " << mba << endl;
                }
                else if ( errno != EAGAIN )
                {
                        ostringstream os;
-                       os << "Surface: couldn't write to port " << port().name();
+                       os << "Surface: couldn't write to port " << output_port().name();
                        os << ", error: " << fetch_errmsg( errno ) << "(" << errno << ")";
                        
                        cout << os.str() << endl;
@@ -173,7 +173,7 @@ void SurfacePort::write_sysex( MIDI::byte msg )
 ostream & Mackie::operator << ( ostream & os, const SurfacePort & port )
 {
        os << "{ ";
-       os << "name: " << port.port().name();
+       os << "name: " << port.input_port().name() << " " << port.output_port().name();
        os << "; ";
        os << " }";
        return os;
index 86ec8ffd9e38bd72f6283587df3885d552142683..214c8e6291fa003a80a29b32fed1ea520b238927 100644 (file)
@@ -37,7 +37,7 @@ namespace Mackie
 class SurfacePort
 {
 public:
-       SurfacePort( MIDI::Port & port, int number );
+       SurfacePort (MIDI::Port & input_port, MIDI::Port & output_port, int number);
        virtual ~SurfacePort();
        
        // when this is successful, active() should return true
@@ -60,8 +60,10 @@ public:
        /// return the correct sysex header for this port
        virtual const MidiByteArray & sysex_hdr() const = 0;
 
-       MIDI::Port & port() { return *_port; }
-       const MIDI::Port & port() const { return *_port; }
+       MIDI::Port & input_port() { return *_input_port; }
+       const MIDI::Port & input_port() const { return *_input_port; }
+       MIDI::Port & output_port() { return *_output_port; }
+       const MIDI::Port & output_port() const { return *_output_port; }
        
        // all control notofications are sent from here
        PBD::Signal3<void,SurfacePort &, Control &, const ControlState &> control_event;
@@ -90,7 +92,8 @@ protected:
        SurfacePort();
        
 private:
-       MIDI::Port * _port;
+       MIDI::Port * _input_port;
+       MIDI::Port * _output_port;
        int _number;
        bool _active;