X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmidi%2B%2B%2Fport.h;h=4e63d41141653f8e976e1acbf679f6e54eb06869;hb=4a71e6f28fed69ce8f82e98430180fdbf2da1684;hp=ca977fad2f44f03f1f5e3e9ce0e0551345da4714;hpb=ea23298f10e9587eba483cb54a6f7d75ca68126a;p=ardour.git diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index ca977fad2f..4e63d41141 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -16,22 +16,17 @@ */ -#ifndef __libmidi_port_h__ -#define __libmidi_port_h__ +#ifndef __libmidi_port_base_h__ +#define __libmidi_port_base_h__ #include #include -#include - #include "pbd/xml++.h" #include "pbd/crossthread.h" #include "pbd/signals.h" #include "pbd/ringbuffer.h" -#include "evoral/Event.hpp" -#include "evoral/EventRingBuffer.hpp" - #include "midi++/types.h" #include "midi++/parser.h" @@ -42,19 +37,17 @@ class PortRequest; class Port { public: - Port (std::string const &, int, jack_client_t *); - Port (const XMLNode&, jack_client_t *); - ~Port (); - - XMLNode& get_state () const; - void set_state (const XMLNode&); - - // FIXME: make Manager a friend of port so these can be hidden? + enum Flags { + IsInput = JackPortIsInput, + IsOutput = JackPortIsOutput, + }; + + Port (std::string const &, Flags); + Port (const XMLNode&); + virtual ~Port (); - /* Only for use by MidiManager. Don't ever call this. */ - void cycle_start(nframes_t nframes); - /* Only for use by MidiManager. Don't ever call this. */ - void cycle_end(); + virtual XMLNode& get_state () const; + virtual void set_state (const XMLNode&); /** Write a message to port. * @param msg Raw MIDI message to send @@ -62,17 +55,23 @@ class Port { * @param timestamp Time stamp in frames of this message (relative to cycle start) * @return number of bytes successfully written */ - int write (byte *msg, size_t msglen, timestamp_t timestamp); + virtual int write (const byte *msg, size_t msglen, timestamp_t timestamp) = 0; /** Read raw bytes from a port. * @param buf memory to store read data in * @param bufsize size of @a buf * @return number of bytes successfully read, negative if error */ - int read (byte *buf, size_t bufsize); + virtual int read (byte *buf, size_t bufsize) = 0; + + /** block until the output FIFO used by non-process threads + * is empty, checking every @a check_interval_usecs usecs + * for current status. Not to be called by a thread that + * executes any part of a JACK process callback (will + * simply return immediately in that situation). + */ + virtual void drain (int /* check_interval_usecs */) {} - void parse (nframes_t timestamp); - /** Write a message to port. * @return true on success. * FIXME: describe semantics here @@ -81,6 +80,8 @@ class Port { return !(write (msg, len, timestamp) == (int) len); } + virtual void parse (framecnt_t timestamp) = 0; + bool clock (timestamp_t timestamp); /* select(2)/poll(2)-based I/O */ @@ -88,84 +89,49 @@ class Port { /** Get the file descriptor for port. * @return File descriptor, or -1 if not selectable. */ - int selectable () const { - return xthread.selectable(); - } + virtual int selectable () const = 0; Channel *channel (channel_t chn) { 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; } + virtual bool centrally_parsed() const; + void set_centrally_parsed (bool yn) { _centrally_parsed = yn; } + + 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(); }; - nframes_t nframes_this_cycle() const { return _nframes_this_cycle; } + static std::string state_node_name; - void reestablish (void *); - void reconnect (); + protected: + bool _ok; + std::string _tagname; + Channel* _channel[16]; + Parser* _parser; + Flags _flags; + bool _centrally_parsed; - static void set_process_thread (pthread_t); - static pthread_t get_process_thread () { return _process_thread; } - static bool is_process_thread(); - - static PBD::Signal0 MakeConnections; - static PBD::Signal0 JackHalted; - -private: - bool _ok; - 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; - - void create_port_names (); - int create_ports (); - - 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; - 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; - 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); - - static pthread_t _process_thread; - - RingBuffer< Evoral::Event > output_fifo; - Evoral::EventRingBuffer input_fifo; - - Glib::Mutex output_fifo_lock; - + void init (std::string const &, Flags); }; struct PortSet { @@ -175,8 +141,8 @@ struct PortSet { std::list ports; }; -std::ostream & operator << ( std::ostream & os, const Port & port ); +std::ostream & operator << (std::ostream& os, const Port& port); } // namespace MIDI -#endif // __libmidi_port_h__ +#endif // __libmidi_port_base_h__