The RtMidi Tutorial

Tutorial Class/Enum List File List Compound Members C interface

RtMidi.h
Go to the documentation of this file.
1/**********************************************************************/
38/**********************************************************************/
39
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/************************************************************************/
77/************************************************************************/
78
79 class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception
80{
81 public:
83 enum Type {
84 WARNING,
85 DEBUG_WARNING,
86 UNSPECIFIED,
87 NO_DEVICES_FOUND,
88 INVALID_DEVICE,
89 MEMORY_ERROR,
90 INVALID_PARAMETER,
91 INVALID_USE,
92 DRIVER_ERROR,
93 SYSTEM_ERROR,
94 THREAD_ERROR
95 };
96
98 RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw()
99 : message_(message), type_(type) {}
100
102 virtual ~RtMidiError( void ) throw() {}
103
105 virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
106
108 virtual const Type& getType( void ) const throw() { return type_; }
109
111 virtual const std::string& getMessage( void ) const throw() { return message_; }
112
114 virtual const char* what( void ) const throw() { return message_.c_str(); }
115
116 protected:
117 std::string message_;
118 Type type_;
119};
120
122
129 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
130
131class MidiApi;
132
133 class RTMIDI_DLL_PUBLIC RtMidi
134{
135 public:
136
137 RtMidi(RtMidi&& other) noexcept;
139 enum Api {
140 UNSPECIFIED,
141 MACOSX_CORE,
142 LINUX_ALSA,
143 UNIX_JACK,
144 WINDOWS_MM,
145 RTMIDI_DUMMY,
146 WEB_MIDI_API,
147 NUM_APIS
148 };
149
151 static std::string getVersion( void ) throw();
152
154
159 static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
160
162
167 static std::string getApiName( RtMidi::Api api );
168
170
174 static std::string getApiDisplayName( RtMidi::Api api );
175
177
182 static RtMidi::Api getCompiledApiByName( const std::string &name );
183
185 virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0;
186
188 virtual void openVirtualPort( const std::string &portName = std::string( "RtMidi" ) ) = 0;
189
191 virtual unsigned int getPortCount() = 0;
192
194 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
195
197 virtual void closePort( void ) = 0;
198
199 void setClientName( const std::string &clientName );
200 void setPortName( const std::string &portName );
201
203
207 virtual bool isPortOpen( void ) const = 0;
208
210
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/**********************************************************************/
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:
260 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData );
261
263
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
287 ~RtMidiIn ( void ) throw();
288
290 RtMidi::Api getCurrentApi( void ) throw();
291
293
298 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) );
299
301
310 void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) );
311
313
323 void setCallback( RtMidiCallback callback, void *userData = 0 );
324
326
330 void cancelCallback();
331
333 void closePort( void );
334
336
340 virtual bool isPortOpen() const;
341
343
346 unsigned int getPortCount();
347
349
354 std::string getPortName( unsigned int portNumber = 0 );
355
357
364 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
365
367
374 double getMessage( std::vector<unsigned char> *message );
375
377
381 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
382
384
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/**********************************************************************/
412/**********************************************************************/
413
414 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
415{
416 public:
418
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
431 ~RtMidiOut( void ) throw();
432
434 RtMidi::Api getCurrentApi( void ) throw();
435
437
443 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) );
444
446 void closePort( void );
447
449
453 virtual bool isPortOpen() const;
454
456
464 void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) );
465
467 unsigned int getPortCount( void );
468
470
475 std::string getPortName( unsigned int portNumber = 0 );
476
478
482 void sendMessage( const std::vector<unsigned char> *message );
483
485
492 void sendMessage( const unsigned char *message, size_t size );
493
495
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
539 void error( RtMidiError::Type type, std::string errorString );
540
541protected:
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
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
RtMidiErrorCallback
void(* RtMidiErrorCallback)(RtMidiError::Type type, const std::string &errorText, void *userData)
RtMidi error callback function prototype.
Definition RtMidi.h:129
MidiApi
Definition RtMidi.h:520
MidiApi::error
void error(RtMidiError::Type type, std::string errorString)
A basic error reporting function for RtMidi classes.
MidiInApi
Definition RtMidi.h:554
MidiOutApi
Definition RtMidi.h:619
RtMidiError
Exception handling class for RtMidi.
Definition RtMidi.h:80
RtMidiError::getMessage
virtual const std::string & getMessage(void) const
Returns the thrown error message string.
Definition RtMidi.h:111
RtMidiError::getType
virtual const Type & getType(void) const
Returns the thrown error message type.
Definition RtMidi.h:108
RtMidiError::printMessage
virtual void printMessage(void) const
Prints thrown error message to stderr.
Definition RtMidi.h:105
RtMidiError::Type
Type
Defined RtMidiError types.
Definition RtMidi.h:83
RtMidiError::INVALID_USE
@ INVALID_USE
Definition RtMidi.h:91
RtMidiError::NO_DEVICES_FOUND
@ NO_DEVICES_FOUND
Definition RtMidi.h:87
RtMidiError::MEMORY_ERROR
@ MEMORY_ERROR
Definition RtMidi.h:89
RtMidiError::INVALID_PARAMETER
@ INVALID_PARAMETER
Definition RtMidi.h:90
RtMidiError::WARNING
@ WARNING
Definition RtMidi.h:84
RtMidiError::INVALID_DEVICE
@ INVALID_DEVICE
Definition RtMidi.h:88
RtMidiError::DRIVER_ERROR
@ DRIVER_ERROR
Definition RtMidi.h:92
RtMidiError::UNSPECIFIED
@ UNSPECIFIED
Definition RtMidi.h:86
RtMidiError::DEBUG_WARNING
@ DEBUG_WARNING
Definition RtMidi.h:85
RtMidiError::SYSTEM_ERROR
@ SYSTEM_ERROR
Definition RtMidi.h:93
RtMidiError::~RtMidiError
virtual ~RtMidiError(void)
The destructor.
Definition RtMidi.h:102
RtMidiError::what
virtual const char * what(void) const
Returns the thrown error message as a c-style string.
Definition RtMidi.h:114
RtMidiError::RtMidiError
RtMidiError(const std::string &message, Type type=RtMidiError::UNSPECIFIED)
The constructor.
Definition RtMidi.h:98
RtMidiIn
A realtime MIDI input class.
Definition RtMidi.h:257
RtMidiIn::RtMidiIn
RtMidiIn(RtMidi::Api api=UNSPECIFIED, const std::string &clientName="RtMidi Input Client", unsigned int queueSizeLimit=100)
Default constructor that allows an optional api, client name and queue size.
RtMidiIn::RtMidiCallback
void(* RtMidiCallback)(double timeStamp, std::vector< unsigned char > *message, void *userData)
User callback function type definition.
Definition RtMidi.h:260
RtMidiIn::~RtMidiIn
~RtMidiIn(void)
If a MIDI connection is still open, it will be closed by the destructor.
RtMidiOut
A realtime MIDI output class.
Definition RtMidi.h:415
RtMidiOut::RtMidiOut
RtMidiOut(RtMidi::Api api=UNSPECIFIED, const std::string &clientName="RtMidi Output Client")
Default constructor that allows an optional client name.
RtMidiOut::~RtMidiOut
~RtMidiOut(void)
The destructor closes any open MIDI connections.
RtMidi
An abstract base class for realtime MIDI input/output.
Definition RtMidi.h:134
RtMidi::getCompiledApi
static void getCompiledApi(std::vector< RtMidi::Api > &apis)
A static function to determine the available compiled MIDI APIs.
RtMidi::openVirtualPort
virtual void openVirtualPort(const std::string &portName=std::string("RtMidi"))=0
Pure virtual openVirtualPort() function.
RtMidi::closePort
virtual void closePort(void)=0
Pure virtual closePort() function.
RtMidi::openPort
virtual void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi"))=0
Pure virtual openPort() function.
RtMidi::getApiDisplayName
static std::string getApiDisplayName(RtMidi::Api api)
Return the display name of a specified compiled MIDI API.
RtMidi::isPortOpen
virtual bool isPortOpen(void) const =0
Returns true if a port is open and false if not.
RtMidi::getApiName
static std::string getApiName(RtMidi::Api api)
Return the name of a specified compiled MIDI API.
RtMidi::getPortName
virtual std::string getPortName(unsigned int portNumber=0)=0
Pure virtual getPortName() function.
RtMidi::getVersion
static std::string getVersion(void)
A static function to determine the current RtMidi version.
RtMidi::getPortCount
virtual unsigned int getPortCount()=0
Pure virtual getPortCount() function.
RtMidi::getCompiledApiByName
static RtMidi::Api getCompiledApiByName(const std::string &name)
Return the compiled MIDI API having the given name.
RtMidi::setErrorCallback
virtual void setErrorCallback(RtMidiErrorCallback errorCallback=NULL, void *userData=0)=0
Set an error callback function to be invoked when an error has occured.
RtMidi::Api
Api
MIDI API specifier arguments.
Definition RtMidi.h:139
RtMidi::UNIX_JACK
@ UNIX_JACK
Definition RtMidi.h:143
RtMidi::LINUX_ALSA
@ LINUX_ALSA
Definition RtMidi.h:142
RtMidi::WEB_MIDI_API
@ WEB_MIDI_API
Definition RtMidi.h:146
RtMidi::MACOSX_CORE
@ MACOSX_CORE
Definition RtMidi.h:141
RtMidi::UNSPECIFIED
@ UNSPECIFIED
Definition RtMidi.h:140
RtMidi::RTMIDI_DUMMY
@ RTMIDI_DUMMY
Definition RtMidi.h:145
RtMidi::WINDOWS_MM
@ WINDOWS_MM
Definition RtMidi.h:144
MidiInApi::MidiMessage
Definition RtMidi.h:567
MidiInApi::MidiMessage::timeStamp
double timeStamp
Time in seconds elapsed since the previous message.
Definition RtMidi.h:571
MidiInApi::MidiQueue
Definition RtMidi.h:578
MidiInApi::RtMidiInData
Definition RtMidi.h:594

| ©2003-2021 Gary P. Scavone, McGill University. All Rights Reserved. Maintained by Gary P. Scavone, gary at music.mcgill.ca