annotate data/midi/rtmidi/RtMidi.h @ 1879:652c5360e682

Ensure transforms are populated before instantiateDefaultPluginFor runs - otherwise if we have prior knowledge of a transform id, we can find ourselves trying to instantiate it before the plugin factory has heard of it and e.g. knows which server to use
author Chris Cannam
date Thu, 25 Jun 2020 12:20:06 +0100
parents 08bbbd2023c4
children
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@1397 11 Copyright (c) 2003-2016 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@1397 25 asked to send the modifications to the original developer so that
Chris@1397 26 they can be incorporated into the canonical version. This is,
Chris@1397 27 however, not a binding provision of this license.
Chris@559 28
Chris@559 29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@559 30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@559 31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@559 32 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@559 33 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@559 34 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@559 35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@559 36 */
Chris@559 37 /**********************************************************************/
Chris@559 38
Chris@1397 39 /*!
Chris@1397 40 \file RtMidi.h
Chris@1397 41 */
Chris@559 42
Chris@559 43 #ifndef RTMIDI_H
Chris@559 44 #define RTMIDI_H
Chris@559 45
Chris@1397 46 #define RTMIDI_VERSION "2.1.1"
Chris@1397 47
Chris@1397 48 #include <exception>
Chris@1397 49 #include <iostream>
Chris@559 50 #include <string>
Chris@1397 51 #include <vector>
Chris@1397 52
Chris@1397 53 /************************************************************************/
Chris@1397 54 /*! \class RtMidiError
Chris@1397 55 \brief Exception handling class for RtMidi.
Chris@1397 56
Chris@1397 57 The RtMidiError class is quite simple but it does allow errors to be
Chris@1397 58 "caught" by RtMidiError::Type. See the RtMidi documentation to know
Chris@1397 59 which methods can throw an RtMidiError.
Chris@1397 60 */
Chris@1397 61 /************************************************************************/
Chris@1397 62
Chris@1397 63 class RtMidiError : public std::exception
Chris@1397 64 {
Chris@1397 65 public:
Chris@1397 66 //! Defined RtMidiError types.
Chris@1397 67 enum Type {
Chris@1397 68 WARNING, /*!< A non-critical error. */
Chris@1397 69 DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */
Chris@1397 70 UNSPECIFIED, /*!< The default, unspecified error type. */
Chris@1397 71 NO_DEVICES_FOUND, /*!< No devices found on system. */
Chris@1397 72 INVALID_DEVICE, /*!< An invalid device ID was specified. */
Chris@1397 73 MEMORY_ERROR, /*!< An error occured during memory allocation. */
Chris@1397 74 INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
Chris@1397 75 INVALID_USE, /*!< The function was called incorrectly. */
Chris@1397 76 DRIVER_ERROR, /*!< A system driver error occured. */
Chris@1397 77 SYSTEM_ERROR, /*!< A system error occured. */
Chris@1397 78 THREAD_ERROR /*!< A thread error occured. */
Chris@1397 79 };
Chris@1397 80
Chris@1397 81 //! The constructor.
Chris@1397 82 RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
Chris@1397 83
Chris@1397 84 //! The destructor.
Chris@1397 85 virtual ~RtMidiError( void ) throw() {}
Chris@1397 86
Chris@1397 87 //! Prints thrown error message to stderr.
Chris@1397 88 virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
Chris@1397 89
Chris@1397 90 //! Returns the thrown error message type.
Chris@1397 91 virtual const Type& getType(void) const throw() { return type_; }
Chris@1397 92
Chris@1397 93 //! Returns the thrown error message string.
Chris@1397 94 virtual const std::string& getMessage(void) const throw() { return message_; }
Chris@1397 95
Chris@1397 96 //! Returns the thrown error message as a c-style string.
Chris@1397 97 virtual const char* what( void ) const throw() { return message_.c_str(); }
Chris@1397 98
Chris@1397 99 protected:
Chris@1397 100 std::string message_;
Chris@1397 101 Type type_;
Chris@1397 102 };
Chris@1397 103
Chris@1397 104 //! RtMidi error callback function prototype.
Chris@1397 105 /*!
Chris@1397 106 \param type Type of error.
Chris@1397 107 \param errorText Error description.
Chris@1397 108
Chris@1397 109 Note that class behaviour is undefined after a critical error (not
Chris@1397 110 a warning) is reported.
Chris@1397 111 */
Chris@1397 112 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
Chris@1397 113
Chris@1397 114 class MidiApi;
Chris@559 115
Chris@559 116 class RtMidi
Chris@559 117 {
Chris@559 118 public:
Chris@559 119
Chris@1397 120 //! MIDI API specifier arguments.
Chris@1397 121 enum Api {
Chris@1397 122 UNSPECIFIED, /*!< Search for a working compiled API. */
Chris@1397 123 MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */
Chris@1397 124 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
Chris@1397 125 UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */
Chris@1397 126 WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
Chris@1397 127 RTMIDI_DUMMY /*!< A compilable but non-functional API. */
Chris@1397 128 };
Chris@1397 129
Chris@1397 130 //! A static function to determine the current RtMidi version.
Chris@1397 131 static std::string getVersion( void ) throw();
Chris@1397 132
Chris@1397 133 //! A static function to determine the available compiled MIDI APIs.
Chris@1397 134 /*!
Chris@1397 135 The values returned in the std::vector can be compared against
Chris@1397 136 the enumerated list values. Note that there can be more than one
Chris@1397 137 API compiled for certain operating systems.
Chris@1397 138 */
Chris@1397 139 static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
Chris@1397 140
Chris@559 141 //! Pure virtual openPort() function.
Chris@565 142 virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
Chris@559 143
Chris@559 144 //! Pure virtual openVirtualPort() function.
Chris@559 145 virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
Chris@559 146
Chris@559 147 //! Pure virtual getPortCount() function.
Chris@559 148 virtual unsigned int getPortCount() = 0;
Chris@559 149
Chris@559 150 //! Pure virtual getPortName() function.
Chris@559 151 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
Chris@559 152
Chris@559 153 //! Pure virtual closePort() function.
Chris@559 154 virtual void closePort( void ) = 0;
Chris@559 155
Chris@1397 156 //! Returns true if a port is open and false if not.
Chris@1397 157 virtual bool isPortOpen( void ) const = 0;
Chris@1397 158
Chris@1397 159 //! Set an error callback function to be invoked when an error has occured.
Chris@1397 160 /*!
Chris@1397 161 The callback function will be called whenever an error has occured. It is best
Chris@1397 162 to set the error callback function before opening a port.
Chris@1397 163 */
Chris@1397 164 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
Chris@1397 165
Chris@559 166 protected:
Chris@559 167
Chris@559 168 RtMidi();
Chris@1397 169 virtual ~RtMidi();
Chris@559 170
Chris@1397 171 MidiApi *rtapi_;
Chris@559 172 };
Chris@559 173
Chris@559 174 /**********************************************************************/
Chris@559 175 /*! \class RtMidiIn
Chris@559 176 \brief A realtime MIDI input class.
Chris@559 177
Chris@559 178 This class provides a common, platform-independent API for
Chris@559 179 realtime MIDI input. It allows access to a single MIDI input
Chris@559 180 port. Incoming MIDI messages are either saved to a queue for
Chris@559 181 retrieval using the getMessage() function or immediately passed to
Chris@559 182 a user-specified callback function. Create multiple instances of
Chris@559 183 this class to connect to more than one MIDI device at the same
Chris@1397 184 time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also
Chris@1397 185 possible to open a virtual input port to which other MIDI software
Chris@1397 186 clients can connect.
Chris@559 187
Chris@1397 188 by Gary P. Scavone, 2003-2014.
Chris@559 189 */
Chris@559 190 /**********************************************************************/
Chris@559 191
Chris@1397 192 // **************************************************************** //
Chris@1397 193 //
Chris@1397 194 // RtMidiIn and RtMidiOut class declarations.
Chris@1397 195 //
Chris@1397 196 // RtMidiIn / RtMidiOut are "controllers" used to select an available
Chris@1397 197 // MIDI input or output interface. They present common APIs for the
Chris@1397 198 // user to call but all functionality is implemented by the classes
Chris@1397 199 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut
Chris@1397 200 // each create an instance of a MidiInApi or MidiOutApi subclass based
Chris@1397 201 // on the user's API choice. If no choice is made, they attempt to
Chris@1397 202 // make a "logical" API selection.
Chris@1397 203 //
Chris@1397 204 // **************************************************************** //
Chris@559 205
Chris@559 206 class RtMidiIn : public RtMidi
Chris@559 207 {
Chris@559 208 public:
Chris@559 209
Chris@559 210 //! User callback function type definition.
Chris@559 211 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
Chris@559 212
Chris@1397 213 //! Default constructor that allows an optional api, client name and queue size.
Chris@559 214 /*!
Chris@1397 215 An exception will be thrown if a MIDI system initialization
Chris@1397 216 error occurs. The queue size defines the maximum number of
Chris@1397 217 messages that can be held in the MIDI queue (when not using a
Chris@1397 218 callback function). If the queue size limit is reached,
Chris@1397 219 incoming messages will be ignored.
Chris@1397 220
Chris@1397 221 If no API argument is specified and multiple API support has been
Chris@1397 222 compiled, the default order of use is ALSA, JACK (Linux) and CORE,
Chris@1397 223 JACK (OS-X).
Chris@1397 224
Chris@1397 225 \param api An optional API id can be specified.
Chris@1397 226 \param clientName An optional client name can be specified. This
Chris@1397 227 will be used to group the ports that are created
Chris@1397 228 by the application.
Chris@1397 229 \param queueSizeLimit An optional size of the MIDI input queue can be specified.
Chris@559 230 */
Chris@1397 231 RtMidiIn( RtMidi::Api api=UNSPECIFIED,
Chris@1397 232 const std::string clientName = std::string( "RtMidi Input Client"),
Chris@1397 233 unsigned int queueSizeLimit = 100 );
Chris@559 234
Chris@559 235 //! If a MIDI connection is still open, it will be closed by the destructor.
Chris@1397 236 ~RtMidiIn ( void ) throw();
Chris@559 237
Chris@1397 238 //! Returns the MIDI API specifier for the current instance of RtMidiIn.
Chris@1397 239 RtMidi::Api getCurrentApi( void ) throw();
Chris@1397 240
Chris@1397 241 //! Open a MIDI input connection given by enumeration number.
Chris@559 242 /*!
Chris@1397 243 \param portNumber An optional port number greater than 0 can be specified.
Chris@1397 244 Otherwise, the default or first port found is opened.
Chris@1397 245 \param portName An optional name for the application port that is used to connect to portId can be specified.
Chris@559 246 */
Chris@1397 247 void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) );
Chris@559 248
Chris@1397 249 //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only).
Chris@559 250 /*!
Chris@1397 251 This function creates a virtual MIDI input port to which other
Chris@1397 252 software applications can connect. This type of functionality
Chris@1397 253 is currently only supported by the Macintosh OS-X, any JACK,
Chris@1397 254 and Linux ALSA APIs (the function returns an error for the other APIs).
Chris@1397 255
Chris@1397 256 \param portName An optional name for the application port that is
Chris@1397 257 used to connect to portId can be specified.
Chris@559 258 */
Chris@559 259 void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) );
Chris@559 260
Chris@559 261 //! Set a callback function to be invoked for incoming MIDI messages.
Chris@559 262 /*!
Chris@1397 263 The callback function will be called whenever an incoming MIDI
Chris@1397 264 message is received. While not absolutely necessary, it is best
Chris@1397 265 to set the callback function before opening a MIDI port to avoid
Chris@1397 266 leaving some messages in the queue.
Chris@1397 267
Chris@1397 268 \param callback A callback function must be given.
Chris@1397 269 \param userData Optionally, a pointer to additional data can be
Chris@1397 270 passed to the callback function whenever it is called.
Chris@559 271 */
Chris@559 272 void setCallback( RtMidiCallback callback, void *userData = 0 );
Chris@559 273
Chris@559 274 //! Cancel use of the current callback function (if one exists).
Chris@559 275 /*!
Chris@1397 276 Subsequent incoming MIDI messages will be written to the queue
Chris@1397 277 and can be retrieved with the \e getMessage function.
Chris@559 278 */
Chris@559 279 void cancelCallback();
Chris@559 280
Chris@559 281 //! Close an open MIDI connection (if one exists).
Chris@559 282 void closePort( void );
Chris@559 283
Chris@1397 284 //! Returns true if a port is open and false if not.
Chris@1397 285 virtual bool isPortOpen() const;
Chris@1397 286
Chris@559 287 //! Return the number of available MIDI input ports.
Chris@1397 288 /*!
Chris@1397 289 \return This function returns the number of MIDI ports of the selected API.
Chris@1397 290 */
Chris@559 291 unsigned int getPortCount();
Chris@559 292
Chris@559 293 //! Return a string identifier for the specified MIDI input port number.
Chris@559 294 /*!
Chris@1397 295 \return The name of the port with the given Id is returned.
Chris@1397 296 \retval An empty string is returned if an invalid port specifier is provided.
Chris@559 297 */
Chris@559 298 std::string getPortName( unsigned int portNumber = 0 );
Chris@559 299
Chris@559 300 //! Specify whether certain MIDI message types should be queued or ignored during input.
Chris@559 301 /*!
Chris@1397 302 By default, MIDI timing and active sensing messages are ignored
Chris@1397 303 during message input because of their relative high data rates.
Chris@1397 304 MIDI sysex messages are ignored by default as well. Variable
Chris@1397 305 values of "true" imply that the respective message type will be
Chris@1397 306 ignored.
Chris@559 307 */
Chris@559 308 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
Chris@559 309
Chris@559 310 //! 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 311 /*!
Chris@1397 312 This function returns immediately whether a new message is
Chris@1397 313 available or not. A valid message is indicated by a non-zero
Chris@1397 314 vector size. An exception is thrown if an error occurs during
Chris@1397 315 message retrieval or an input connection was not previously
Chris@1397 316 established.
Chris@559 317 */
Chris@559 318 double getMessage( std::vector<unsigned char> *message );
Chris@559 319
Chris@1397 320 //! Set an error callback function to be invoked when an error has occured.
Chris@1397 321 /*!
Chris@1397 322 The callback function will be called whenever an error has occured. It is best
Chris@1397 323 to set the error callback function before opening a port.
Chris@1397 324 */
Chris@1397 325 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
Chris@559 326
Chris@1397 327 protected:
Chris@1397 328 void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
Chris@559 329
Chris@559 330 };
Chris@559 331
Chris@559 332 /**********************************************************************/
Chris@559 333 /*! \class RtMidiOut
Chris@559 334 \brief A realtime MIDI output class.
Chris@559 335
Chris@559 336 This class provides a common, platform-independent API for MIDI
Chris@559 337 output. It allows one to probe available MIDI output ports, to
Chris@559 338 connect to one such port, and to send MIDI bytes immediately over
Chris@559 339 the connection. Create multiple instances of this class to
Chris@1397 340 connect to more than one MIDI device at the same time. With the
Chris@1397 341 OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a
Chris@1397 342 virtual port to which other MIDI software clients can connect.
Chris@559 343
Chris@1397 344 by Gary P. Scavone, 2003-2014.
Chris@559 345 */
Chris@559 346 /**********************************************************************/
Chris@559 347
Chris@559 348 class RtMidiOut : public RtMidi
Chris@559 349 {
Chris@559 350 public:
Chris@559 351
Chris@565 352 //! Default constructor that allows an optional client name.
Chris@559 353 /*!
Chris@1397 354 An exception will be thrown if a MIDI system initialization error occurs.
Chris@1397 355
Chris@1397 356 If no API argument is specified and multiple API support has been
Chris@1397 357 compiled, the default order of use is ALSA, JACK (Linux) and CORE,
Chris@1397 358 JACK (OS-X).
Chris@559 359 */
Chris@1397 360 RtMidiOut( RtMidi::Api api=UNSPECIFIED,
Chris@1397 361 const std::string clientName = std::string( "RtMidi Output Client") );
Chris@559 362
Chris@559 363 //! The destructor closes any open MIDI connections.
Chris@1397 364 ~RtMidiOut( void ) throw();
Chris@1397 365
Chris@1397 366 //! Returns the MIDI API specifier for the current instance of RtMidiOut.
Chris@1397 367 RtMidi::Api getCurrentApi( void ) throw();
Chris@559 368
Chris@559 369 //! Open a MIDI output connection.
Chris@559 370 /*!
Chris@559 371 An optional port number greater than 0 can be specified.
Chris@559 372 Otherwise, the default or first port found is opened. An
Chris@559 373 exception is thrown if an error occurs while attempting to make
Chris@559 374 the port connection.
Chris@559 375 */
Chris@565 376 void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
Chris@559 377
Chris@559 378 //! Close an open MIDI connection (if one exists).
Chris@1397 379 void closePort( void );
Chris@559 380
Chris@1397 381 //! Returns true if a port is open and false if not.
Chris@1397 382 virtual bool isPortOpen() const;
Chris@1397 383
Chris@1397 384 //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only).
Chris@559 385 /*!
Chris@559 386 This function creates a virtual MIDI output port to which other
Chris@559 387 software applications can connect. This type of functionality
Chris@1397 388 is currently only supported by the Macintosh OS-X, Linux ALSA
Chris@1397 389 and JACK APIs (the function does nothing with the other APIs).
Chris@1397 390 An exception is thrown if an error occurs while attempting to
Chris@1397 391 create the virtual port.
Chris@559 392 */
Chris@559 393 void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) );
Chris@559 394
Chris@559 395 //! Return the number of available MIDI output ports.
Chris@1397 396 unsigned int getPortCount( void );
Chris@559 397
Chris@559 398 //! Return a string identifier for the specified MIDI port type and number.
Chris@559 399 /*!
Chris@1397 400 An empty string is returned if an invalid port specifier is provided.
Chris@559 401 */
Chris@559 402 std::string getPortName( unsigned int portNumber = 0 );
Chris@559 403
Chris@559 404 //! Immediately send a single message out an open MIDI output port.
Chris@559 405 /*!
Chris@559 406 An exception is thrown if an error occurs during output or an
Chris@559 407 output connection was not previously established.
Chris@559 408 */
Chris@559 409 void sendMessage( std::vector<unsigned char> *message );
Chris@559 410
Chris@1397 411 //! Set an error callback function to be invoked when an error has occured.
Chris@1397 412 /*!
Chris@1397 413 The callback function will be called whenever an error has occured. It is best
Chris@1397 414 to set the error callback function before opening a port.
Chris@1397 415 */
Chris@1397 416 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
Chris@559 417
Chris@1397 418 protected:
Chris@1397 419 void openMidiApi( RtMidi::Api api, const std::string clientName );
Chris@1397 420 };
Chris@1397 421
Chris@1397 422
Chris@1397 423 // **************************************************************** //
Chris@1397 424 //
Chris@1397 425 // MidiInApi / MidiOutApi class declarations.
Chris@1397 426 //
Chris@1397 427 // Subclasses of MidiInApi and MidiOutApi contain all API- and
Chris@1397 428 // OS-specific code necessary to fully implement the RtMidi API.
Chris@1397 429 //
Chris@1397 430 // Note that MidiInApi and MidiOutApi are abstract base classes and
Chris@1397 431 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will
Chris@1397 432 // create instances of a MidiInApi or MidiOutApi subclass.
Chris@1397 433 //
Chris@1397 434 // **************************************************************** //
Chris@1397 435
Chris@1397 436 class MidiApi
Chris@1397 437 {
Chris@1397 438 public:
Chris@1397 439
Chris@1397 440 MidiApi();
Chris@1397 441 virtual ~MidiApi();
Chris@1397 442 virtual RtMidi::Api getCurrentApi( void ) = 0;
Chris@1397 443 virtual void openPort( unsigned int portNumber, const std::string portName ) = 0;
Chris@1397 444 virtual void openVirtualPort( const std::string portName ) = 0;
Chris@1397 445 virtual void closePort( void ) = 0;
Chris@1397 446
Chris@1397 447 virtual unsigned int getPortCount( void ) = 0;
Chris@1397 448 virtual std::string getPortName( unsigned int portNumber ) = 0;
Chris@1397 449
Chris@1397 450 inline bool isPortOpen() const { return connected_; }
Chris@1397 451 void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
Chris@1397 452
Chris@1397 453 //! A basic error reporting function for RtMidi classes.
Chris@1397 454 void error( RtMidiError::Type type, std::string errorString );
Chris@1397 455
Chris@1397 456 protected:
Chris@1397 457 virtual void initialize( const std::string& clientName ) = 0;
Chris@1397 458
Chris@1397 459 void *apiData_;
Chris@1397 460 bool connected_;
Chris@1397 461 std::string errorString_;
Chris@1397 462 RtMidiErrorCallback errorCallback_;
Chris@1397 463 bool firstErrorOccurred_;
Chris@1397 464 void *errorCallbackUserData_;
Chris@1397 465 };
Chris@1397 466
Chris@1397 467 class MidiInApi : public MidiApi
Chris@1397 468 {
Chris@1397 469 public:
Chris@1397 470
Chris@1397 471 MidiInApi( unsigned int queueSizeLimit );
Chris@1397 472 virtual ~MidiInApi( void );
Chris@1397 473 void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
Chris@1397 474 void cancelCallback( void );
Chris@1397 475 virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
Chris@1397 476 double getMessage( std::vector<unsigned char> *message );
Chris@1397 477
Chris@1397 478 // A MIDI structure used internally by the class to store incoming
Chris@1397 479 // messages. Each message represents one and only one MIDI message.
Chris@1397 480 struct MidiMessage {
Chris@1397 481 std::vector<unsigned char> bytes;
Chris@1397 482 double timeStamp;
Chris@1397 483
Chris@1397 484 // Default constructor.
Chris@1397 485 MidiMessage()
Chris@1397 486 :bytes(0), timeStamp(0.0) {}
Chris@1397 487 };
Chris@1397 488
Chris@1397 489 struct MidiQueue {
Chris@1397 490 unsigned int front;
Chris@1397 491 unsigned int back;
Chris@1397 492 unsigned int size;
Chris@1397 493 unsigned int ringSize;
Chris@1397 494 MidiMessage *ring;
Chris@1397 495
Chris@1397 496 // Default constructor.
Chris@1397 497 MidiQueue()
Chris@1397 498 :front(0), back(0), size(0), ringSize(0) {}
Chris@1397 499 };
Chris@1397 500
Chris@1397 501 // The RtMidiInData structure is used to pass private class data to
Chris@1397 502 // the MIDI input handling function or thread.
Chris@1397 503 struct RtMidiInData {
Chris@1397 504 MidiQueue queue;
Chris@1397 505 MidiMessage message;
Chris@1397 506 unsigned char ignoreFlags;
Chris@1397 507 bool doInput;
Chris@1397 508 bool firstMessage;
Chris@1397 509 void *apiData;
Chris@1397 510 bool usingCallback;
Chris@1397 511 RtMidiIn::RtMidiCallback userCallback;
Chris@1397 512 void *userData;
Chris@1397 513 bool continueSysex;
Chris@1397 514
Chris@1397 515 // Default constructor.
Chris@1397 516 RtMidiInData()
Chris@1397 517 : ignoreFlags(7), doInput(false), firstMessage(true),
Chris@1397 518 apiData(0), usingCallback(false), userCallback(0), userData(0),
Chris@1397 519 continueSysex(false) {}
Chris@1397 520 };
Chris@1397 521
Chris@1397 522 protected:
Chris@1397 523 RtMidiInData inputData_;
Chris@1397 524 };
Chris@1397 525
Chris@1397 526 class MidiOutApi : public MidiApi
Chris@1397 527 {
Chris@1397 528 public:
Chris@1397 529
Chris@1397 530 MidiOutApi( void );
Chris@1397 531 virtual ~MidiOutApi( void );
Chris@1397 532 virtual void sendMessage( std::vector<unsigned char> *message ) = 0;
Chris@1397 533 };
Chris@1397 534
Chris@1397 535 // **************************************************************** //
Chris@1397 536 //
Chris@1397 537 // Inline RtMidiIn and RtMidiOut definitions.
Chris@1397 538 //
Chris@1397 539 // **************************************************************** //
Chris@1397 540
Chris@1397 541 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
Chris@1397 542 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
Chris@1397 543 inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
Chris@1397 544 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
Chris@1397 545 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
Chris@1397 546 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
Chris@1397 547 inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
Chris@1397 548 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
Chris@1397 549 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
Chris@1397 550 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
Chris@1397 551 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
Chris@1397 552 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
Chris@1397 553
Chris@1397 554 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
Chris@1397 555 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
Chris@1397 556 inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
Chris@1397 557 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
Chris@1397 558 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
Chris@1397 559 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
Chris@1397 560 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
Chris@1397 561 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
Chris@1397 562 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
Chris@1397 563
Chris@1397 564 // **************************************************************** //
Chris@1397 565 //
Chris@1397 566 // MidiInApi and MidiOutApi subclass prototypes.
Chris@1397 567 //
Chris@1397 568 // **************************************************************** //
Chris@1397 569
Chris@1397 570 #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
Chris@1397 571 #define __RTMIDI_DUMMY__
Chris@1397 572 #endif
Chris@1397 573
Chris@1397 574 #if defined(__MACOSX_CORE__)
Chris@1397 575
Chris@1397 576 class MidiInCore: public MidiInApi
Chris@1397 577 {
Chris@1397 578 public:
Chris@1397 579 MidiInCore( const std::string clientName, unsigned int queueSizeLimit );
Chris@1397 580 ~MidiInCore( void );
Chris@1397 581 RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
Chris@1397 582 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 583 void openVirtualPort( const std::string portName );
Chris@1397 584 void closePort( void );
Chris@1397 585 unsigned int getPortCount( void );
Chris@1397 586 std::string getPortName( unsigned int portNumber );
Chris@1397 587
Chris@1397 588 protected:
Chris@1397 589 void initialize( const std::string& clientName );
Chris@1397 590 };
Chris@1397 591
Chris@1397 592 class MidiOutCore: public MidiOutApi
Chris@1397 593 {
Chris@1397 594 public:
Chris@1397 595 MidiOutCore( const std::string clientName );
Chris@1397 596 ~MidiOutCore( void );
Chris@1397 597 RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
Chris@1397 598 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 599 void openVirtualPort( const std::string portName );
Chris@1397 600 void closePort( void );
Chris@1397 601 unsigned int getPortCount( void );
Chris@1397 602 std::string getPortName( unsigned int portNumber );
Chris@1397 603 void sendMessage( std::vector<unsigned char> *message );
Chris@1397 604
Chris@1397 605 protected:
Chris@565 606 void initialize( const std::string& clientName );
Chris@559 607 };
Chris@559 608
Chris@559 609 #endif
Chris@1397 610
Chris@1397 611 #if defined(__UNIX_JACK__)
Chris@1397 612
Chris@1397 613 class MidiInJack: public MidiInApi
Chris@1397 614 {
Chris@1397 615 public:
Chris@1397 616 MidiInJack( const std::string clientName, unsigned int queueSizeLimit );
Chris@1397 617 ~MidiInJack( void );
Chris@1397 618 RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
Chris@1397 619 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 620 void openVirtualPort( const std::string portName );
Chris@1397 621 void closePort( void );
Chris@1397 622 unsigned int getPortCount( void );
Chris@1397 623 std::string getPortName( unsigned int portNumber );
Chris@1397 624
Chris@1397 625 protected:
Chris@1397 626 std::string clientName;
Chris@1397 627
Chris@1397 628 void connect( void );
Chris@1397 629 void initialize( const std::string& clientName );
Chris@1397 630 };
Chris@1397 631
Chris@1397 632 class MidiOutJack: public MidiOutApi
Chris@1397 633 {
Chris@1397 634 public:
Chris@1397 635 MidiOutJack( const std::string clientName );
Chris@1397 636 ~MidiOutJack( void );
Chris@1397 637 RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
Chris@1397 638 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 639 void openVirtualPort( const std::string portName );
Chris@1397 640 void closePort( void );
Chris@1397 641 unsigned int getPortCount( void );
Chris@1397 642 std::string getPortName( unsigned int portNumber );
Chris@1397 643 void sendMessage( std::vector<unsigned char> *message );
Chris@1397 644
Chris@1397 645 protected:
Chris@1397 646 std::string clientName;
Chris@1397 647
Chris@1397 648 void connect( void );
Chris@1397 649 void initialize( const std::string& clientName );
Chris@1397 650 };
Chris@1397 651
Chris@1397 652 #endif
Chris@1397 653
Chris@1397 654 #if defined(__LINUX_ALSA__)
Chris@1397 655
Chris@1397 656 class MidiInAlsa: public MidiInApi
Chris@1397 657 {
Chris@1397 658 public:
Chris@1397 659 MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit );
Chris@1397 660 ~MidiInAlsa( void );
Chris@1397 661 RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
Chris@1397 662 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 663 void openVirtualPort( const std::string portName );
Chris@1397 664 void closePort( void );
Chris@1397 665 unsigned int getPortCount( void );
Chris@1397 666 std::string getPortName( unsigned int portNumber );
Chris@1397 667
Chris@1397 668 protected:
Chris@1397 669 void initialize( const std::string& clientName );
Chris@1397 670 };
Chris@1397 671
Chris@1397 672 class MidiOutAlsa: public MidiOutApi
Chris@1397 673 {
Chris@1397 674 public:
Chris@1397 675 MidiOutAlsa( const std::string clientName );
Chris@1397 676 ~MidiOutAlsa( void );
Chris@1397 677 RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
Chris@1397 678 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 679 void openVirtualPort( const std::string portName );
Chris@1397 680 void closePort( void );
Chris@1397 681 unsigned int getPortCount( void );
Chris@1397 682 std::string getPortName( unsigned int portNumber );
Chris@1397 683 void sendMessage( std::vector<unsigned char> *message );
Chris@1397 684
Chris@1397 685 protected:
Chris@1397 686 void initialize( const std::string& clientName );
Chris@1397 687 };
Chris@1397 688
Chris@1397 689 #endif
Chris@1397 690
Chris@1397 691 #if defined(__WINDOWS_MM__)
Chris@1397 692
Chris@1397 693 class MidiInWinMM: public MidiInApi
Chris@1397 694 {
Chris@1397 695 public:
Chris@1397 696 MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit );
Chris@1397 697 ~MidiInWinMM( void );
Chris@1397 698 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
Chris@1397 699 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 700 void openVirtualPort( const std::string portName );
Chris@1397 701 void closePort( void );
Chris@1397 702 unsigned int getPortCount( void );
Chris@1397 703 std::string getPortName( unsigned int portNumber );
Chris@1397 704
Chris@1397 705 protected:
Chris@1397 706 void initialize( const std::string& clientName );
Chris@1397 707 };
Chris@1397 708
Chris@1397 709 class MidiOutWinMM: public MidiOutApi
Chris@1397 710 {
Chris@1397 711 public:
Chris@1397 712 MidiOutWinMM( const std::string clientName );
Chris@1397 713 ~MidiOutWinMM( void );
Chris@1397 714 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
Chris@1397 715 void openPort( unsigned int portNumber, const std::string portName );
Chris@1397 716 void openVirtualPort( const std::string portName );
Chris@1397 717 void closePort( void );
Chris@1397 718 unsigned int getPortCount( void );
Chris@1397 719 std::string getPortName( unsigned int portNumber );
Chris@1397 720 void sendMessage( std::vector<unsigned char> *message );
Chris@1397 721
Chris@1397 722 protected:
Chris@1397 723 void initialize( const std::string& clientName );
Chris@1397 724 };
Chris@1397 725
Chris@1397 726 #endif
Chris@1397 727
Chris@1397 728 #if defined(__RTMIDI_DUMMY__)
Chris@1397 729
Chris@1397 730 class MidiInDummy: public MidiInApi
Chris@1397 731 {
Chris@1397 732 public:
Chris@1397 733 MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
Chris@1397 734 RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
Chris@1397 735 void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
Chris@1397 736 void openVirtualPort( const std::string /*portName*/ ) {}
Chris@1397 737 void closePort( void ) {}
Chris@1397 738 unsigned int getPortCount( void ) { return 0; }
Chris@1399 739 std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
Chris@1397 740
Chris@1397 741 protected:
Chris@1397 742 void initialize( const std::string& /*clientName*/ ) {}
Chris@1397 743 };
Chris@1397 744
Chris@1397 745 class MidiOutDummy: public MidiOutApi
Chris@1397 746 {
Chris@1397 747 public:
Chris@1397 748 MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
Chris@1397 749 RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
Chris@1397 750 void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
Chris@1397 751 void openVirtualPort( const std::string /*portName*/ ) {}
Chris@1397 752 void closePort( void ) {}
Chris@1397 753 unsigned int getPortCount( void ) { return 0; }
Chris@1397 754 std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
Chris@1397 755 void sendMessage( std::vector<unsigned char> * /*message*/ ) {}
Chris@1397 756
Chris@1397 757 protected:
Chris@1397 758 void initialize( const std::string& /*clientName*/ ) {}
Chris@1397 759 };
Chris@1397 760
Chris@1397 761 #endif
Chris@1397 762
Chris@1397 763 #endif