RtMidi.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /**********************************************************************/
  2. /*! \class RtMidi
  3. \brief An abstract base class for realtime MIDI input/output.
  4. This class implements some common functionality for the realtime
  5. MIDI input/output subclasses RtMidiIn and RtMidiOut.
  6. RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
  7. RtMidi: realtime MIDI i/o C++ classes
  8. Copyright (c) 2003-2004 Gary P. Scavone
  9. Permission is hereby granted, free of charge, to any person
  10. obtaining a copy of this software and associated documentation files
  11. (the "Software"), to deal in the Software without restriction,
  12. including without limitation the rights to use, copy, modify, merge,
  13. publish, distribute, sublicense, and/or sell copies of the Software,
  14. and to permit persons to whom the Software is furnished to do so,
  15. subject to the following conditions:
  16. The above copyright notice and this permission notice shall be
  17. included in all copies or substantial portions of the Software.
  18. Any person wishing to distribute modifications to the Software is
  19. requested to send the modifications to the original developer so that
  20. they can be incorporated into the canonical version.
  21. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  24. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  25. ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  26. CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. */
  29. /**********************************************************************/
  30. // RtMidi: Version 1.0.2, 21 September 2004
  31. #ifndef RTMIDI_H
  32. #define RTMIDI_H
  33. #include "RtError.h"
  34. #include <string>
  35. class RtMidi
  36. {
  37. protected:
  38. RtMidi();
  39. virtual ~RtMidi() {};
  40. // A basic error reporting function for internal use in the RtMidi
  41. // subclasses. The behavior of this function can be modified to
  42. // suit specific needs.
  43. void error( RtError::Type type );
  44. virtual void openPort( unsigned int portNumber = 0 ) = 0;
  45. void *apiData_;
  46. bool connected_;
  47. std::string errorString_;
  48. };
  49. /**********************************************************************/
  50. /*! \class RtMidiIn
  51. \brief A realtime MIDI input class.
  52. This class provides a common, platform-independent API for
  53. realtime MIDI input. It allows access to a single MIDI input
  54. port. Incoming MIDI messages are either saved to a queue for
  55. retrieval using the getMessage() function or immediately passed to
  56. a user-specified callback function. Create multiple instances of
  57. this class to connect to more than one MIDI device at the same
  58. time. With the OS-X and Linux ALSA MIDI APIs, it is also possible
  59. to open a virtual input port to which other MIDI software clients
  60. can connect.
  61. by Gary P. Scavone, 2003-2004.
  62. */
  63. /**********************************************************************/
  64. #include <vector>
  65. #include <queue>
  66. class RtMidiIn : public RtMidi
  67. {
  68. public:
  69. //! User callback function type definition.
  70. typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
  71. //! Default constructor.
  72. /*!
  73. An exception will be thrown if a MIDI system initialization error occurs.
  74. */
  75. RtMidiIn();
  76. //! If a MIDI connection is still open, it will be closed by the destructor.
  77. ~RtMidiIn();
  78. //! Open a MIDI input connection.
  79. /*!
  80. An optional port number greater than 0 can be specified.
  81. Otherwise, the default or first port found is opened.
  82. */
  83. void openPort( unsigned int portNumber = 0 );
  84. //! Create a virtual input port to allow software connections (OS X and ALSA only).
  85. /*!
  86. This function creates a virtual MIDI input port to which other
  87. software applications can connect. This type of functionality
  88. is currently only supported by the Macintosh OS-X and Linux ALSA
  89. APIs (the function does nothing for the other APIs).
  90. */
  91. void openVirtualPort();
  92. //! Set a callback function to be invoked for incoming MIDI messages.
  93. /*!
  94. The callback function will be called whenever an incoming MIDI
  95. message is received. While not absolutely necessary, it is best
  96. to set the callback function before opening a MIDI port to avoid
  97. leaving some messages in the queue.
  98. */
  99. void setCallback( RtMidiCallback callback, void *userData = 0 );
  100. //! Cancel use of the current callback function (if one exists).
  101. /*!
  102. Subsequent incoming MIDI messages will be written to the queue
  103. and can be retrieved with the \e getMessage function.
  104. */
  105. void cancelCallback();
  106. //! Close an open MIDI connection (if one exists).
  107. void closePort( void );
  108. //! Return the number of available MIDI input ports.
  109. unsigned int getPortCount();
  110. //! Return a string identifier for the specified MIDI input port number.
  111. /*!
  112. An exception is thrown if an invalid port specifier is provided.
  113. */
  114. std::string getPortName( unsigned int portNumber = 0 );
  115. //! Set the maximum number of MIDI messages to be saved in the queue.
  116. /*!
  117. If the queue size limit is reached, incoming messages will be
  118. ignored. The default limit is 1024.
  119. */
  120. void setQueueSizeLimit( unsigned int queueSize );
  121. //! Specify whether certain MIDI message types should be queued or ignored during input.
  122. /*!
  123. By default, MIDI timing and active sensing messages are ignored
  124. during message input because of their relative high data rates.
  125. MIDI sysex messages are ignored by default as well. Variable
  126. values of "true" imply that the respective message type will be
  127. ignored.
  128. */
  129. void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
  130. //! 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.
  131. /*!
  132. This function returns immediately whether a new message is
  133. available or not. A valid message is indicated by a non-zero
  134. vector size. An exception is thrown if an error occurs during
  135. message retrieval or an input connection was not previously
  136. established.
  137. */
  138. double getMessage( std::vector<unsigned char> *message );
  139. // A MIDI structure used internally by the class to store incoming
  140. // messages. Each message represents one and only one MIDI message.
  141. struct MidiMessage {
  142. std::vector<unsigned char> bytes;
  143. double timeStamp;
  144. // Default constructor.
  145. MidiMessage()
  146. :bytes(3), timeStamp(0.0) {}
  147. };
  148. // The RtMidiInData structure is used to pass private class data to
  149. // the MIDI input handling function or thread.
  150. struct RtMidiInData {
  151. std::queue<MidiMessage> queue;
  152. unsigned int queueLimit;
  153. unsigned char ignoreFlags;
  154. bool doInput;
  155. bool firstMessage;
  156. void *apiData;
  157. bool usingCallback;
  158. void *userCallback;
  159. void *userData;
  160. // Default constructor.
  161. RtMidiInData()
  162. : queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
  163. apiData(0), usingCallback(false), userCallback(0), userData(0) {}
  164. };
  165. private:
  166. void initialize( void );
  167. RtMidiInData inputData_;
  168. };
  169. /**********************************************************************/
  170. /*! \class RtMidiOut
  171. \brief A realtime MIDI output class.
  172. This class provides a common, platform-independent API for MIDI
  173. output. It allows one to probe available MIDI output ports, to
  174. connect to one such port, and to send MIDI bytes immediately over
  175. the connection. Create multiple instances of this class to
  176. connect to more than one MIDI device at the same time.
  177. by Gary P. Scavone, 2003-2004.
  178. */
  179. /**********************************************************************/
  180. class RtMidiOut : public RtMidi
  181. {
  182. public:
  183. //! Default constructor.
  184. /*!
  185. An exception will be thrown if a MIDI system initialization error occurs.
  186. */
  187. RtMidiOut();
  188. //! The destructor closes any open MIDI connections.
  189. ~RtMidiOut();
  190. //! Open a MIDI output connection.
  191. /*!
  192. An optional port number greater than 0 can be specified.
  193. Otherwise, the default or first port found is opened. An
  194. exception is thrown if an error occurs while attempting to make
  195. the port connection.
  196. */
  197. void openPort( unsigned int portNumber = 0 );
  198. //! Close an open MIDI connection (if one exists).
  199. void closePort();
  200. //! Create a virtual output port to allow software connections (OS X and ALSA only).
  201. /*!
  202. This function creates a virtual MIDI output port to which other
  203. software applications can connect. This type of functionality
  204. is currently only supported by the Macintosh OS-X and Linux ALSA
  205. APIs (the function does nothing with the other APIs). An
  206. exception is thrown if an error occurs while attempting to create
  207. the virtual port.
  208. */
  209. void openVirtualPort();
  210. //! Return the number of available MIDI output ports.
  211. unsigned int getPortCount();
  212. //! Return a string identifier for the specified MIDI port type and number.
  213. /*!
  214. An exception is thrown if an invalid port specifier is provided.
  215. */
  216. std::string getPortName( unsigned int portNumber );
  217. //! Immediately send a single message out an open MIDI output port.
  218. /*!
  219. An exception is thrown if an error occurs during output or an
  220. output connection was not previously established.
  221. */
  222. void sendMessage( std::vector<unsigned char> *message );
  223. private:
  224. void initialize( void );
  225. };
  226. #endif