diff options
Diffstat (limited to 'libs/midi++2/midi++')
-rw-r--r-- | libs/midi++2/midi++/.DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | libs/midi++2/midi++/.cvsignore | 1 | ||||
-rw-r--r-- | libs/midi++2/midi++/alsa_rawmidi.h | 43 | ||||
-rw-r--r-- | libs/midi++2/midi++/alsa_sequencer.h | 63 | ||||
-rw-r--r-- | libs/midi++2/midi++/channel.h | 161 | ||||
-rw-r--r-- | libs/midi++2/midi++/controllable.h | 92 | ||||
-rw-r--r-- | libs/midi++2/midi++/coremidi_midiport.h | 67 | ||||
-rw-r--r-- | libs/midi++2/midi++/factory.h | 40 | ||||
-rw-r--r-- | libs/midi++2/midi++/fd_midiport.h | 94 | ||||
-rw-r--r-- | libs/midi++2/midi++/fifomidi.h | 47 | ||||
-rw-r--r-- | libs/midi++2/midi++/manager.h | 88 | ||||
-rw-r--r-- | libs/midi++2/midi++/mmc.h | 261 | ||||
-rw-r--r-- | libs/midi++2/midi++/nullmidi.h | 62 | ||||
-rw-r--r-- | libs/midi++2/midi++/parser.h | 189 | ||||
-rw-r--r-- | libs/midi++2/midi++/port.h | 147 | ||||
-rw-r--r-- | libs/midi++2/midi++/port_request.h | 60 | ||||
-rw-r--r-- | libs/midi++2/midi++/types.h | 69 |
17 files changed, 1484 insertions, 0 deletions
diff --git a/libs/midi++2/midi++/.DS_Store b/libs/midi++2/midi++/.DS_Store Binary files differnew file mode 100644 index 0000000000..5008ddfcf5 --- /dev/null +++ b/libs/midi++2/midi++/.DS_Store diff --git a/libs/midi++2/midi++/.cvsignore b/libs/midi++2/midi++/.cvsignore new file mode 100644 index 0000000000..67020331ba --- /dev/null +++ b/libs/midi++2/midi++/.cvsignore @@ -0,0 +1 @@ +version.h diff --git a/libs/midi++2/midi++/alsa_rawmidi.h b/libs/midi++2/midi++/alsa_rawmidi.h new file mode 100644 index 0000000000..655b673174 --- /dev/null +++ b/libs/midi++2/midi++/alsa_rawmidi.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __alsa_rawmidi_h__ +#define __alsa_rawmidi_h__ + +#include <vector> +#include <string> + +#include <fcntl.h> +#include <unistd.h> + +#include <midi++/port.h> +#include <midi++/fd_midiport.h> + +class ALSA_RawMidiPort : public MIDI::FD_MidiPort + +{ + public: + ALSA_RawMidiPort (MIDI::PortRequest &req) + : FD_MidiPort (req, "/dev/snd", "midi") {} + virtual ~ALSA_RawMidiPort () {} +}; + + +#endif // __alsa_rawmidi_h__ + diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h new file mode 100644 index 0000000000..8ddb2a7dd7 --- /dev/null +++ b/libs/midi++2/midi++/alsa_sequencer.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2004 Paul 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __alsa_sequencer_midiport_h__ +#define __alsa_sequencer_midiport_h__ + +#include <vector> +#include <string> + +#include <fcntl.h> +#include <unistd.h> + +#include <alsa/asoundlib.h> +#include <midi++/port.h> + +namespace MIDI { + +class ALSA_SequencerMidiPort : public Port + +{ + public: + ALSA_SequencerMidiPort (PortRequest &req); + virtual ~ALSA_SequencerMidiPort (); + + /* select(2)/poll(2)-based I/O */ + + virtual int selectable() const; + + protected: + /* Direct I/O */ + + int write (byte *msg, size_t msglen); + int read (byte *buf, size_t max); + + private: + snd_seq_t *seq; + snd_midi_event_t *decoder, *encoder; + int port_id; + snd_seq_event_t SEv; + int CreatePorts(PortRequest &req); + +}; + +}; /* namespace MIDI */ + +#endif // __alsa_sequencer_midiport_h__ + diff --git a/libs/midi++2/midi++/channel.h b/libs/midi++2/midi++/channel.h new file mode 100644 index 0000000000..1efde3cb93 --- /dev/null +++ b/libs/midi++2/midi++/channel.h @@ -0,0 +1,161 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midichannel_h__ +#define __midichannel_h__ + +#include <queue> + +#include <sigc++/sigc++.h> + +#include <midi++/types.h> +#include <midi++/parser.h> + +namespace MIDI { + +class Port; + +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]; } + + byte last_note_on () { + return _last_note_on; + } + byte last_on_velocity () { + return _last_on_velocity; + } + byte last_note_off () { + return _last_note_off; + } + byte last_off_velocity () { + return _last_off_velocity; + } + + pitchbend_t pitchbend () { + return pitch_bend; + } + + controller_value_t controller_value (byte n) { + return controller_val[n%128]; + } + + controller_value_t *controller_addr (byte n) { + return &controller_val[n%128]; + } + + void set_controller (byte n, byte val) { + controller_val[n%128] = val; + } + + int channel_msg (byte id, byte val1, byte val2); + + int all_notes_off () { + return channel_msg (MIDI::controller, 123, 0); + } + + int control (byte id, byte value) { + return channel_msg (MIDI::controller, id, value); + } + + int note_on (byte note, byte velocity) { + return channel_msg (MIDI::on, note, velocity); + } + + int note_off (byte note, byte velocity) { + return channel_msg (MIDI::off, note, velocity); + } + + int aftertouch (byte value) { + return channel_msg (MIDI::chanpress, value, 0); + } + + int poly_aftertouch (byte note, byte value) { + return channel_msg (MIDI::polypress, note, value); + } + + int program_change (byte value) { + return channel_msg (MIDI::program, value, 0); + } + + int pitchbend (byte msb, byte lsb) { + return channel_msg (MIDI::pitchbend, lsb, msb); + } + + protected: + friend class Port; + void connect_input_signals (); + void connect_output_signals (); + + private: + 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); + + void process_note_off (Parser &, EventTwoBytes *); + void process_note_on (Parser &, EventTwoBytes *); + void process_controller (Parser &, EventTwoBytes *); + void process_polypress (Parser &, EventTwoBytes *); + void process_program_change (Parser &, byte); + void process_chanpress (Parser &, byte); + void process_pitchbend (Parser &, pitchbend_t); + void process_reset (Parser &); +}; + +}; /* namespace MIDI */ + +#endif // __midichannel_h__ + + + + diff --git a/libs/midi++2/midi++/controllable.h b/libs/midi++2/midi++/controllable.h new file mode 100644 index 0000000000..3fa108bb46 --- /dev/null +++ b/libs/midi++2/midi++/controllable.h @@ -0,0 +1,92 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __qm_midicontrollable_h__ +#define __qm_midicontrollable_h__ + +#include <string> + +#include <sigc++/sigc++.h> + +#include <midi++/types.h> + +namespace MIDI { + +class Channel; +class Port; +class Parser; + +class Controllable : public sigc::trackable +{ + public: + Controllable (Port *, bool bistate = false); + virtual ~Controllable (); + + void midi_rebind (Port *, channel_t channel=-1); + void midi_forget (); + void learn_about_external_control (); + void stop_learning (); + void drop_external_control (); + + virtual void set_value (float) = 0; + + sigc::signal<void> learning_started; + sigc::signal<void> learning_stopped; + + bool get_control_info (channel_t&, eventType&, byte&); + void set_control_type (channel_t, eventType, byte); + + bool get_midi_feedback () { return feedback; } + void set_midi_feedback (bool val) { feedback = val; } + + Port * get_port() { return port; } + + std::string control_description() const { return _control_description; } + + void send_midi_feedback (float); + + private: + bool bistate; + int midi_msg_id; /* controller ID or note number */ + sigc::connection midi_sense_connection[2]; + sigc::connection midi_learn_connection; + size_t connections; + Port* port; + eventType control_type; + byte control_additional; + channel_t control_channel; + std::string _control_description; + bool feedback; + + void midi_receiver (Parser &p, byte *, size_t); + void midi_sense_note (Parser &, EventTwoBytes *, bool is_on); + void midi_sense_note_on (Parser &p, EventTwoBytes *tb); + void midi_sense_note_off (Parser &p, EventTwoBytes *tb); + void midi_sense_controller (Parser &, EventTwoBytes *); + void midi_sense_program_change (Parser &, byte); + void midi_sense_pitchbend (Parser &, pitchbend_t); + + void bind_midi (channel_t, eventType, byte); +}; + +}; /* namespace MIDI */ + +#endif // __qm_midicontrollable_h__ + diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h new file mode 100644 index 0000000000..e02a225784 --- /dev/null +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2004 Paul Davis + Copyright (C) 2004 Grame + 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ĘSee the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#ifndef __coremidi_midiport_h__ +#define __coremidi_midiport_h__ + +#include <list> +#include <string> + +#include <fcntl.h> +#include <unistd.h> + +#include <midi++/port.h> + +#include <CoreMIDI/CoreMIDI.h> + +namespace MIDI { + + 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); + + private: + byte midi_buffer[1024]; + MIDIClientRef midi_client; + MIDIEndpointRef midi_destination; + MIDIEndpointRef midi_source; + + int Open(PortRequest & req); + void Close(); + static MIDITimeStamp MIDIGetCurrentHostTime(); + + bool firstrecv; + }; + +}; /* namespace MIDI */ + +#endif // __coremidi_midiport_h__ diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h new file mode 100644 index 0000000000..1543f68cdc --- /dev/null +++ b/libs/midi++2/midi++/factory.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midi_factory_h__ +#define __midi_factory_h__ + +#include <vector> +#include <string> + +#include <midi++/port.h> + +namespace MIDI { + +class PortFactory { + public: + Port *create_port (PortRequest &req); + + static void add_port_request (std::vector<PortRequest *> &reqs, + const std::string &reqstr); +}; + +}; /* namespace MIDI */ + +#endif // __midi_factory_h__ diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h new file mode 100644 index 0000000000..853af9d7b4 --- /dev/null +++ b/libs/midi++2/midi++/fd_midiport.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 1999 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __fd_midiport_h__ +#define __fd_midiport_h__ + +#include <vector> +#include <string> +#include <cerrno> + +#include <cerrno> +#include <fcntl.h> +#include <unistd.h> + +#include <midi++/port.h> +#include <midi++/port_request.h> + +namespace MIDI { + +class FD_MidiPort : public Port + +{ + public: + FD_MidiPort (PortRequest &req, + const std::string &dirpath, + const std::string &pattern); + + virtual ~FD_MidiPort () { + ::close (_fd); + } + + virtual int selectable() const; + static std::vector<std::string *> *list_devices (); + + protected: + int _fd; + virtual void open (PortRequest &req); + + virtual int write (byte *msg, size_t msglen) { + int nwritten; + + if ((_mode & O_ACCMODE) == O_RDONLY) { + return -EACCES; + } + + if (slowdown) { + return do_slow_write (msg, msglen); + } + + if ((nwritten = ::write (_fd, msg, msglen)) > 0) { + bytes_written += nwritten; + + if (output_parser) { + output_parser->raw_preparse + (*output_parser, msg, nwritten); + for (int i = 0; i < nwritten; i++) { + output_parser->scanner (msg[i]); + } + output_parser->raw_postparse + (*output_parser, msg, nwritten); + } + } + return nwritten; + } + + virtual int read (byte *buf, size_t max); + + private: + static std::string *midi_dirpath; + static std::string *midi_filename_pattern; + + int do_slow_write (byte *msg, unsigned int msglen); +}; + +}; /*namespace MIDI */ + +#endif // __fd_midiport_h__ diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h new file mode 100644 index 0000000000..eb8778d4d5 --- /dev/null +++ b/libs/midi++2/midi++/fifomidi.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __fifomidi_h__ +#define __fifomidi_h__ + +#include <fcntl.h> +#include <vector> +#include <string> +#include <unistd.h> + +#include <midi++/port.h> +#include <midi++/port_request.h> +#include <midi++/fd_midiport.h> + +namespace MIDI { + +class FIFO_MidiPort : public MIDI::FD_MidiPort + +{ + public: + FIFO_MidiPort (PortRequest &req); + ~FIFO_MidiPort () {}; + + private: + void open (PortRequest &req); +}; + +}; /* namespace MIDI */ + +#endif // __fifomidi_h__ diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h new file mode 100644 index 0000000000..4889aad8c9 --- /dev/null +++ b/libs/midi++2/midi++/manager.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 1998 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midi_manager_h__ +#define __midi_manager_h__ + +#include <map> +#include <string> + +#include <midi++/types.h> +#include <midi++/port.h> + +namespace MIDI { + +class Manager { + public: + ~Manager (); + + Port *add_port (PortRequest &); + int remove_port (std::string port); + + Port *port (std::string name); + Port *port (size_t number); + + 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); + + typedef std::map<std::string, Port *> PortMap; + + const PortMap& get_midi_ports() const { return ports_by_tag; } + + static Manager *instance () { + if (theManager == 0) { + theManager = new Manager; + } + return theManager; + } + + static int parse_port_request (std::string str, Port::Type type); + + private: + /* This is a SINGLETON pattern */ + + Manager (); + + static Manager *theManager; + PortMap ports_by_device; /* canonical */ + PortMap ports_by_tag; /* may contain duplicate Ports */ + + void close_ports (); +}; + +}; /* namespace MIDI */ + +#endif // __midi_manager_h__ diff --git a/libs/midi++2/midi++/mmc.h b/libs/midi++2/midi++/mmc.h new file mode 100644 index 0000000000..7b51b33a72 --- /dev/null +++ b/libs/midi++2/midi++/mmc.h @@ -0,0 +1,261 @@ +/* + Copyright (C) 2000 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midipp_mmc_h_h__ +#define __midipp_mmc_h_h__ + +#include <sigc++/sigc++.h> +#include <midi++/types.h> + +namespace MIDI { + +class Port; +class Parser; + +class MachineControl : public sigc::trackable + +{ + public: + typedef byte CommandSignature[60]; + typedef byte ResponseSignature[60]; + + enum Command { + cmdStop = 0x1, + cmdPlay = 0x2, + cmdDeferredPlay = 0x3, + cmdFastForward = 0x4, + cmdRewind = 0x5, + cmdRecordStrobe = 0x6, + + cmdRecordExit = 0x7, + cmdRecordPause = 0x8, + cmdPause = 0x9, + cmdEject = 0xA, + cmdChase = 0xB, + cmdCommandErrorReset = 0xC, + cmdMmcReset = 0xD, + + cmdIllegalMackieJogStart = 0x20, + cmdIllegalMackieJogStop = 0x21, + + cmdWrite = 0x40, + cmdMaskedWrite = 0x41, + cmdRead = 0x42, + cmdUpdate = 0x43, + cmdLocate = 0x44, + cmdVariablePlay = 0x45, + cmdSearch = 0x46, + + cmdShuttle = 0x47, + cmdStep = 0x48, + cmdAssignSystemMaster = 0x49, + cmdGeneratorCommand = 0x4A, + cmdMtcCommand = 0x4B, + cmdMove = 0x4C, + cmdAdd = 0x4D, + + cmdSubtract = 0x4E, + cmdDropFrameAdjust = 0x4F, + cmdProcedure = 0x50, + cmdEvent = 0x51, + cmdGroup = 0x52, + cmdCommandSegment = 0x53, + cmdDeferredVariablePlay = 0x54, + + cmdRecordStrobeVariable = 0x55, + + cmdWait = 0x7C, + cmdResume = 0x7F, + }; + + MachineControl (Port &port, + float MMCVersion, + CommandSignature &cs, + ResponseSignature &rs); + + Port &port() { return _port; } + + void set_device_id (byte id); + static bool is_mmc (byte *sysex_buf, size_t len); + + /* Signals to connect to if you want to run "callbacks" + when certain MMC commands are received. + */ + + sigc::signal<void,MachineControl &> Stop; + sigc::signal<void,MachineControl &> Play; + sigc::signal<void,MachineControl &> DeferredPlay; + sigc::signal<void,MachineControl &> FastForward; + sigc::signal<void,MachineControl &> Rewind; + sigc::signal<void,MachineControl &> RecordStrobe; + sigc::signal<void,MachineControl &> RecordExit; + sigc::signal<void,MachineControl &> RecordPause; + sigc::signal<void,MachineControl &> Pause; + sigc::signal<void,MachineControl &> Eject; + sigc::signal<void,MachineControl &> Chase; + sigc::signal<void,MachineControl &> CommandErrorReset; + sigc::signal<void,MachineControl &> MmcReset; + + sigc::signal<void,MachineControl &> JogStart; + sigc::signal<void,MachineControl &> JogStop; + + sigc::signal<void,MachineControl &> Write; + sigc::signal<void,MachineControl &> MaskedWrite; + sigc::signal<void,MachineControl &> Read; + sigc::signal<void,MachineControl &> Update; + sigc::signal<void,MachineControl &> VariablePlay; + sigc::signal<void,MachineControl &> Search; + sigc::signal<void,MachineControl &> AssignSystemMaster; + sigc::signal<void,MachineControl &> GeneratorCommand; + sigc::signal<void,MachineControl &> MidiTimeCodeCommand; + sigc::signal<void,MachineControl &> Move; + sigc::signal<void,MachineControl &> Add; + sigc::signal<void,MachineControl &> Subtract; + sigc::signal<void,MachineControl &> DropFrameAdjust; + sigc::signal<void,MachineControl &> Procedure; + sigc::signal<void,MachineControl &> Event; + sigc::signal<void,MachineControl &> Group; + sigc::signal<void,MachineControl &> CommandSegment; + sigc::signal<void,MachineControl &> DeferredVariablePlay; + sigc::signal<void,MachineControl &> RecordStrobeVariable; + sigc::signal<void,MachineControl &> Wait; + sigc::signal<void,MachineControl &> Resume; + + /* The second argument is the shuttle speed, the third is + true if the direction is "forwards", false for "reverse" + */ + + sigc::signal<void,MachineControl &,float,bool> Shuttle; + + /* The second argument specifies the desired track record enabled + status. + */ + + sigc::signal<void,MachineControl &,size_t,bool> + TrackRecordStatusChange; + + /* The second argument points to a byte array containing + the locate target value in MMC Standard Time Code + format (5 bytes, roughly: hrs/mins/secs/frames/subframes) + */ + + sigc::signal<void,MachineControl &, const byte *> Locate; + + /* The second argument is the number of steps to jump */ + + sigc::signal<void,MachineControl &, int> Step; + + protected: + +#define MMC_NTRACKS 48 + + /* MMC Information fields (think "registers") */ + + CommandSignature commandSignature; + ResponseSignature responseSignature; + + byte updateRate; + byte responseError; + byte commandError; + byte commandErrorLevel; + + byte motionControlTally; + byte velocityTally; + byte stopMode; + byte fastMode; + byte recordMode; + byte recordStatus; + bool trackRecordStatus[MMC_NTRACKS]; + bool trackRecordReady[MMC_NTRACKS]; + byte globalMonitor; + byte recordMonitor; + byte trackSyncMonitor; + byte trackInputMonitor; + byte stepLength; + byte playSpeedReference; + byte fixedSpeed; + byte lifterDefeat; + byte controlDisable; + byte trackMute; + byte failure; + byte selectedTimeCode; + byte shortSelectedTimeCode; + byte timeStandard; + byte selectedTimeCodeSource; + byte selectedTimeCodeUserbits; + byte selectedMasterCode; + byte requestedOffset; + byte actualOffset; + byte lockDeviation; + byte shortSelectedMasterCode; + byte shortRequestedOffset; + byte shortActualOffset; + byte shortLockDeviation; + byte resolvedPlayMode; + byte chaseMode; + byte generatorTimeCode; + byte shortGeneratorTimeCode; + byte generatorCommandTally; + byte generatorSetUp; + byte generatorUserbits; + byte vitcInsertEnable; + byte midiTimeCodeInput; + byte shortMidiTimeCodeInput; + byte midiTimeCodeCommandTally; + byte midiTimeCodeSetUp; + byte gp0; + byte gp1; + byte gp2; + byte gp3; + byte gp4; + byte gp5; + byte gp6; + byte gp7; + byte shortGp0; + byte shortGp1; + byte shortGp2; + byte shortGp3; + byte shortGp4; + byte shortGp5; + byte shortGp6; + byte shortGp7; + byte procedureResponse; + byte eventResponse; + byte responseSegment; + byte wait; + byte resume; + + private: + byte _device_id; + MIDI::Port &_port; + + void process_mmc_message (Parser &p, byte *, size_t len); + + int do_masked_write (byte *, size_t len); + int do_locate (byte *, size_t len); + int do_step (byte *, size_t len); + int do_shuttle (byte *, size_t len); + + void write_track_record_ready (byte *, size_t len); +}; + +}; /* namespace MIDI */ + +#endif /* __midipp_mmc_h_h__ */ diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h new file mode 100644 index 0000000000..a94b1015b0 --- /dev/null +++ b/libs/midi++2/midi++/nullmidi.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __nullmidi_h__ +#define __nullmidi_h__ + +#include <fcntl.h> +#include <vector> +#include <string> + +#include <midi++/port.h> +#include <midi++/port_request.h> + +namespace MIDI { + +class Null_MidiPort : public Port + +{ + public: + Null_MidiPort (PortRequest &req) + : Port (req) { + + /* reset devname and tagname */ + + _devname = "nullmidi"; + _tagname = "null"; + _type = Port::Null; + _ok = true; + } + + virtual ~Null_MidiPort () {}; + + virtual int write (byte *msg, size_t msglen) { + return msglen; + } + + virtual int read (byte *buf, size_t max) { + return 0; + } + + virtual int selectable() const { return -1; } +}; + +}; /* namespace MIDI */ + +#endif // __nullmidi_h__ diff --git a/libs/midi++2/midi++/parser.h b/libs/midi++2/midi++/parser.h new file mode 100644 index 0000000000..4ac07cc15d --- /dev/null +++ b/libs/midi++2/midi++/parser.h @@ -0,0 +1,189 @@ +/* + Copyright (C) 1998 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midi_parse_h__ +#define __midi_parse_h__ + +#include <string> +#include <iostream> + +#include <sigc++/sigc++.h> + +#include <midi++/types.h> + +namespace MIDI { + +class Port; +class Parser; + +typedef sigc::signal<void, Parser &, byte> OneByteSignal; +typedef sigc::signal<void, Parser &, EventTwoBytes *> TwoByteSignal; +typedef sigc::signal<void, Parser &, pitchbend_t> PitchBendSignal; +typedef sigc::signal<void, Parser &, byte *, size_t> Signal; + +class Parser : public sigc::trackable { + public: + Parser (Port &p); + ~Parser (); + + /* signals that anyone can connect to */ + + OneByteSignal bank_change; + TwoByteSignal note_on; + TwoByteSignal note_off; + TwoByteSignal poly_pressure; + OneByteSignal pressure; + OneByteSignal program_change; + PitchBendSignal pitchbend; + TwoByteSignal controller; + + OneByteSignal channel_bank_change[16]; + TwoByteSignal channel_note_on[16]; + TwoByteSignal channel_note_off[16]; + TwoByteSignal channel_poly_pressure[16]; + OneByteSignal channel_pressure[16]; + OneByteSignal channel_program_change[16]; + PitchBendSignal channel_pitchbend[16]; + TwoByteSignal channel_controller[16]; + sigc::signal<void, Parser &> channel_active_preparse[16]; + sigc::signal<void, Parser &> channel_active_postparse[16]; + + OneByteSignal mtc_quarter_frame; + + Signal raw_preparse; + Signal raw_postparse; + Signal any; + Signal sysex; + Signal mmc; + Signal position; + Signal song; + + Signal mtc; + sigc::signal<void,Parser&> mtc_qtr; + + sigc::signal<void, Parser &> all_notes_off; + sigc::signal<void, Parser &> tune; + sigc::signal<void, Parser &> timing; + sigc::signal<void, Parser &> start; + sigc::signal<void, Parser &> stop; + sigc::signal<void, Parser &> contineu; /* note spelling */ + sigc::signal<void, Parser &> active_sense; + sigc::signal<void, Parser &> reset; + sigc::signal<void, Parser &> eox; + + /* This should really be protected, but then derivatives of Port + can't access it. + */ + + void scanner (byte c); + + size_t *message_counts() { return message_counter; } + const char *midi_event_type_name (MIDI::eventType); + void trace (bool onoff, std::ostream *o, const std::string &prefix = ""); + bool tracing() { return trace_stream != 0; } + Port &port() { return _port; } + + void set_offline (bool); + bool offline() const { return _offline; } + sigc::signal<void> OfflineStatusChanged; + + sigc::signal<int, byte *, size_t> edit; + + void set_mmc_forwarding (bool yn) { + _mmc_forward = yn; + } + + /* MTC */ + + enum MTC_Status { + MTC_Stopped = 0, + MTC_Forward, + MTC_Backward + }; + + MTC_FPS mtc_fps() const { return _mtc_fps; } + MTC_Status mtc_running() const { return _mtc_running; } + const byte *mtc_current() const { return _mtc_time; } + bool mtc_locked() const { return _mtc_locked; } + + sigc::signal<void,MTC_Status> mtc_status; + sigc::signal<bool> mtc_skipped; + sigc::signal<void,const byte*,bool> mtc_time; + + void set_mtc_forwarding (bool yn) { + _mtc_forward = yn; + } + + void reset_mtc_state (); + + private: + Port &_port; + /* tracing */ + + std::ostream *trace_stream; + std::string trace_prefix; + void trace_event (Parser &p, byte *msg, size_t len); + sigc::connection trace_connection; + + size_t message_counter[256]; + + enum ParseState { + NEEDSTATUS, + NEEDONEBYTE, + NEEDTWOBYTES, + VARIABLELENGTH + }; + ParseState state; + unsigned char *msgbuf; + int msglen; + int msgindex; + MIDI::eventType msgtype; + channel_t channel; + bool _offline; + bool runnable; + bool was_runnable; + bool _mmc_forward; + bool _mtc_forward; + int expected_mtc_quarter_frame_code; + byte _mtc_time[4]; + byte _qtr_mtc_time[4]; + unsigned long consecutive_qtr_frame_cnt; + MTC_FPS _mtc_fps; + MTC_Status _mtc_running; + bool _mtc_locked; + byte last_qtr_frame; + + ParseState pre_variable_state; + MIDI::eventType pre_variable_msgtype; + byte last_status_byte; + + void channel_msg (byte); + void realtime_msg (byte); + void system_msg (byte); + void signal (byte *msg, size_t msglen); + bool possible_mmc (byte *msg, size_t msglen); + bool possible_mtc (byte *msg, size_t msglen); + void process_mtc_quarter_frame (byte *msg); +}; + +}; /* namespace MIDI */ + +#endif // __midi_parse_h__ + diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h new file mode 100644 index 0000000000..81e28615d0 --- /dev/null +++ b/libs/midi++2/midi++/port.h @@ -0,0 +1,147 @@ +/* + Copyright (C) 1998-99 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __libmidi_port_h__ +#define __libmidi_port_h__ + +#include <string> + +#include <sigc++/sigc++.h> + +#include <pbd/selectable.h> +#include <midi++/types.h> +#include <midi++/parser.h> + +namespace MIDI { + +class Channel; +class PortRequest; + +class Port : public sigc::trackable { + public: + enum Type { + Unknown, + ALSA_RawMidi, + ALSA_Sequencer, + CoreMidi_MidiPort, + Null, + FIFO, + }; + + + Port (PortRequest &); + virtual ~Port (); + + /* Direct I/O */ + + virtual int write (byte *msg, size_t msglen) = 0; + virtual int read (byte *buf, size_t max) = 0; + + /* slowdown 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 */ + + 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; } + + 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; + } + } + + int midimsg (byte *msg, size_t len) { + return !(write (msg, len) == (int) len); + } + + int 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); + } + + int 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; } + + protected: + bool _ok; + 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; +}; + +}; /* namespace MIDI */ + +#endif // __libmidi_port_h__ + diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h new file mode 100644 index 0000000000..28a0d1d70b --- /dev/null +++ b/libs/midi++2/midi++/port_request.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 1999 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __midi_port_request_h__ +#define __midi_port_request_h__ + +#include <string> + +namespace MIDI { + +struct PortRequest { + enum Status { + Unknown, + OK, + Busy, + NoSuchFile, + TypeUnsupported, + NotAllowed + }; + const char *devname; + const char *tagname; + int mode; + Port::Type type; + Status status; + + PortRequest () { + devname = 0; + tagname = 0; + mode = 0; + type = Port::Unknown; + status = Unknown; + } + + PortRequest (const std::string &xdev, + const std::string &xtag, + const std::string &xmode, + const std::string &xtype); +}; + +}; /* namespace MIDI */ + +#endif // __midi_port_request_h__ + diff --git a/libs/midi++2/midi++/types.h b/libs/midi++2/midi++/types.h new file mode 100644 index 0000000000..b9d9bf33e7 --- /dev/null +++ b/libs/midi++2/midi++/types.h @@ -0,0 +1,69 @@ +#ifndef __midi_types_h__ +#define __midi_types_h__ + +namespace MIDI { + + typedef char channel_t; + typedef float controller_value_t; + typedef unsigned char byte; + typedef unsigned short pitchbend_t; + + enum eventType { + none = 0x0, + raw = 0xF4, /* undefined in MIDI spec */ + any = 0xF5, /* undefined in MIDI spec */ + off = 0x80, + on = 0x90, + controller = 0xB0, + program = 0xC0, + chanpress = 0xD0, + polypress = 0xA0, + pitchbend = 0xE0, + sysex = 0xF0, + mtc_quarter = 0xF1, + position = 0xF2, + song = 0xF3, + tune = 0xF6, + eox = 0xF7, + timing = 0xF8, + start = 0xFA, + contineu = 0xFB, /* note spelling */ + stop = 0xFC, + active = 0xFE, + reset = 0xFF + }; + + extern const char *controller_names[]; + byte decode_controller_name (const char *name); + + struct EventTwoBytes { + union { + byte note_number; + byte controller_number; + }; + union { + byte velocity; + byte value; + }; + }; + + enum MTC_FPS { + MTC_24_FPS = 0, + MTC_25_FPS = 1, + MTC_30_FPS_DROP = 2, + MTC_30_FPS = 3 + }; + + enum MTC_Status { + MTC_Stopped = 0, + MTC_Forward, + MTC_Backward, + }; + +}; /* namespace MIDI */ + +#endif // __midi_types_h__ + + + + |