diff options
author | David Robillard <d@drobilla.net> | 2006-06-08 23:46:42 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-06-08 23:46:42 +0000 |
commit | 74dd5bd7060b337964d5ea5a3d419c26a62c10a6 (patch) | |
tree | 8a1ece4e1c6eb2b3a09c149b8b2afc71f70a024c /libs/midi++2/midi++ | |
parent | 0c1b9afc634d098ac6029acb3508d25823d0fc14 (diff) |
Committed filthy mess of a working copy solely for moving between machines.
Nothing to see here, move along now...
git-svn-id: svn://localhost/trunk/ardour2midi@575 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/midi++2/midi++')
-rw-r--r-- | libs/midi++2/midi++/alsa_rawmidi.h | 3 | ||||
-rw-r--r-- | libs/midi++2/midi++/alsa_sequencer.h | 5 | ||||
-rw-r--r-- | libs/midi++2/midi++/channel.h | 111 | ||||
-rw-r--r-- | libs/midi++2/midi++/controllable.h | 2 | ||||
-rw-r--r-- | libs/midi++2/midi++/coremidi_midiport.h | 50 | ||||
-rw-r--r-- | libs/midi++2/midi++/factory.h | 2 | ||||
-rw-r--r-- | libs/midi++2/midi++/fd_midiport.h | 8 | ||||
-rw-r--r-- | libs/midi++2/midi++/manager.h | 33 | ||||
-rw-r--r-- | libs/midi++2/midi++/nullmidi.h | 5 | ||||
-rw-r--r-- | libs/midi++2/midi++/port.h | 115 | ||||
-rw-r--r-- | libs/midi++2/midi++/types.h | 4 |
11 files changed, 181 insertions, 157 deletions
diff --git a/libs/midi++2/midi++/alsa_rawmidi.h b/libs/midi++2/midi++/alsa_rawmidi.h index 655b673174..f6c17541c2 100644 --- a/libs/midi++2/midi++/alsa_rawmidi.h +++ b/libs/midi++2/midi++/alsa_rawmidi.h @@ -29,6 +29,8 @@ #include <midi++/port.h> #include <midi++/fd_midiport.h> +namespace MIDI { + class ALSA_RawMidiPort : public MIDI::FD_MidiPort { @@ -38,6 +40,7 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort virtual ~ALSA_RawMidiPort () {} }; +} // namespace MIDI #endif // __alsa_rawmidi_h__ diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h index 8ddb2a7dd7..cb02ed961c 100644 --- a/libs/midi++2/midi++/alsa_sequencer.h +++ b/libs/midi++2/midi++/alsa_sequencer.h @@ -44,9 +44,8 @@ class ALSA_SequencerMidiPort : public Port protected: /* Direct I/O */ - - int write (byte *msg, size_t msglen); - int read (byte *buf, size_t max); + int write (byte *msg, size_t msglen, timestamp_t timestamp); + int read (byte *buf, size_t max, timestamp_t timestamp); private: snd_seq_t *seq; diff --git a/libs/midi++2/midi++/channel.h b/libs/midi++2/midi++/channel.h index f534f7e6da..0d24bf8bbe 100644 --- a/libs/midi++2/midi++/channel.h +++ b/libs/midi++2/midi++/channel.h @@ -32,17 +32,22 @@ namespace MIDI { class Port; +/** Stateful MIDI channel class. + * + * This remembers various useful information about the current 'state' of a + * MIDI channel (eg current pitch bend value). + */ class Channel : public sigc::trackable { public: Channel (byte channel_number, Port &); - Port &midi_port() { return port; } - byte channel() { return channel_number; } - byte program() { return program_number; } - byte bank() { return bank_number; } - byte pressure () { return chanpress; } - byte poly_pressure (byte n) { return polypress[n]; } + Port &midi_port() { return _port; } + byte channel() { return _channel_number; } + byte program() { return _program_number; } + byte bank() { return _bank_number; } + byte pressure () { return _chanpress; } + byte poly_pressure (byte n) { return _polypress[n]; } byte last_note_on () { return _last_note_on; @@ -58,53 +63,52 @@ class Channel : public sigc::trackable { } pitchbend_t pitchbend () { - return pitch_bend; + return _pitch_bend; } controller_value_t controller_value (byte n) { - return controller_val[n%128]; + return _controller_val[n%128]; } controller_value_t *controller_addr (byte n) { - return &controller_val[n%128]; + return &_controller_val[n%128]; } void set_controller (byte n, byte val) { - controller_val[n%128] = val; + _controller_val[n%128] = val; } - bool channel_msg (byte id, byte val1, byte val2); - - bool all_notes_off () { - return channel_msg (MIDI::controller, 123, 0); + bool channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp); + bool all_notes_off (timestamp_t timestamp) { + return channel_msg (MIDI::controller, 123, 0, timestamp); } - bool control (byte id, byte value) { - return channel_msg (MIDI::controller, id, value); + bool control (byte id, byte value, timestamp_t timestamp) { + return channel_msg (MIDI::controller, id, value, timestamp); } - bool note_on (byte note, byte velocity) { - return channel_msg (MIDI::on, note, velocity); + bool note_on (byte note, byte velocity, timestamp_t timestamp) { + return channel_msg (MIDI::on, note, velocity, timestamp); } - bool note_off (byte note, byte velocity) { - return channel_msg (MIDI::off, note, velocity); + bool note_off (byte note, byte velocity, timestamp_t timestamp) { + return channel_msg (MIDI::off, note, velocity, timestamp); } - bool aftertouch (byte value) { - return channel_msg (MIDI::chanpress, value, 0); + bool aftertouch (byte value, timestamp_t timestamp) { + return channel_msg (MIDI::chanpress, value, 0, timestamp); } - bool poly_aftertouch (byte note, byte value) { - return channel_msg (MIDI::polypress, note, value); + bool poly_aftertouch (byte note, byte value, timestamp_t timestamp) { + return channel_msg (MIDI::polypress, note, value, timestamp); } - bool program_change (byte value) { - return channel_msg (MIDI::program, value, 0); + bool program_change (byte value, timestamp_t timestamp) { + return channel_msg (MIDI::program, value, 0, timestamp); } - bool pitchbend (byte msb, byte lsb) { - return channel_msg (MIDI::pitchbend, lsb, msb); + bool pitchbend (byte msb, byte lsb, timestamp_t timestamp) { + return channel_msg (MIDI::pitchbend, lsb, msb, timestamp); } protected: @@ -113,34 +117,33 @@ class Channel : public sigc::trackable { void connect_output_signals (); private: - Port &port; + Port & _port; /* Current channel values */ - - byte channel_number; - byte bank_number; - byte program_number; - byte rpn_msb; - byte rpn_lsb; - byte nrpn_msb; - byte nrpn_lsb; - byte chanpress; - byte polypress[128]; - bool controller_14bit[128]; - controller_value_t controller_val[128]; - byte controller_msb[128]; - byte controller_lsb[128]; - byte _last_note_on; - byte _last_on_velocity; - byte _last_note_off; - byte _last_off_velocity; - pitchbend_t pitch_bend; - bool _omni; - bool _poly; - bool _mono; - size_t _notes_on; - - void reset (bool notes_off = true); + byte _channel_number; + byte _bank_number; + byte _program_number; + byte _rpn_msb; + byte _rpn_lsb; + byte _nrpn_msb; + byte _nrpn_lsb; + byte _chanpress; + byte _polypress[128]; + bool _controller_14bit[128]; + controller_value_t _controller_val[128]; + byte _controller_msb[128]; + byte _controller_lsb[128]; + byte _last_note_on; + byte _last_on_velocity; + byte _last_note_off; + byte _last_off_velocity; + pitchbend_t _pitch_bend; + bool _omni; + bool _poly; + bool _mono; + size_t _notes_on; + + void reset (timestamp_t timestamp, nframes_t nframes, bool notes_off = true); void process_note_off (Parser &, EventTwoBytes *); void process_note_on (Parser &, EventTwoBytes *); diff --git a/libs/midi++2/midi++/controllable.h b/libs/midi++2/midi++/controllable.h index 3fa108bb46..44249cfa4f 100644 --- a/libs/midi++2/midi++/controllable.h +++ b/libs/midi++2/midi++/controllable.h @@ -60,7 +60,7 @@ class Controllable : public sigc::trackable std::string control_description() const { return _control_description; } - void send_midi_feedback (float); + void send_midi_feedback (float val, timestamp_t timestamp); private: bool bistate; diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h index e02a225784..046b170bce 100644 --- a/libs/midi++2/midi++/coremidi_midiport.h +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -32,35 +32,35 @@ namespace MIDI { - class CoreMidi_MidiPort:public Port { - public: - CoreMidi_MidiPort(PortRequest & req); - virtual ~ CoreMidi_MidiPort(); +class CoreMidi_MidiPort:public Port { + public: + CoreMidi_MidiPort(PortRequest & req); + virtual ~ CoreMidi_MidiPort(); - virtual int selectable() const { - return -1; - } - protected: - /* Direct I/O */ - int write(byte * msg, size_t msglen); - int read(byte * buf, size_t max) { - return 0; - } /* CoreMidi callback */ - static void read_proc(const MIDIPacketList * pktlist, - void *refCon, void *connRefCon); + virtual int selectable() const { + return -1; + } + protected: + /* Direct I/O */ + int write (byte *msg, size_t msglen, timestamp_t timestamp); + int read (byte *buf, size_t max, timestamp_t timestamp); - private: - byte midi_buffer[1024]; - MIDIClientRef midi_client; - MIDIEndpointRef midi_destination; - MIDIEndpointRef midi_source; + /* CoreMidi callback */ + static void read_proc(const MIDIPacketList * pktlist, + void *refCon, void *connRefCon); - int Open(PortRequest & req); - void Close(); - static MIDITimeStamp MIDIGetCurrentHostTime(); + private: + byte midi_buffer[1024]; + MIDIClientRef midi_client; + MIDIEndpointRef midi_destination; + MIDIEndpointRef midi_source; - bool firstrecv; - }; + int Open(PortRequest & req); + void Close(); + static MIDITimeStamp MIDIGetCurrentHostTime(); + + bool firstrecv; +}; }; /* namespace MIDI */ diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h index 1543f68cdc..3fa57b6676 100644 --- a/libs/midi++2/midi++/factory.h +++ b/libs/midi++2/midi++/factory.h @@ -29,7 +29,7 @@ namespace MIDI { class PortFactory { public: - Port *create_port (PortRequest &req); + Port *create_port (PortRequest &req, void* data); static void add_port_request (std::vector<PortRequest *> &reqs, const std::string &reqstr); diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h index 853af9d7b4..e84dc47794 100644 --- a/libs/midi++2/midi++/fd_midiport.h +++ b/libs/midi++2/midi++/fd_midiport.h @@ -53,7 +53,10 @@ class FD_MidiPort : public Port int _fd; virtual void open (PortRequest &req); - virtual int write (byte *msg, size_t msglen) { + /* Direct I/O */ + + virtual int write (byte *msg, size_t msglen, + timestamp_t timestamp) { int nwritten; if ((_mode & O_ACCMODE) == O_RDONLY) { @@ -80,7 +83,8 @@ class FD_MidiPort : public Port return nwritten; } - virtual int read (byte *buf, size_t max); + virtual int read (byte *buf, size_t max, + timestamp_t timestamp); private: static std::string *midi_dirpath; diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index 4889aad8c9..ddf5c0f8cd 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -29,10 +29,27 @@ namespace MIDI { +/** Creates, stores, and manages system MIDI ports. + */ class Manager { public: ~Manager (); + void set_api_data(void* data) { api_data = data; } + + /** Signal the start of an audio cycle. + * This MUST be called before any reading/writing for this cycle. + * Realtime safe. + */ + void cycle_start(nframes_t nframes); + + /** Signal the end of an audio cycle. + * This signifies that the cycle began with @ref cycle_start has ended. + * This MUST be called at the end of each cycle. + * Realtime safe. + */ + void cycle_end(); + Port *add_port (PortRequest &); int remove_port (std::string port); @@ -41,20 +58,6 @@ class Manager { size_t nports () { return ports_by_device.size(); } - /* defaults for clients who are not picky */ - - Port *inputPort; - Port *outputPort; - channel_t inputChannelNumber; - channel_t outputChannelNumber; - - int set_input_port (size_t port); - int set_input_port (std::string); - int set_output_port (size_t port); - int set_output_port (std::string); - int set_input_channel (channel_t); - int set_output_channel (channel_t); - int foreach_port (int (*func)(const Port &, size_t n, void *), void *arg); @@ -80,6 +83,8 @@ class Manager { PortMap ports_by_device; /* canonical */ PortMap ports_by_tag; /* may contain duplicate Ports */ + void *api_data; + void close_ports (); }; diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h index a94b1015b0..04c7d438bf 100644 --- a/libs/midi++2/midi++/nullmidi.h +++ b/libs/midi++2/midi++/nullmidi.h @@ -46,11 +46,12 @@ class Null_MidiPort : public Port virtual ~Null_MidiPort () {}; - virtual int write (byte *msg, size_t msglen) { + /* Direct I/O */ + int write (byte *msg, size_t msglen, timestamp_t timestamp) { return msglen; } - virtual int read (byte *buf, size_t max) { + int read (byte *buf, size_t max, timestamp_t timestamp) { return 0; } diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index 442cc4e5ed..919afb3755 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -37,6 +37,7 @@ class Port : public sigc::trackable { public: enum Type { Unknown, + JACK_Midi, ALSA_RawMidi, ALSA_Sequencer, CoreMidi_MidiPort, @@ -44,42 +45,64 @@ class Port : public sigc::trackable { FIFO, }; - Port (PortRequest &); virtual ~Port (); - /* Direct I/O */ + // 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); - /** \return number of bytes successfully written */ - virtual int write (byte *msg, size_t msglen) = 0; + /* Only for use by MidiManager. Don't ever call this. */ + virtual void cycle_end(); - /** \return number of bytes successfully written to \a buf */ - virtual int read (byte *buf, size_t max) = 0; + /* 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; + + /** Write a message to port. + * @return true on success. + * FIXME: describe semantics here + */ + bool midimsg (byte *msg, size_t len, timestamp_t timestamp) { + return !(write (msg, len, timestamp) == (int) len); + } - /** Slow down I/O to a loop of single byte emissions - interspersed with a busy loop of 10000 * this value. + bool clock (timestamp_t timestamp); - This may be ignored by a particular instance of this virtual - class. See FD_MidiPort for an example of where it used. */ + /** 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; } /* 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; - void selector_read_callback (Select::Selectable *, Select::Condition); - - static void xforms_read_callback (int cond, int fd, void *ptr); - static void gtk_read_callback (void *ptr, int fd, int cond); - - static void write_callback (byte *msg, unsigned int len, void *); - Channel *channel (channel_t chn) { return _channel[chn&0x7F]; } - Parser *input() { return input_parser; } - Parser *output() { return output_parser; } + Parser *input() { return input_parser; } + Parser *output() { return output_parser; } void iostat (int *written, int *read, const size_t **in_counts, @@ -99,47 +122,31 @@ class Port : public sigc::trackable { } } - /** Write a message. - * \return true on success. */ - bool midimsg (byte *msg, size_t len) { - return !(write (msg, len) == (int) len); - } - - /** Write a 3-byte message. - * \return true on success. */ - bool three_byte_msg (byte a, byte b, byte c) { - byte msg[3]; - - msg[0] = a; - msg[1] = b; - msg[2] = c; - - return !(write (msg, 3) == 3); - } - 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(); } + Type type () const { return _type; } + int mode () const { return _mode; } + bool ok () const { return _ok; } + size_t number () const { return _number; } protected: - bool _ok; - Type _type; - std::string _devname; - std::string _tagname; - int _mode; - size_t _number; - Channel *_channel[16]; + 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; + unsigned int bytes_written; + unsigned int bytes_read; + Parser *input_parser; + Parser *output_parser; + size_t slowdown; private: static size_t nports; diff --git a/libs/midi++2/midi++/types.h b/libs/midi++2/midi++/types.h index b9d9bf33e7..dc70381d5b 100644 --- a/libs/midi++2/midi++/types.h +++ b/libs/midi++2/midi++/types.h @@ -4,9 +4,11 @@ namespace MIDI { typedef char channel_t; - typedef float controller_value_t; + typedef float controller_value_t; typedef unsigned char byte; typedef unsigned short pitchbend_t; + typedef unsigned int timestamp_t; + typedef unsigned int nframes_t; enum eventType { none = 0x0, |