summaryrefslogtreecommitdiff
path: root/libs/midi++2/midi++/port.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/midi++2/midi++/port.h')
-rw-r--r--libs/midi++2/midi++/port.h145
1 files changed, 101 insertions, 44 deletions
diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h
index e7b532013e..a2315f7284 100644
--- a/libs/midi++2/midi++/port.h
+++ b/libs/midi++2/midi++/port.h
@@ -16,8 +16,8 @@
*/
-#ifndef __libmidi_port_h__
-#define __libmidi_port_h__
+#ifndef __libmidi_port_base_h__
+#define __libmidi_port_base_h__
#include <string>
#include <iostream>
@@ -34,70 +34,127 @@
#include "midi++/types.h"
#include "midi++/parser.h"
-#include "midi++/port_base.h"
namespace MIDI {
class Channel;
class PortRequest;
-class Port : public PortBase {
+class Port {
public:
- Port (std::string const &, PortBase::Flags, jack_client_t *);
- Port (const XMLNode&, jack_client_t *);
- ~Port ();
+ enum Flags {
+ IsInput = JackPortIsInput,
+ IsOutput = JackPortIsOutput,
+ };
+
+ Port (std::string const &, Flags);
+ Port (const XMLNode&);
+ virtual ~Port ();
XMLNode& get_state () const;
void set_state (const XMLNode&);
- void cycle_start (pframes_t nframes);
- void cycle_end ();
+ // FIXME: make Manager a friend of port so these can be hidden?
+
+ /* Only for use by MidiManager. Don't ever call this. */
+ virtual void cycle_start (pframes_t nframes) {}
+ /* Only for use by MidiManager. Don't ever call this. */
+ virtual void cycle_end () {}
+
+ /** Write a message to port.
+ * @param msg Raw MIDI message to send
+ * @param msglen Size of @a msg
+ * @param timestamp Time stamp in frames of this message (relative to cycle start)
+ * @return number of bytes successfully written
+ */
+ virtual int write (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
+ */
+ 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) {}
+
+ /** Write a message to port.
+ * @return true on success.
+ * FIXME: describe semantics here
+ */
+ int midimsg (byte *msg, size_t len, timestamp_t timestamp) {
+ 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 */
+
+ /** Get the file descriptor for port.
+ * @return File descriptor, or -1 if not selectable.
+ */
+ virtual int selectable () const = 0;
+
+ Channel *channel (channel_t chn) {
+ return _channel[chn&0x7F];
+ }
+
+ Parser* parser () {
+ return _parser;
+ }
+
+ const char *name () const { return _tagname.c_str(); }
+ bool ok () const { return _ok; }
- void parse (framecnt_t timestamp);
- int write (byte *msg, size_t msglen, timestamp_t timestamp);
- int read (byte *buf, size_t bufsize);
- void drain (int check_interval_usecs);
- int selectable () const { return xthread.selectable(); }
+ virtual bool centrally_parsed() const;
+ void set_centrally_parsed (bool yn) { _centrally_parsed = yn; }
- pframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
+ bool receives_input () const {
+ return _flags == IsInput;
+ }
- void reestablish (jack_client_t *);
- void reconnect ();
+ bool sends_output () const {
+ return _flags == IsOutput;
+ }
- static void set_process_thread (pthread_t);
- static pthread_t get_process_thread () { return _process_thread; }
- static bool is_process_thread();
+ struct Descriptor {
+ std::string tag;
+ Flags flags;
- static PBD::Signal0<void> MakeConnections;
- static PBD::Signal0<void> JackHalted;
+ Descriptor (const XMLNode&);
+ XMLNode& get_state();
+ };
-private:
- bool _currently_in_cycle;
- pframes_t _nframes_this_cycle;
- jack_client_t* _jack_client;
- jack_port_t* _jack_port;
- timestamp_t _last_write_timestamp;
- RingBuffer< Evoral::Event<double> > output_fifo;
- Evoral::EventRingBuffer<timestamp_t> input_fifo;
- Glib::Mutex output_fifo_lock;
- CrossThreadChannel xthread;
+ static std::string state_node_name;
- int create_port ();
+ protected:
+ bool _ok;
+ std::string _tagname;
+ Channel* _channel[16];
+ Parser* _parser;
+ Flags _flags;
+ bool _centrally_parsed;
- /** Channel used to signal to the MidiControlUI that input has arrived */
-
- 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 &, Flags);
+};
- static pthread_t _process_thread;
-
+struct PortSet {
+ PortSet (std::string str) : owner (str) { }
+
+ std::string owner;
+ std::list<XMLNode> ports;
};
+std::ostream & operator << (std::ostream& os, const Port& port);
+
} // namespace MIDI
-#endif // __libmidi_port_h__
+#endif // __libmidi_port_base_h__