X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmidi%2B%2B%2Fport.h;h=03abd1a41c9d382d208decb83eb76ef6a7210db4;hb=7a76168b662c4e4fa0eec3859e500cb0b2ac65e7;hp=e4338cf95226fceb940e398de10795f15c3394c4;hpb=99904735e066804358f1d0bd138a84f1e9ecda91;p=ardour.git diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index e4338cf952..03abd1a41c 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1998-99 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 @@ -16,141 +16,145 @@ */ -#ifndef __libmidi_port_h__ -#define __libmidi_port_h__ +#ifndef __libmidi_port_base_h__ +#define __libmidi_port_base_h__ #include +#include -#include +#include -#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" namespace MIDI { class Channel; class PortRequest; -class Port : public sigc::trackable { +class Port { public: - enum Type { - Unknown, - JACK_Midi, - ALSA_RawMidi, - ALSA_Sequencer, - CoreMidi_MidiPort, - Null, - FIFO + enum Flags { + IsInput = JackPortIsInput, + IsOutput = JackPortIsOutput, }; - - Port (PortRequest &); + + Port (std::string const &, Flags); + Port (const XMLNode&); virtual ~Port (); + XMLNode& get_state () const; + void set_state (const XMLNode&); + // 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(nframes_t nframes); /* Only for use by MidiManager. Don't ever call this. */ - virtual void cycle_end(); + virtual void cycle_start (pframes_t) {} + /* Only for use by MidiManager. Don't ever call this. */ + virtual void cycle_end () {} - /* Direct I/O */ - - /** Read a message from port. - * @param buf Raw MIDI message to send - * @param max Max size to write to @a buf - * @param timestamp Time stamp in frames of this message (relative to cycle start) - * @return number of bytes successfully written to \a buf - */ - virtual int read(byte *buf, size_t max, timestamp_t timestamp) = 0; - /** 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; + 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 + */ + 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 */ - bool midimsg (byte *msg, size_t len, timestamp_t timestamp) { + int midimsg (byte *msg, size_t len, timestamp_t timestamp) { return !(write (msg, len, timestamp) == (int) len); - } + } - bool clock (timestamp_t timestamp); + virtual void parse (framecnt_t timestamp) = 0; - /** Slow down I/O to a loop of single byte emissions - * interspersed with a busy loop of 10000 * this value. - * - * This may be ignored by a particular instance of this virtual - * class. See FD_MidiPort for an example of where it used. */ - void set_slowdown (size_t n) { slowdown = n; } + 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; + * @return File descriptor, or -1 if not 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; } - - void iostat (int *written, int *read, - const size_t **in_counts, - const size_t **out_counts) { - - *written = bytes_written; - *read = bytes_read; - if (input_parser) { - *in_counts = input_parser->message_counts(); - } else { - *in_counts = 0; - } - if (output_parser) { - *out_counts = output_parser->message_counts(); - } else { - *out_counts = 0; - } + Parser* parser () { + return _parser; } - bool clock (); - - const char *device () const { return _devname.c_str(); } - const char *name () const { return _tagname.c_str(); } - Type type () const { return _type; } - int mode () const { return _mode; } - bool ok () const { return _ok; } - size_t number () const { return _number; } + 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; + } + + bool sends_output () const { + return _flags == IsOutput; + } + + struct Descriptor { + std::string tag; + Flags flags; + + Descriptor (const XMLNode&); + XMLNode& get_state(); + }; + + static std::string state_node_name; protected: - bool _ok; - bool _currently_in_cycle; - nframes_t _nframes_this_cycle; - Type _type; - std::string _devname; - std::string _tagname; - int _mode; - size_t _number; - Channel *_channel[16]; - sigc::connection thru_connection; - unsigned int bytes_written; - unsigned int bytes_read; - Parser *input_parser; - Parser *output_parser; - size_t slowdown; - - private: - static size_t nports; + bool _ok; + std::string _tagname; + Channel* _channel[16]; + Parser* _parser; + Flags _flags; + bool _centrally_parsed; + + void init (std::string const &, Flags); +}; + +struct PortSet { + PortSet (std::string str) : owner (str) { } + + std::string owner; + std::list ports; }; +std::ostream & operator << (std::ostream& os, const Port& port); + } // namespace MIDI -#endif // __libmidi_port_h__ +#endif // __libmidi_port_base_h__