annotate data/midi/rtmidi/RtMidi.h @ 588:d04b8674b710

* Try to identify the properly conformant audio file structure written out by Sonic Annotator (but we still don't actually import it yet)
author Chris Cannam
date Wed, 13 May 2009 13:30:08 +0000
parents 3086876472dc
children b0533d195c83
rev   line source
Chris@559 1 /**********************************************************************/
Chris@559 2 /*! \class RtMidi
Chris@559 3 \brief An abstract base class for realtime MIDI input/output.
Chris@559 4
Chris@559 5 This class implements some common functionality for the realtime
Chris@559 6 MIDI input/output subclasses RtMidiIn and RtMidiOut.
Chris@559 7
Chris@559 8 RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
Chris@559 9
Chris@559 10 RtMidi: realtime MIDI i/o C++ classes
Chris@565 11 Copyright (c) 2003-2009 Gary P. Scavone
Chris@559 12
Chris@559 13 Permission is hereby granted, free of charge, to any person
Chris@559 14 obtaining a copy of this software and associated documentation files
Chris@559 15 (the "Software"), to deal in the Software without restriction,
Chris@559 16 including without limitation the rights to use, copy, modify, merge,
Chris@559 17 publish, distribute, sublicense, and/or sell copies of the Software,
Chris@559 18 and to permit persons to whom the Software is furnished to do so,
Chris@559 19 subject to the following conditions:
Chris@559 20
Chris@559 21 The above copyright notice and this permission notice shall be
Chris@559 22 included in all copies or substantial portions of the Software.
Chris@559 23
Chris@559 24 Any person wishing to distribute modifications to the Software is
Chris@559 25 requested to send the modifications to the original developer so that
Chris@559 26 they can be incorporated into the canonical version.
Chris@559 27
Chris@559 28 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@559 29 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@559 30 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@559 31 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@559 32 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@559 33 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@559 34 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@559 35 */
Chris@559 36 /**********************************************************************/
Chris@559 37
Chris@565 38 // RtMidi: Version 1.0.8
Chris@559 39
Chris@559 40 #ifndef RTMIDI_H
Chris@559 41 #define RTMIDI_H
Chris@559 42
Chris@559 43 #include "RtError.h"
Chris@559 44 #include <string>
Chris@559 45
Chris@559 46 class RtMidi
Chris@559 47 {
Chris@559 48 public:
Chris@559 49
Chris@559 50 //! Pure virtual openPort() function.
Chris@565 51 virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
Chris@559 52
Chris@559 53 //! Pure virtual openVirtualPort() function.
Chris@559 54 virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
Chris@559 55
Chris@559 56 //! Pure virtual getPortCount() function.
Chris@559 57 virtual unsigned int getPortCount() = 0;
Chris@559 58
Chris@559 59 //! Pure virtual getPortName() function.
Chris@559 60 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
Chris@559 61
Chris@559 62 //! Pure virtual closePort() function.
Chris@559 63 virtual void closePort( void ) = 0;
Chris@559 64
Chris@559 65 protected:
Chris@559 66
Chris@559 67 RtMidi();
Chris@559 68 virtual ~RtMidi() {};
Chris@559 69
Chris@559 70 // A basic error reporting function for internal use in the RtMidi
Chris@559 71 // subclasses. The behavior of this function can be modified to
Chris@559 72 // suit specific needs.
Chris@559 73 void error( RtError::Type type );
Chris@559 74
Chris@559 75 void *apiData_;
Chris@559 76 bool connected_;
Chris@559 77 std::string errorString_;
Chris@559 78 };
Chris@559 79
Chris@559 80 /**********************************************************************/
Chris@559 81 /*! \class RtMidiIn
Chris@559 82 \brief A realtime MIDI input class.
Chris@559 83
Chris@559 84 This class provides a common, platform-independent API for
Chris@559 85 realtime MIDI input. It allows access to a single MIDI input
Chris@559 86 port. Incoming MIDI messages are either saved to a queue for
Chris@559 87 retrieval using the getMessage() function or immediately passed to
Chris@559 88 a user-specified callback function. Create multiple instances of
Chris@559 89 this class to connect to more than one MIDI device at the same
Chris@559 90 time. With the OS-X and Linux ALSA MIDI APIs, it is also possible
Chris@559 91 to open a virtual input port to which other MIDI software clients
Chris@559 92 can connect.
Chris@559 93
Chris@565 94 by Gary P. Scavone, 2003-2008.
Chris@559 95 */
Chris@559 96 /**********************************************************************/
Chris@559 97
Chris@559 98 #include <vector>
Chris@559 99 #include <queue>
Chris@559 100
Chris@559 101 class RtMidiIn : public RtMidi
Chris@559 102 {
Chris@559 103 public:
Chris@559 104
Chris@559 105 //! User callback function type definition.
Chris@559 106 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
Chris@559 107
Chris@565 108 //! Default constructor that allows an optional client name.
Chris@559 109 /*!
Chris@559 110 An exception will be thrown if a MIDI system initialization error occurs.
Chris@559 111 */
Chris@565 112 RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client") );
Chris@559 113
Chris@559 114 //! If a MIDI connection is still open, it will be closed by the destructor.
Chris@559 115 ~RtMidiIn();
Chris@559 116
Chris@559 117 //! Open a MIDI input connection.
Chris@559 118 /*!
Chris@559 119 An optional port number greater than 0 can be specified.
Chris@559 120 Otherwise, the default or first port found is opened.
Chris@559 121 */
Chris@565 122 void openPort( unsigned int portNumber = 0, const std::string Portname = std::string( "RtMidi Input" ) );
Chris@559 123
Chris@559 124 //! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only).
Chris@559 125 /*!
Chris@559 126 This function creates a virtual MIDI input port to which other
Chris@559 127 software applications can connect. This type of functionality
Chris@559 128 is currently only supported by the Macintosh OS-X and Linux ALSA
Chris@559 129 APIs (the function does nothing for the other APIs).
Chris@559 130 */
Chris@559 131 void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) );
Chris@559 132
Chris@559 133 //! Set a callback function to be invoked for incoming MIDI messages.
Chris@559 134 /*!
Chris@559 135 The callback function will be called whenever an incoming MIDI
Chris@559 136 message is received. While not absolutely necessary, it is best
Chris@559 137 to set the callback function before opening a MIDI port to avoid
Chris@559 138 leaving some messages in the queue.
Chris@559 139 */
Chris@559 140 void setCallback( RtMidiCallback callback, void *userData = 0 );
Chris@559 141
Chris@559 142 //! Cancel use of the current callback function (if one exists).
Chris@559 143 /*!
Chris@559 144 Subsequent incoming MIDI messages will be written to the queue
Chris@559 145 and can be retrieved with the \e getMessage function.
Chris@559 146 */
Chris@559 147 void cancelCallback();
Chris@559 148
Chris@559 149 //! Close an open MIDI connection (if one exists).
Chris@559 150 void closePort( void );
Chris@559 151
Chris@559 152 //! Return the number of available MIDI input ports.
Chris@559 153 unsigned int getPortCount();
Chris@559 154
Chris@559 155 //! Return a string identifier for the specified MIDI input port number.
Chris@559 156 /*!
Chris@559 157 An exception is thrown if an invalid port specifier is provided.
Chris@559 158 */
Chris@559 159 std::string getPortName( unsigned int portNumber = 0 );
Chris@559 160
Chris@559 161 //! Set the maximum number of MIDI messages to be saved in the queue.
Chris@559 162 /*!
Chris@559 163 If the queue size limit is reached, incoming messages will be
Chris@559 164 ignored. The default limit is 1024.
Chris@559 165 */
Chris@559 166 void setQueueSizeLimit( unsigned int queueSize );
Chris@559 167
Chris@559 168 //! Specify whether certain MIDI message types should be queued or ignored during input.
Chris@559 169 /*!
Chris@559 170 By default, MIDI timing and active sensing messages are ignored
Chris@559 171 during message input because of their relative high data rates.
Chris@559 172 MIDI sysex messages are ignored by default as well. Variable
Chris@559 173 values of "true" imply that the respective message type will be
Chris@559 174 ignored.
Chris@559 175 */
Chris@559 176 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
Chris@559 177
Chris@559 178 //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds.
Chris@559 179 /*!
Chris@559 180 This function returns immediately whether a new message is
Chris@559 181 available or not. A valid message is indicated by a non-zero
Chris@559 182 vector size. An exception is thrown if an error occurs during
Chris@559 183 message retrieval or an input connection was not previously
Chris@559 184 established.
Chris@559 185 */
Chris@559 186 double getMessage( std::vector<unsigned char> *message );
Chris@559 187
Chris@559 188 // A MIDI structure used internally by the class to store incoming
Chris@559 189 // messages. Each message represents one and only one MIDI message.
Chris@559 190 struct MidiMessage {
Chris@559 191 std::vector<unsigned char> bytes;
Chris@559 192 double timeStamp;
Chris@559 193
Chris@559 194 // Default constructor.
Chris@559 195 MidiMessage()
Chris@559 196 :bytes(3), timeStamp(0.0) {}
Chris@559 197 };
Chris@559 198
Chris@559 199 // The RtMidiInData structure is used to pass private class data to
Chris@559 200 // the MIDI input handling function or thread.
Chris@559 201 struct RtMidiInData {
Chris@559 202 std::queue<MidiMessage> queue;
Chris@565 203 MidiMessage message;
Chris@559 204 unsigned int queueLimit;
Chris@559 205 unsigned char ignoreFlags;
Chris@559 206 bool doInput;
Chris@559 207 bool firstMessage;
Chris@559 208 void *apiData;
Chris@559 209 bool usingCallback;
Chris@559 210 void *userCallback;
Chris@559 211 void *userData;
Chris@565 212 bool continueSysex;
Chris@559 213
Chris@559 214 // Default constructor.
Chris@559 215 RtMidiInData()
Chris@559 216 : queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
Chris@565 217 apiData(0), usingCallback(false), userCallback(0), userData(0),
Chris@565 218 continueSysex(false) {}
Chris@559 219 };
Chris@559 220
Chris@559 221 private:
Chris@559 222
Chris@565 223 void initialize( const std::string& clientName );
Chris@559 224 RtMidiInData inputData_;
Chris@559 225
Chris@559 226 };
Chris@559 227
Chris@559 228 /**********************************************************************/
Chris@559 229 /*! \class RtMidiOut
Chris@559 230 \brief A realtime MIDI output class.
Chris@559 231
Chris@559 232 This class provides a common, platform-independent API for MIDI
Chris@559 233 output. It allows one to probe available MIDI output ports, to
Chris@559 234 connect to one such port, and to send MIDI bytes immediately over
Chris@559 235 the connection. Create multiple instances of this class to
Chris@559 236 connect to more than one MIDI device at the same time.
Chris@559 237
Chris@565 238 by Gary P. Scavone, 2003-2008.
Chris@559 239 */
Chris@559 240 /**********************************************************************/
Chris@559 241
Chris@559 242 class RtMidiOut : public RtMidi
Chris@559 243 {
Chris@559 244 public:
Chris@559 245
Chris@565 246 //! Default constructor that allows an optional client name.
Chris@559 247 /*!
Chris@559 248 An exception will be thrown if a MIDI system initialization error occurs.
Chris@559 249 */
Chris@565 250 RtMidiOut( const std::string clientName = std::string( "RtMidi Output Client" ) );
Chris@559 251
Chris@559 252 //! The destructor closes any open MIDI connections.
Chris@559 253 ~RtMidiOut();
Chris@559 254
Chris@559 255 //! Open a MIDI output connection.
Chris@559 256 /*!
Chris@559 257 An optional port number greater than 0 can be specified.
Chris@559 258 Otherwise, the default or first port found is opened. An
Chris@559 259 exception is thrown if an error occurs while attempting to make
Chris@559 260 the port connection.
Chris@559 261 */
Chris@565 262 void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
Chris@559 263
Chris@559 264 //! Close an open MIDI connection (if one exists).
Chris@559 265 void closePort();
Chris@559 266
Chris@559 267 //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only).
Chris@559 268 /*!
Chris@559 269 This function creates a virtual MIDI output port to which other
Chris@559 270 software applications can connect. This type of functionality
Chris@559 271 is currently only supported by the Macintosh OS-X and Linux ALSA
Chris@559 272 APIs (the function does nothing with the other APIs). An
Chris@559 273 exception is thrown if an error occurs while attempting to create
Chris@559 274 the virtual port.
Chris@559 275 */
Chris@559 276 void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) );
Chris@559 277
Chris@559 278 //! Return the number of available MIDI output ports.
Chris@559 279 unsigned int getPortCount();
Chris@559 280
Chris@559 281 //! Return a string identifier for the specified MIDI port type and number.
Chris@559 282 /*!
Chris@559 283 An exception is thrown if an invalid port specifier is provided.
Chris@559 284 */
Chris@559 285 std::string getPortName( unsigned int portNumber = 0 );
Chris@559 286
Chris@559 287 //! Immediately send a single message out an open MIDI output port.
Chris@559 288 /*!
Chris@559 289 An exception is thrown if an error occurs during output or an
Chris@559 290 output connection was not previously established.
Chris@559 291 */
Chris@559 292 void sendMessage( std::vector<unsigned char> *message );
Chris@559 293
Chris@559 294 private:
Chris@559 295
Chris@565 296 void initialize( const std::string& clientName );
Chris@559 297 };
Chris@559 298
Chris@559 299 #endif