1 /**********************************************************************/ 2 /*! \class RtMidi 3 \brief An abstract base class for realtime MIDI input/output. 4 5 This class implements some common functionality for the realtime 6 MIDI input/output subclasses RtMidiIn and RtMidiOut. 7 8 RtMidi GitHub site: https://github.com/thestk/rtmidi 9 RtMidi WWW site: http://www.music.mcgill.ca/~gary/rtmidi/ 10 11 RtMidi: realtime MIDI i/o C++ classes 12 Copyright (c) 2003-2021 Gary P. Scavone 13 14 Permission is hereby granted, free of charge, to any person 15 obtaining a copy of this software and associated documentation files 16 (the "Software"), to deal in the Software without restriction, 17 including without limitation the rights to use, copy, modify, merge, 18 publish, distribute, sublicense, and/or sell copies of the Software, 19 and to permit persons to whom the Software is furnished to do so, 20 subject to the following conditions: 21 22 The above copyright notice and this permission notice shall be 23 included in all copies or substantial portions of the Software. 24 25 Any person wishing to distribute modifications to the Software is 26 asked to send the modifications to the original developer so that 27 they can be incorporated into the canonical version. This is, 28 however, not a binding provision of this license. 29 30 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 33 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 34 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 35 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 */ 38 /**********************************************************************/ 39 40 /*! 41 \file RtMidi.h 42 */ 43 44 #ifndef RTMIDI_H 45 #define RTMIDI_H 46 47 #if defined _WIN32 || defined __CYGWIN__ 48 #if defined(RTMIDI_EXPORT) 49 #define RTMIDI_DLL_PUBLIC __declspec(dllexport) 50 #else 51 #define RTMIDI_DLL_PUBLIC 52 #endif 53 #else 54 #if __GNUC__ >= 4 55 #define RTMIDI_DLL_PUBLIC __attribute__( (visibility( "default" )) ) 56 #else 57 #define RTMIDI_DLL_PUBLIC 58 #endif 59 #endif 60 61 #define RTMIDI_VERSION "5.0.0" 62 63 #include <exception> 64 #include <iostream> 65 #include <string> 66 #include <vector> 67 68 69 /************************************************************************/ 70 /*! \class RtMidiError 71 \brief Exception handling class for RtMidi. 72 73 The RtMidiError class is quite simple but it does allow errors to be 74 "caught" by RtMidiError::Type. See the RtMidi documentation to know 75 which methods can throw an RtMidiError. 76 */ 77 /************************************************************************/ 78 79 class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception 80 { 81 public: 82 //! Defined RtMidiError types. 83 enum Type { 84 WARNING, /*!< A non-critical error. */ 85 DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ 86 UNSPECIFIED, /*!< The default, unspecified error type. */ 87 NO_DEVICES_FOUND, /*!< No devices found on system. */ 88 INVALID_DEVICE, /*!< An invalid device ID was specified. */ 89 MEMORY_ERROR, /*!< An error occured during memory allocation. */ 90 INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */ 91 INVALID_USE, /*!< The function was called incorrectly. */ 92 DRIVER_ERROR, /*!< A system driver error occured. */ 93 SYSTEM_ERROR, /*!< A system error occured. */ 94 THREAD_ERROR /*!< A thread error occured. */ 95 }; 96 97 //! The constructor. 98 RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() 99 : message_(message), type_(type) {} 100 101 //! The destructor. 102 virtual ~RtMidiError( void ) throw() {} 103 104 //! Prints thrown error message to stderr. 105 virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; } 106 107 //! Returns the thrown error message type. 108 virtual const Type& getType( void ) const throw() { return type_; } 109 110 //! Returns the thrown error message string. 111 virtual const std::string& getMessage( void ) const throw() { return message_; } 112 113 //! Returns the thrown error message as a c-style string. 114 virtual const char* what( void ) const throw() { return message_.c_str(); } 115 116 protected: 117 std::string message_; 118 Type type_; 119 }; 120 121 //! RtMidi error callback function prototype. 122 /*! 123 \param type Type of error. 124 \param errorText Error description. 125 126 Note that class behaviour is undefined after a critical error (not 127 a warning) is reported. 128 */ 129 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData ); 130 131 class MidiApi; 132 133 class RTMIDI_DLL_PUBLIC RtMidi 134 { 135 public: 136 137 RtMidi(RtMidi&& other) noexcept; 138 //! MIDI API specifier arguments. 139 enum Api { 140 UNSPECIFIED, /*!< Search for a working compiled API. */ 141 MACOSX_CORE, /*!< Macintosh OS-X CoreMIDI API. */ 142 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ 143 UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ 144 WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ 145 RTMIDI_DUMMY, /*!< A compilable but non-functional API. */ 146 WEB_MIDI_API, /*!< W3C Web MIDI API. */ 147 NUM_APIS /*!< Number of values in this enum. */ 148 }; 149 150 //! A static function to determine the current RtMidi version. 151 static std::string getVersion( void ) throw(); 152 153 //! A static function to determine the available compiled MIDI APIs. 154 /*! 155 The values returned in the std::vector can be compared against 156 the enumerated list values. Note that there can be more than one 157 API compiled for certain operating systems. 158 */ 159 static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw(); 160 161 //! Return the name of a specified compiled MIDI API. 162 /*! 163 This obtains a short lower-case name used for identification purposes. 164 This value is guaranteed to remain identical across library versions. 165 If the API is unknown, this function will return the empty string. 166 */ 167 static std::string getApiName( RtMidi::Api api ); 168 169 //! Return the display name of a specified compiled MIDI API. 170 /*! 171 This obtains a long name used for display purposes. 172 If the API is unknown, this function will return the empty string. 173 */ 174 static std::string getApiDisplayName( RtMidi::Api api ); 175 176 //! Return the compiled MIDI API having the given name. 177 /*! 178 A case insensitive comparison will check the specified name 179 against the list of compiled APIs, and return the one which 180 matches. On failure, the function returns UNSPECIFIED. 181 */ 182 static RtMidi::Api getCompiledApiByName( const std::string &name ); 183 184 //! Pure virtual openPort() function. 185 virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0; 186 187 //! Pure virtual openVirtualPort() function. 188 virtual void openVirtualPort( const std::string &portName = std::string( "RtMidi" ) ) = 0; 189 190 //! Pure virtual getPortCount() function. 191 virtual unsigned int getPortCount() = 0; 192 193 //! Pure virtual getPortName() function. 194 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; 195 196 //! Pure virtual closePort() function. 197 virtual void closePort( void ) = 0; 198 199 void setClientName( const std::string &clientName ); 200 void setPortName( const std::string &portName ); 201 202 //! Returns true if a port is open and false if not. 203 /*! 204 Note that this only applies to connections made with the openPort() 205 function, not to virtual ports. 206 */ 207 virtual bool isPortOpen( void ) const = 0; 208 209 //! Set an error callback function to be invoked when an error has occured. 210 /*! 211 The callback function will be called whenever an error has occured. It is best 212 to set the error callback function before opening a port. 213 */ 214 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0; 215 216 protected: 217 RtMidi(); 218 virtual ~RtMidi(); 219 MidiApi *rtapi_; 220 221 /* Make the class non-copyable */ 222 RtMidi(RtMidi& other) = delete; 223 RtMidi& operator=(RtMidi& other) = delete; 224 }; 225 226 /**********************************************************************/ 227 /*! \class RtMidiIn 228 \brief A realtime MIDI input class. 229 230 This class provides a common, platform-independent API for 231 realtime MIDI input. It allows access to a single MIDI input 232 port. Incoming MIDI messages are either saved to a queue for 233 retrieval using the getMessage() function or immediately passed to 234 a user-specified callback function. Create multiple instances of 235 this class to connect to more than one MIDI device at the same 236 time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also 237 possible to open a virtual input port to which other MIDI software 238 clients can connect. 239 */ 240 /**********************************************************************/ 241 242 // **************************************************************** // 243 // 244 // RtMidiIn and RtMidiOut class declarations. 245 // 246 // RtMidiIn / RtMidiOut are "controllers" used to select an available 247 // MIDI input or output interface. They present common APIs for the 248 // user to call but all functionality is implemented by the classes 249 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut 250 // each create an instance of a MidiInApi or MidiOutApi subclass based 251 // on the user's API choice. If no choice is made, they attempt to 252 // make a "logical" API selection. 253 // 254 // **************************************************************** // 255 256 class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi 257 { 258 public: 259 //! User callback function type definition. 260 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData ); 261 262 //! Default constructor that allows an optional api, client name and queue size. 263 /*! 264 An exception will be thrown if a MIDI system initialization 265 error occurs. The queue size defines the maximum number of 266 messages that can be held in the MIDI queue (when not using a 267 callback function). If the queue size limit is reached, 268 incoming messages will be ignored. 269 270 If no API argument is specified and multiple API support has been 271 compiled, the default order of use is ALSA, JACK (Linux) and CORE, 272 JACK (OS-X). 273 274 \param api An optional API id can be specified. 275 \param clientName An optional client name can be specified. This 276 will be used to group the ports that are created 277 by the application. 278 \param queueSizeLimit An optional size of the MIDI input queue can be specified. 279 */ 280 RtMidiIn( RtMidi::Api api=UNSPECIFIED, 281 const std::string& clientName = "RtMidi Input Client", 282 unsigned int queueSizeLimit = 100 ); 283 284 RtMidiIn(RtMidiIn&& other) noexcept : RtMidi(std::move(other)) { } 285 286 //! If a MIDI connection is still open, it will be closed by the destructor. 287 ~RtMidiIn ( void ) throw(); 288 289 //! Returns the MIDI API specifier for the current instance of RtMidiIn. 290 RtMidi::Api getCurrentApi( void ) throw(); 291 292 //! Open a MIDI input connection given by enumeration number. 293 /*! 294 \param portNumber An optional port number greater than 0 can be specified. 295 Otherwise, the default or first port found is opened. 296 \param portName An optional name for the application port that is used to connect to portId can be specified. 297 */ 298 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) ); 299 300 //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). 301 /*! 302 This function creates a virtual MIDI input port to which other 303 software applications can connect. This type of functionality 304 is currently only supported by the Macintosh OS-X, any JACK, 305 and Linux ALSA APIs (the function returns an error for the other APIs). 306 307 \param portName An optional name for the application port that is 308 used to connect to portId can be specified. 309 */ 310 void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) ); 311 312 //! Set a callback function to be invoked for incoming MIDI messages. 313 /*! 314 The callback function will be called whenever an incoming MIDI 315 message is received. While not absolutely necessary, it is best 316 to set the callback function before opening a MIDI port to avoid 317 leaving some messages in the queue. 318 319 \param callback A callback function must be given. 320 \param userData Optionally, a pointer to additional data can be 321 passed to the callback function whenever it is called. 322 */ 323 void setCallback( RtMidiCallback callback, void *userData = 0 ); 324 325 //! Cancel use of the current callback function (if one exists). 326 /*! 327 Subsequent incoming MIDI messages will be written to the queue 328 and can be retrieved with the \e getMessage function. 329 */ 330 void cancelCallback(); 331 332 //! Close an open MIDI connection (if one exists). 333 void closePort( void ); 334 335 //! Returns true if a port is open and false if not. 336 /*! 337 Note that this only applies to connections made with the openPort() 338 function, not to virtual ports. 339 */ 340 virtual bool isPortOpen() const; 341 342 //! Return the number of available MIDI input ports. 343 /*! 344 \return This function returns the number of MIDI ports of the selected API. 345 */ 346 unsigned int getPortCount(); 347 348 //! Return a string identifier for the specified MIDI input port number. 349 /*! 350 \return The name of the port with the given Id is returned. 351 \retval An empty string is returned if an invalid port specifier 352 is provided. User code should assume a UTF-8 encoding. 353 */ 354 std::string getPortName( unsigned int portNumber = 0 ); 355 356 //! Specify whether certain MIDI message types should be queued or ignored during input. 357 /*! 358 By default, MIDI timing and active sensing messages are ignored 359 during message input because of their relative high data rates. 360 MIDI sysex messages are ignored by default as well. Variable 361 values of "true" imply that the respective message type will be 362 ignored. 363 */ 364 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); 365 366 //! 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. 367 /*! 368 This function returns immediately whether a new message is 369 available or not. A valid message is indicated by a non-zero 370 vector size. An exception is thrown if an error occurs during 371 message retrieval or an input connection was not previously 372 established. 373 */ 374 double getMessage( std::vector<unsigned char> *message ); 375 376 //! Set an error callback function to be invoked when an error has occured. 377 /*! 378 The callback function will be called whenever an error has occured. It is best 379 to set the error callback function before opening a port. 380 */ 381 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ); 382 383 //! Set maximum expected incoming message size. 384 /*! 385 For APIs that require manual buffer management, it can be useful to set the buffer 386 size and buffer count when expecting to receive large SysEx messages. Note that 387 currently this function has no effect when called after openPort(). The default 388 buffer size is 1024 with a count of 4 buffers, which should be sufficient for most 389 cases; as mentioned, this does not affect all API backends, since most either support 390 dynamically scalable buffers or take care of buffer handling themselves. It is 391 principally intended for users of the Windows MM backend who must support receiving 392 especially large messages. 393 */ 394 virtual void setBufferSize( unsigned int size, unsigned int count ); 395 396 protected: 397 void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit ); 398 }; 399 400 /**********************************************************************/ 401 /*! \class RtMidiOut 402 \brief A realtime MIDI output class. 403 404 This class provides a common, platform-independent API for MIDI 405 output. It allows one to probe available MIDI output ports, to 406 connect to one such port, and to send MIDI bytes immediately over 407 the connection. Create multiple instances of this class to 408 connect to more than one MIDI device at the same time. With the 409 OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a 410 virtual port to which other MIDI software clients can connect. 411 */ 412 /**********************************************************************/ 413 414 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi 415 { 416 public: 417 //! Default constructor that allows an optional client name. 418 /*! 419 An exception will be thrown if a MIDI system initialization error occurs. 420 421 If no API argument is specified and multiple API support has been 422 compiled, the default order of use is ALSA, JACK (Linux) and CORE, 423 JACK (OS-X). 424 */ 425 RtMidiOut( RtMidi::Api api=UNSPECIFIED, 426 const std::string& clientName = "RtMidi Output Client" ); 427 428 RtMidiOut(RtMidiOut&& other) noexcept : RtMidi(std::move(other)) { } 429 430 //! The destructor closes any open MIDI connections. 431 ~RtMidiOut( void ) throw(); 432 433 //! Returns the MIDI API specifier for the current instance of RtMidiOut. 434 RtMidi::Api getCurrentApi( void ) throw(); 435 436 //! Open a MIDI output connection. 437 /*! 438 An optional port number greater than 0 can be specified. 439 Otherwise, the default or first port found is opened. An 440 exception is thrown if an error occurs while attempting to make 441 the port connection. 442 */ 443 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) ); 444 445 //! Close an open MIDI connection (if one exists). 446 void closePort( void ); 447 448 //! Returns true if a port is open and false if not. 449 /*! 450 Note that this only applies to connections made with the openPort() 451 function, not to virtual ports. 452 */ 453 virtual bool isPortOpen() const; 454 455 //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only). 456 /*! 457 This function creates a virtual MIDI output port to which other 458 software applications can connect. This type of functionality 459 is currently only supported by the Macintosh OS-X, Linux ALSA 460 and JACK APIs (the function does nothing with the other APIs). 461 An exception is thrown if an error occurs while attempting to 462 create the virtual port. 463 */ 464 void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) ); 465 466 //! Return the number of available MIDI output ports. 467 unsigned int getPortCount( void ); 468 469 //! Return a string identifier for the specified MIDI port type and number. 470 /*! 471 \return The name of the port with the given Id is returned. 472 \retval An empty string is returned if an invalid port specifier 473 is provided. User code should assume a UTF-8 encoding. 474 */ 475 std::string getPortName( unsigned int portNumber = 0 ); 476 477 //! Immediately send a single message out an open MIDI output port. 478 /*! 479 An exception is thrown if an error occurs during output or an 480 output connection was not previously established. 481 */ 482 void sendMessage( const std::vector<unsigned char> *message ); 483 484 //! Immediately send a single message out an open MIDI output port. 485 /*! 486 An exception is thrown if an error occurs during output or an 487 output connection was not previously established. 488 489 \param message A pointer to the MIDI message as raw bytes 490 \param size Length of the MIDI message in bytes 491 */ 492 void sendMessage( const unsigned char *message, size_t size ); 493 494 //! Set an error callback function to be invoked when an error has occured. 495 /*! 496 The callback function will be called whenever an error has occured. It is best 497 to set the error callback function before opening a port. 498 */ 499 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ); 500 501 protected: 502 void openMidiApi( RtMidi::Api api, const std::string &clientName ); 503 }; 504 505 506 // **************************************************************** // 507 // 508 // MidiInApi / MidiOutApi class declarations. 509 // 510 // Subclasses of MidiInApi and MidiOutApi contain all API- and 511 // OS-specific code necessary to fully implement the RtMidi API. 512 // 513 // Note that MidiInApi and MidiOutApi are abstract base classes and 514 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will 515 // create instances of a MidiInApi or MidiOutApi subclass. 516 // 517 // **************************************************************** // 518 519 class RTMIDI_DLL_PUBLIC MidiApi 520 { 521 public: 522 523 MidiApi(); 524 virtual ~MidiApi(); 525 virtual RtMidi::Api getCurrentApi( void ) = 0; 526 virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0; 527 virtual void openVirtualPort( const std::string &portName ) = 0; 528 virtual void closePort( void ) = 0; 529 virtual void setClientName( const std::string &clientName ) = 0; 530 virtual void setPortName( const std::string &portName ) = 0; 531 532 virtual unsigned int getPortCount( void ) = 0; 533 virtual std::string getPortName( unsigned int portNumber ) = 0; 534 535 inline bool isPortOpen() const { return connected_; } 536 void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ); 537 538 //! A basic error reporting function for RtMidi classes. 539 void error( RtMidiError::Type type, std::string errorString ); 540 541 protected: 542 virtual void initialize( const std::string& clientName ) = 0; 543 544 void *apiData_; 545 bool connected_; 546 std::string errorString_; 547 RtMidiErrorCallback errorCallback_; 548 bool firstErrorOccurred_; 549 void *errorCallbackUserData_; 550 551 }; 552 553 class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi 554 { 555 public: 556 557 MidiInApi( unsigned int queueSizeLimit ); 558 virtual ~MidiInApi( void ); 559 void setCallback( RtMidiIn::RtMidiCallback callback, void *userData ); 560 void cancelCallback( void ); 561 virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); 562 double getMessage( std::vector<unsigned char> *message ); 563 virtual void setBufferSize( unsigned int size, unsigned int count ); 564 565 // A MIDI structure used internally by the class to store incoming 566 // messages. Each message represents one and only one MIDI message. 567 struct MidiMessage { 568 std::vector<unsigned char> bytes; 569 570 //! Time in seconds elapsed since the previous message 571 double timeStamp; 572 573 // Default constructor. 574 MidiMessage() 575 : bytes(0), timeStamp(0.0) {} 576 }; 577 578 struct MidiQueue { 579 unsigned int front; 580 unsigned int back; 581 unsigned int ringSize; 582 MidiMessage *ring; 583 584 // Default constructor. 585 MidiQueue() 586 : front(0), back(0), ringSize(0), ring(0) {} 587 bool push( const MidiMessage& ); 588 bool pop( std::vector<unsigned char>*, double* ); 589 unsigned int size( unsigned int *back=0, unsigned int *front=0 ); 590 }; 591 592 // The RtMidiInData structure is used to pass private class data to 593 // the MIDI input handling function or thread. 594 struct RtMidiInData { 595 MidiQueue queue; 596 MidiMessage message; 597 unsigned char ignoreFlags; 598 bool doInput; 599 bool firstMessage; 600 void *apiData; 601 bool usingCallback; 602 RtMidiIn::RtMidiCallback userCallback; 603 void *userData; 604 bool continueSysex; 605 unsigned int bufferSize; 606 unsigned int bufferCount; 607 608 // Default constructor. 609 RtMidiInData() 610 : ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false), 611 userCallback(0), userData(0), continueSysex(false), bufferSize(1024), bufferCount(4) {} 612 }; 613 614 protected: 615 RtMidiInData inputData_; 616 }; 617 618 class RTMIDI_DLL_PUBLIC MidiOutApi : public MidiApi 619 { 620 public: 621 622 MidiOutApi( void ); 623 virtual ~MidiOutApi( void ); 624 virtual void sendMessage( const unsigned char *message, size_t size ) = 0; 625 }; 626 627 // **************************************************************** // 628 // 629 // Inline RtMidiIn and RtMidiOut definitions. 630 // 631 // **************************************************************** // 632 633 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } 634 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); } 635 inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); } 636 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); } 637 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); } 638 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { static_cast<MidiInApi *>(rtapi_)->setCallback( callback, userData ); } 639 inline void RtMidiIn :: cancelCallback( void ) { static_cast<MidiInApi *>(rtapi_)->cancelCallback(); } 640 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); } 641 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } 642 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); } 643 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); } 644 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); } 645 inline void RtMidiIn :: setBufferSize( unsigned int size, unsigned int count ) { static_cast<MidiInApi *>(rtapi_)->setBufferSize(size, count); } 646 647 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } 648 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); } 649 inline void RtMidiOut :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); } 650 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); } 651 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); } 652 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); } 653 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } 654 inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( &message->at(0), message->size() ); } 655 inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( message, size ); } 656 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); } 657 658 #endif 659