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