*/
-#ifndef __libmidi_port_h__
-#define __libmidi_port_h__
+#ifndef __libmidi_port_base_h__
+#define __libmidi_port_base_h__
#include <string>
#include <iostream>
-#include <jack/types.h>
-
#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"
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
* @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
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.
*/
- 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<void> MakeConnections;
- static PBD::Signal0<void> 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<double> > output_fifo;
- Evoral::EventRingBuffer<timestamp_t> input_fifo;
-
- Glib::Mutex output_fifo_lock;
-
+ void init (std::string const &, Flags);
};
struct PortSet {
std::list<XMLNode> 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__