/*
- Copyright (C) 1998-2010 Paul Barton-Davis
+ Copyright (C) 1998-2010 Paul Barton-Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
*/
-#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 <pthread.h>
#include "pbd/xml++.h"
+#ifndef PLATFORM_WINDOWS
#include "pbd/crossthread.h"
+#endif
#include "pbd/signals.h"
#include "pbd/ringbuffer.h"
-#include "evoral/Event.hpp"
-#include "evoral/EventRingBuffer.hpp"
-
+#include "midi++/libmidi_visibility.h"
#include "midi++/types.h"
#include "midi++/parser.h"
class Channel;
class PortRequest;
-class Port {
+class LIBMIDIPP_API Port {
public:
enum Flags {
- IsInput = JackPortIsInput,
- IsOutput = JackPortIsOutput,
+ IsInput = 0x1, /* MUST MATCH JACK's JackPortIsInput */
+ IsOutput = 0x2, /* MUST MATCH JACK's JackPortIsOutput */
};
-
- Port (std::string const &, Flags, 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?
+ 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 */, int /* total_usecs_to_wait */) {}
- void parse (nframes_t timestamp);
-
/** 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.
+ * @return File descriptor, or -1 if not selectable.
*/
- int selectable () const {
- return xthread.selectable();
- }
+ virtual int selectable () const = 0;
- Channel *channel (channel_t chn) {
+ 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; }
+ virtual bool centrally_parsed() const;
+ void set_centrally_parsed (bool yn) { _centrally_parsed = yn; }
+
bool receives_input () const {
return _flags == IsInput;
}
XMLNode& get_state();
};
- nframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
-
- void reestablish (jack_client_t *);
- void reconnect ();
-
- static void set_process_thread (pthread_t);
- static pthread_t get_process_thread () { return _process_thread; }
- static bool is_process_thread();
-
static std::string state_node_name;
-
- 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;
- size_t _number;
- Channel *_channel[16];
- Parser *_parser;
-
- int create_port ();
-
- jack_client_t* _jack_client;
- 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 _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;
+ protected:
+ bool _ok;
+ std::string _tagname;
+ Channel* _channel[16];
+ Parser* _parser;
+ Flags _flags;
+ bool _centrally_parsed;
- RingBuffer< Evoral::Event<double> > output_fifo;
- Evoral::EventRingBuffer<timestamp_t> input_fifo;
-
- Glib::Mutex output_fifo_lock;
-
- Flags _flags;
+ void init (std::string const &, Flags);
};
-struct PortSet {
+struct LIBMIDIPP_API PortSet {
PortSet (std::string str) : owner (str) { }
-
+
std::string owner;
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__