X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fmidi%2B%2B2%2Fmidi%2B%2B%2Fport.h;h=02cc340194b89f3a81be9dff8a85013b595c9816;hb=22fd92f97c5ff2bb1890a3b88085bed5c035498e;hp=e7b532013ebfe04cb8d61808d5afffb9220ecc70;hpb=1660f00ff3777b2bd52a4c73fe9aa43050f8ad34;p=ardour.git diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index e7b532013e..02cc340194 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -1,5 +1,5 @@ /* - 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 @@ -16,88 +16,138 @@ */ -#ifndef __libmidi_port_h__ -#define __libmidi_port_h__ +#ifndef __libmidi_port_base_h__ +#define __libmidi_port_base_h__ #include #include -#include +#include #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" -#include "midi++/port_base.h" namespace MIDI { class Channel; class PortRequest; -class Port : public PortBase { +class LIBMIDIPP_API Port { public: - Port (std::string const &, PortBase::Flags, jack_client_t *); - Port (const XMLNode&, jack_client_t *); - ~Port (); - - XMLNode& get_state () const; - void set_state (const XMLNode&); - - void cycle_start (pframes_t nframes); - void cycle_end (); - - 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(); } - - pframes_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 PBD::Signal0 MakeConnections; - static PBD::Signal0 JackHalted; - -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 > output_fifo; - Evoral::EventRingBuffer input_fifo; - Glib::Mutex output_fifo_lock; - CrossThreadChannel xthread; - - int create_port (); - - /** 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 (); + enum Flags { + IsInput = 0x1, /* MUST MATCH JACK's JackPortIsInput */ + IsOutput = 0x2, /* MUST MATCH JACK's JackPortIsOutput */ + }; + + Port (std::string const &, Flags); + Port (const XMLNode&); + virtual ~Port (); + + virtual XMLNode& get_state () const; + virtual void set_state (const XMLNode&); + + /** 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 (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 */, int /* total_usecs_to_wait */) {} + + /** 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; } + + 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; + std::string _tagname; + Channel* _channel[16]; + Parser* _parser; + Flags _flags; + bool _centrally_parsed; + void init (std::string const &, Flags); +}; - static pthread_t _process_thread; +struct LIBMIDIPP_API 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__