summaryrefslogtreecommitdiff
path: root/libs/midi++2
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-06-08 23:46:42 +0000
committerDavid Robillard <d@drobilla.net>2006-06-08 23:46:42 +0000
commit74dd5bd7060b337964d5ea5a3d419c26a62c10a6 (patch)
tree8a1ece4e1c6eb2b3a09c149b8b2afc71f70a024c /libs/midi++2
parent0c1b9afc634d098ac6029acb3508d25823d0fc14 (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')
-rw-r--r--libs/midi++2/SConscript14
-rw-r--r--libs/midi++2/alsa_sequencer_midiport.cc4
-rw-r--r--libs/midi++2/coremidi_midiport.cc2
-rw-r--r--libs/midi++2/fd_midiport.cc2
-rw-r--r--libs/midi++2/midi++/alsa_rawmidi.h3
-rw-r--r--libs/midi++2/midi++/alsa_sequencer.h5
-rw-r--r--libs/midi++2/midi++/channel.h111
-rw-r--r--libs/midi++2/midi++/controllable.h2
-rw-r--r--libs/midi++2/midi++/coremidi_midiport.h50
-rw-r--r--libs/midi++2/midi++/factory.h2
-rw-r--r--libs/midi++2/midi++/fd_midiport.h8
-rw-r--r--libs/midi++2/midi++/manager.h33
-rw-r--r--libs/midi++2/midi++/nullmidi.h5
-rw-r--r--libs/midi++2/midi++/port.h115
-rw-r--r--libs/midi++2/midi++/types.h4
-rw-r--r--libs/midi++2/midichannel.cc108
-rw-r--r--libs/midi++2/midicontrollable.cc4
-rw-r--r--libs/midi++2/midifactory.cc15
-rw-r--r--libs/midi++2/midimanager.cc124
-rw-r--r--libs/midi++2/midiport.cc39
-rw-r--r--libs/midi++2/port_request.cc7
21 files changed, 299 insertions, 358 deletions
diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript
index 7c3267a6c7..5230bfc391 100644
--- a/libs/midi++2/SConscript
+++ b/libs/midi++2/SConscript
@@ -30,18 +30,24 @@ version.cc
""")
sysdep_sources = Split ("""
+jack_midiport.cc
alsa_sequencer_midiport.cc
coremidi_midiport.cc
""")
-if env['SYSMIDI'] == 'CoreMIDI':
+if env['SYSMIDI'] == 'JACK MIDI':
+ sysdep_src = [ 'jack_midiport.cc' ]
+ midi2.Append (CCFLAGS="-DWITH_JACK_MIDI")
+elif env['SYSMIDI'] == 'ALSA Sequencer':
+ sysdep_src = [ 'alsa_sequencer_midiport.cc' ]
+ midi2.Append (CCFLAGS="-DWITH_ALSA")
+elif env['SYSMIDI'] == 'CoreMIDI':
sysdep_src = [ 'coremidi_midiport.cc' ]
midi2.Append (CCFLAGS="-DWITH_COREMIDI")
midi2.Append (LINKFLAGS="-framework CoreMIDI")
midi2.Append (LINKFLAGS="-framework CoreFoundation")
-else:
- sysdep_src = [ 'alsa_sequencer_midiport.cc' ]
- midi2.Append (CCFLAGS="-DWITH_ALSA")
+
+
midi2.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
midi2.Append(CCFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc
index fca6707efd..1a758b275d 100644
--- a/libs/midi++2/alsa_sequencer_midiport.cc
+++ b/libs/midi++2/alsa_sequencer_midiport.cc
@@ -79,7 +79,7 @@ int ALSA_SequencerMidiPort::selectable () const
return -1;
}
-int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen)
+int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t timestamp)
{
TR_FN ();
int R;
@@ -118,7 +118,7 @@ int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen)
return totwritten;
}
-int ALSA_SequencerMidiPort::read (byte *buf, size_t max)
+int ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t timestamp)
{
TR_FN();
int err;
diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc
index 8d1d927b7b..2cd98239ec 100644
--- a/libs/midi++2/coremidi_midiport.cc
+++ b/libs/midi++2/coremidi_midiport.cc
@@ -56,7 +56,7 @@ void CoreMidi_MidiPort::Close ()
if (midi_client) MIDIClientDispose(midi_client);
}
-int CoreMidi_MidiPort::write (byte *msg, size_t msglen)
+int CoreMidi_MidiPort::write (byte *msg, size_t msglen, timestamp_t timestamp)
{
OSStatus err;
MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
diff --git a/libs/midi++2/fd_midiport.cc b/libs/midi++2/fd_midiport.cc
index 2ced63c259..ef387e7c49 100644
--- a/libs/midi++2/fd_midiport.cc
+++ b/libs/midi++2/fd_midiport.cc
@@ -151,7 +151,7 @@ FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
}
int
-FD_MidiPort::read (byte* buf, size_t max)
+FD_MidiPort::read (byte* buf, size_t max, timestamp_t timestamp)
{
int nread;
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,
diff --git a/libs/midi++2/midichannel.cc b/libs/midi++2/midichannel.cc
index 42949591fe..fe4f4afeb2 100644
--- a/libs/midi++2/midichannel.cc
+++ b/libs/midi++2/midichannel.cc
@@ -25,61 +25,61 @@
using namespace sigc;
using namespace MIDI;
-Channel::Channel (byte channelnum, Port &p) : port (p)
+Channel::Channel (byte channelnum, Port &p) : _port (p)
{
- channel_number = channelnum;
+ _channel_number = channelnum;
- reset (false);
+ reset (0, 1, false);
}
void
Channel::connect_input_signals ()
{
- port.input()->channel_pressure[channel_number].connect
+ _port.input()->channel_pressure[_channel_number].connect
(mem_fun (*this, &Channel::process_chanpress));
- port.input()->channel_note_on[channel_number].connect
+ _port.input()->channel_note_on[_channel_number].connect
(mem_fun (*this, &Channel::process_note_on));
- port.input()->channel_note_off[channel_number].connect
+ _port.input()->channel_note_off[_channel_number].connect
(mem_fun (*this, &Channel::process_note_off));
- port.input()->channel_poly_pressure[channel_number].connect
+ _port.input()->channel_poly_pressure[_channel_number].connect
(mem_fun (*this, &Channel::process_polypress));
- port.input()->channel_program_change[channel_number].connect
+ _port.input()->channel_program_change[_channel_number].connect
(mem_fun (*this, &Channel::process_program_change));
- port.input()->channel_controller[channel_number].connect
+ _port.input()->channel_controller[_channel_number].connect
(mem_fun (*this, &Channel::process_controller));
- port.input()->channel_pitchbend[channel_number].connect
+ _port.input()->channel_pitchbend[_channel_number].connect
(mem_fun (*this, &Channel::process_pitchbend));
- port.input()->reset.connect (mem_fun (*this, &Channel::process_reset));
+ _port.input()->reset.connect (mem_fun (*this, &Channel::process_reset));
}
void
Channel::connect_output_signals ()
{
- port.output()->channel_pressure[channel_number].connect
+ _port.output()->channel_pressure[_channel_number].connect
(mem_fun (*this, &Channel::process_chanpress));
- port.output()->channel_note_on[channel_number].connect
+ _port.output()->channel_note_on[_channel_number].connect
(mem_fun (*this, &Channel::process_note_on));
- port.output()->channel_note_off[channel_number].connect
+ _port.output()->channel_note_off[_channel_number].connect
(mem_fun (*this, &Channel::process_note_off));
- port.output()->channel_poly_pressure[channel_number].connect
+ _port.output()->channel_poly_pressure[_channel_number].connect
(mem_fun (*this, &Channel::process_polypress));
- port.output()->channel_program_change[channel_number].connect
+ _port.output()->channel_program_change[_channel_number].connect
(mem_fun (*this, &Channel::process_program_change));
- port.output()->channel_controller[channel_number].connect
+ _port.output()->channel_controller[_channel_number].connect
(mem_fun (*this, &Channel::process_controller));
- port.output()->channel_pitchbend[channel_number].connect
+ _port.output()->channel_pitchbend[_channel_number].connect
(mem_fun (*this, &Channel::process_pitchbend));
- port.output()->reset.connect (mem_fun (*this, &Channel::process_reset));
+ _port.output()->reset.connect (mem_fun (*this, &Channel::process_reset));
}
void
-Channel::reset (bool notes_off)
+Channel::reset (timestamp_t timestamp, nframes_t nframes, bool notes_off)
{
- program_number = channel_number;
- bank_number = 0;
- pitch_bend = 0;
+ _program_number = _channel_number;
+ _bank_number = 0;
+ _pitch_bend = 0;
_last_note_on = 0;
_last_note_off = 0;
@@ -87,25 +87,25 @@ Channel::reset (bool notes_off)
_last_off_velocity = 0;
if (notes_off) {
- all_notes_off ();
+ all_notes_off (timestamp);
}
- memset (polypress, 0, sizeof (polypress));
- memset (controller_msb, 0, sizeof (controller_msb));
- memset (controller_lsb, 0, sizeof (controller_lsb));
+ memset (_polypress, 0, sizeof (_polypress));
+ memset (_controller_msb, 0, sizeof (_controller_msb));
+ memset (_controller_lsb, 0, sizeof (_controller_lsb));
/* zero all controllers XXX not necessarily the right thing */
- memset (controller_val, 0, sizeof (controller_val));
+ memset (_controller_val, 0, sizeof (_controller_val));
for (int n = 0; n < 128; n++) {
- controller_14bit[n] = false;
+ _controller_14bit[n] = false;
}
- rpn_msb = 0;
- rpn_lsb = 0;
- nrpn_msb = 0;
- nrpn_lsb = 0;
+ _rpn_msb = 0;
+ _rpn_lsb = 0;
+ _nrpn_msb = 0;
+ _nrpn_lsb = 0;
_omni = true;
_poly = false;
@@ -155,20 +155,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
it directly.
*/
- cv = (unsigned short) controller_val[tb->controller_number];
+ cv = (unsigned short) _controller_val[tb->controller_number];
- if (controller_14bit[tb->controller_number]) {
+ if (_controller_14bit[tb->controller_number]) {
cv = ((tb->value << 7) | (cv & 0x7f));
} else {
cv = tb->value;
}
- controller_val[tb->controller_number] = (controller_value_t)cv;
+ _controller_val[tb->controller_number] = (controller_value_t)cv;
} else if ((tb->controller_number >= 32 &&
tb->controller_number <= 63)) {
- cv = (unsigned short) controller_val[tb->controller_number];
+ cv = (unsigned short) _controller_val[tb->controller_number];
/* LSB for CC 0-31 arrived.
@@ -183,20 +183,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
int cn = tb->controller_number - 32;
- if (controller_14bit[cn] == false) {
- controller_14bit[cn] = true;
+ if (_controller_14bit[cn] == false) {
+ _controller_14bit[cn] = true;
cv = (cv << 7) | (tb->value & 0x7f);
} else {
cv = (cv & 0x3f80) | (tb->value & 0x7f);
}
- controller_val[tb->controller_number] =
+ _controller_val[tb->controller_number] =
(controller_value_t) cv;
} else {
/* controller can only take 7 bit values */
- controller_val[tb->controller_number] =
+ _controller_val[tb->controller_number] =
(controller_value_t) tb->value;
}
@@ -204,11 +204,11 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
*/
if (tb->controller_number == 0) {
- bank_number = (unsigned short) controller_val[0];
- if (port.input()) {
- port.input()->bank_change (*port.input(), bank_number);
- port.input()->channel_bank_change[channel_number]
- (*port.input(), bank_number);
+ _bank_number = (unsigned short) _controller_val[0];
+ if (_port.input()) {
+ _port.input()->bank_change (*_port.input(), _bank_number);
+ _port.input()->channel_bank_change[_channel_number]
+ (*_port.input(), _bank_number);
}
}
@@ -218,47 +218,47 @@ void
Channel::process_program_change (Parser &parser, byte val)
{
- program_number = val;
+ _program_number = val;
}
void
Channel::process_chanpress (Parser &parser, byte val)
{
- chanpress = val;
+ _chanpress = val;
}
void
Channel::process_polypress (Parser &parser, EventTwoBytes *tb)
{
- polypress[tb->note_number] = tb->value;
+ _polypress[tb->note_number] = tb->value;
}
void
Channel::process_pitchbend (Parser &parser, pitchbend_t val)
{
- pitch_bend = val;
+ _pitch_bend = val;
}
void
Channel::process_reset (Parser &parser)
{
- reset ();
+ reset (0, 1);
}
/** Write a message to a channel.
* \return true if success
*/
bool
-Channel::channel_msg (byte id, byte val1, byte val2)
+Channel::channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp)
{
unsigned char msg[3];
int len = 0;
- msg[0] = id | (channel_number & 0xf);
+ msg[0] = id | (_channel_number & 0xf);
switch (id) {
case off:
@@ -302,5 +302,5 @@ Channel::channel_msg (byte id, byte val1, byte val2)
break;
}
- return port.midimsg (msg, len);
+ return _port.midimsg (msg, len, timestamp);
}
diff --git a/libs/midi++2/midicontrollable.cc b/libs/midi++2/midicontrollable.cc
index f17782f3c4..24bc381255 100644
--- a/libs/midi++2/midicontrollable.cc
+++ b/libs/midi++2/midicontrollable.cc
@@ -308,7 +308,7 @@ Controllable::get_control_info (channel_t& chn, eventType& ev, byte& additional)
void
-Controllable::send_midi_feedback (float val)
+Controllable::send_midi_feedback (float val, timestamp_t timestamp)
{
byte msg[3];
@@ -320,6 +320,6 @@ Controllable::send_midi_feedback (float val)
msg[1] = control_additional;
msg[2] = (byte) (val * 127.0f);
- port->write (msg, 3);
+ port->write (msg, 3, timestamp);
}
diff --git a/libs/midi++2/midifactory.cc b/libs/midi++2/midifactory.cc
index 38baada204..d8119e362e 100644
--- a/libs/midi++2/midifactory.cc
+++ b/libs/midi++2/midifactory.cc
@@ -17,11 +17,16 @@
$Id$
*/
+#include <cassert>
#include <midi++/types.h>
#include <midi++/factory.h>
#include <midi++/nullmidi.h>
#include <midi++/fifomidi.h>
+#ifdef WITH_JACK_MIDI
+#include <midi++/jack.h>
+#endif // WITH_JACK_MIDI
+
#ifdef WITH_ALSA
#include <midi++/alsa_sequencer.h>
#include <midi++/alsa_rawmidi.h>
@@ -35,13 +40,21 @@
using namespace std;
using namespace MIDI;
+// FIXME: void* data pointer, filthy
Port *
-PortFactory::create_port (PortRequest &req)
+PortFactory::create_port (PortRequest &req, void* data)
{
Port *port;
switch (req.type) {
+#ifdef WITH_JACK_MIDI
+ case Port::JACK_Midi:
+ assert(data != NULL);
+ port = new JACK_MidiPort (req, (jack_client_t*)data);
+ break;
+#endif // WITH_JACK_MIDI
+
#ifdef WITH_ALSA
case Port::ALSA_RawMidi:
port = new ALSA_RawMidiPort (req);
diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc
index 7b3ed7d336..bcdcddf7a4 100644
--- a/libs/midi++2/midimanager.cc
+++ b/libs/midi++2/midimanager.cc
@@ -33,12 +33,8 @@ using namespace MIDI;
Manager *Manager::theManager = 0;
Manager::Manager ()
-
+ : api_data(NULL)
{
- inputPort = 0;
- outputPort = 0;
- inputChannelNumber = 0;
- outputChannelNumber = 0;
}
Manager::~Manager ()
@@ -102,8 +98,7 @@ Manager::add_port (PortRequest &req)
/* modes must be different or complementary */
}
-
- port = factory.create_port (req);
+ port = factory.create_port (req, api_data);
if (port == 0) {
return 0;
@@ -122,18 +117,6 @@ Manager::add_port (PortRequest &req)
newpair.second = port;
ports_by_device.insert (newpair);
- /* first port added becomes the default input
- port.
- */
-
- if (inputPort == 0) {
- inputPort = port;
- }
-
- if (outputPort == 0) {
- outputPort = port;
- }
-
return port;
}
@@ -154,92 +137,6 @@ Manager::remove_port (string name)
return 0;
}
-int
-Manager::set_input_port (string tag)
-{
- PortMap::iterator res;
- bool found = false;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if (tag == (*res).first) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- return -1;
- }
-
- inputPort = (*res).second;
-
- return 0;
-}
-
-int
-Manager::set_input_port (size_t portnum)
-
-{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if ((*res).second->number() == portnum) {
- inputPort = (*res).second;
- return 0;
- }
- }
-
- return -1;
-}
-
-int
-Manager::set_output_port (string tag)
-
-{
- PortMap::iterator res;
- bool found = false;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if (tag == (*res).first) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- return -1;
- }
-
- // XXX send a signal to say we're about to change output ports
-
- if (outputPort) {
- for (channel_t chan = 0; chan < 16; chan++) {
- outputPort->channel (chan)->all_notes_off ();
- }
- }
- outputPort = (*res).second;
-
- // XXX send a signal to say we've changed output ports
-
- return 0;
-}
-
-int
-Manager::set_output_port (size_t portnum)
-
-{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if ((*res).second->number() == portnum) {
- outputPort = (*res).second;
- return 0;
- }
- }
-
- return -1;
-}
-
Port *
Manager::port (string name)
{
@@ -372,3 +269,20 @@ Manager::parse_port_request (string str, Port::Type type)
return 0;
}
+
+void
+Manager::cycle_start(nframes_t nframes)
+{
+ for (PortMap::iterator i = ports_by_device.begin();
+ i != ports_by_device.end(); i++)
+ (*i).second->cycle_start(nframes);
+}
+
+void
+Manager::cycle_end()
+{
+ for (PortMap::iterator i = ports_by_device.begin();
+ i != ports_by_device.end(); i++)
+ (*i).second->cycle_end();
+}
+
diff --git a/libs/midi++2/midiport.cc b/libs/midi++2/midiport.cc
index a7c4ba0940..7f31b909d3 100644
--- a/libs/midi++2/midiport.cc
+++ b/libs/midi++2/midiport.cc
@@ -32,7 +32,8 @@ using namespace MIDI;
size_t Port::nports = 0;
Port::Port (PortRequest &req)
-
+ : _currently_in_cycle(false)
+ , _nframes_this_cycle(0)
{
_ok = false; /* derived class must set to true if constructor
succeeds.
@@ -87,48 +88,28 @@ Port::~Port ()
* \return true on success.
*/
bool
-Port::clock ()
-
+Port::clock (timestamp_t timestamp)
{
static byte clockmsg = 0xf8;
if (_mode != O_RDONLY) {
- return midimsg (&clockmsg, 1);
+ return midimsg (&clockmsg, 1, timestamp);
}
return false;
}
void
-Port::selector_read_callback (Selectable *s, Select::Condition cond)
-
-{
- byte buf[64];
- read (buf, sizeof (buf));
-}
-
-void
-Port::xforms_read_callback (int cond, int fd, void *ptr)
-
-{
- byte buf[64];
-
- ((Port *)ptr)->read (buf, sizeof (buf));
-}
-
-void
-Port::gtk_read_callback (void *ptr, int fd, int cond)
-
+Port::cycle_start (nframes_t nframes)
{
- byte buf[64];
-
- ((Port *)ptr)->read (buf, sizeof (buf));
+ _currently_in_cycle = true;
+ _nframes_this_cycle = nframes;
}
void
-Port::write_callback (byte *msg, unsigned int len, void *ptr)
-
+Port::cycle_end ()
{
- ((Port *)ptr)->write (msg, len);
+ _currently_in_cycle = false;
+ _nframes_this_cycle = 0;
}
diff --git a/libs/midi++2/port_request.cc b/libs/midi++2/port_request.cc
index d081bdb570..d209f02574 100644
--- a/libs/midi++2/port_request.cc
+++ b/libs/midi++2/port_request.cc
@@ -36,7 +36,7 @@ PortRequest::PortRequest (const string &xdev,
devname = strdup (xdev.c_str());
tagname = strdup (xtag.c_str());
-
+
if (xmode == "output" ||
xmode == "out" ||
xmode == "OUTPUT" ||
@@ -58,7 +58,10 @@ PortRequest::PortRequest (const string &xdev,
status = Unknown;
}
- if (xtype == "ALSA/RAW" ||
+ if (xtype == "JACK" ||
+ xtype == "jack") {
+ type = Port::JACK_Midi;
+ } else if (xtype == "ALSA/RAW" ||
xtype == "alsa/raw") {
type = Port::ALSA_RawMidi;
} else if (xtype == "ALSA/SEQUENCER" ||