annotate data/midi/rtmidi/RtMidi.h @ 562:ecce042cc374

* Wire up MIDI input port (as far as printing a message when an event comes in, anyway)
author Chris Cannam
date Mon, 23 Feb 2009 17:50:17 +0000
parents 32d156c75df7
children 3086876472dc
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@559 11 Copyright (c) 2003-2007 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@559 38 // RtMidi: Version 1.0.7
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@559 51 virtual void openPort( unsigned int portNumber = 0 ) = 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@559 94 by Gary P. Scavone, 2003-2004.
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@559 108 //! Default constructor.
Chris@559 109 /*!
Chris@559 110 An exception will be thrown if a MIDI system initialization error occurs.
Chris@559 111 */
Chris@562 112 RtMidiIn(std::string inputName = 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@559 122 void openPort( unsigned int portNumber = 0 );
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@559 203 unsigned int queueLimit;
Chris@559 204 unsigned char ignoreFlags;
Chris@559 205 bool doInput;
Chris@559 206 bool firstMessage;
Chris@559 207 void *apiData;
Chris@559 208 bool usingCallback;
Chris@559 209 void *userCallback;
Chris@559 210 void *userData;
Chris@559 211
Chris@559 212 // Default constructor.
Chris@559 213 RtMidiInData()
Chris@559 214 : queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
Chris@559 215 apiData(0), usingCallback(false), userCallback(0), userData(0) {}
Chris@559 216 };
Chris@559 217
Chris@559 218 private:
Chris@559 219
Chris@562 220 void initialize(std::string name);
Chris@559 221 RtMidiInData inputData_;
Chris@559 222
Chris@559 223 };
Chris@559 224
Chris@559 225 /**********************************************************************/
Chris@559 226 /*! \class RtMidiOut
Chris@559 227 \brief A realtime MIDI output class.
Chris@559 228
Chris@559 229 This class provides a common, platform-independent API for MIDI
Chris@559 230 output. It allows one to probe available MIDI output ports, to
Chris@559 231 connect to one such port, and to send MIDI bytes immediately over
Chris@559 232 the connection. Create multiple instances of this class to
Chris@559 233 connect to more than one MIDI device at the same time.
Chris@559 234
Chris@559 235 by Gary P. Scavone, 2003-2004.
Chris@559 236 */
Chris@559 237 /**********************************************************************/
Chris@559 238
Chris@559 239 class RtMidiOut : public RtMidi
Chris@559 240 {
Chris@559 241 public:
Chris@559 242
Chris@559 243 //! Default constructor.
Chris@559 244 /*!
Chris@559 245 An exception will be thrown if a MIDI system initialization error occurs.
Chris@559 246 */
Chris@562 247 RtMidiOut(std::string outputName = "RtMidi Output Client");
Chris@559 248
Chris@559 249 //! The destructor closes any open MIDI connections.
Chris@559 250 ~RtMidiOut();
Chris@559 251
Chris@559 252 //! Open a MIDI output connection.
Chris@559 253 /*!
Chris@559 254 An optional port number greater than 0 can be specified.
Chris@559 255 Otherwise, the default or first port found is opened. An
Chris@559 256 exception is thrown if an error occurs while attempting to make
Chris@559 257 the port connection.
Chris@559 258 */
Chris@559 259 void openPort( unsigned int portNumber = 0 );
Chris@559 260
Chris@559 261 //! Close an open MIDI connection (if one exists).
Chris@559 262 void closePort();
Chris@559 263
Chris@559 264 //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only).
Chris@559 265 /*!
Chris@559 266 This function creates a virtual MIDI output port to which other
Chris@559 267 software applications can connect. This type of functionality
Chris@559 268 is currently only supported by the Macintosh OS-X and Linux ALSA
Chris@559 269 APIs (the function does nothing with the other APIs). An
Chris@559 270 exception is thrown if an error occurs while attempting to create
Chris@559 271 the virtual port.
Chris@559 272 */
Chris@559 273 void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) );
Chris@559 274
Chris@559 275 //! Return the number of available MIDI output ports.
Chris@559 276 unsigned int getPortCount();
Chris@559 277
Chris@559 278 //! Return a string identifier for the specified MIDI port type and number.
Chris@559 279 /*!
Chris@559 280 An exception is thrown if an invalid port specifier is provided.
Chris@559 281 */
Chris@559 282 std::string getPortName( unsigned int portNumber = 0 );
Chris@559 283
Chris@559 284 //! Immediately send a single message out an open MIDI output port.
Chris@559 285 /*!
Chris@559 286 An exception is thrown if an error occurs during output or an
Chris@559 287 output connection was not previously established.
Chris@559 288 */
Chris@559 289 void sendMessage( std::vector<unsigned char> *message );
Chris@559 290
Chris@559 291 private:
Chris@559 292
Chris@562 293 void initialize(std::string name);
Chris@559 294 };
Chris@559 295
Chris@559 296 #endif