tutorial.txt 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*! \mainpage The RtMidi Tutorial
  2. <CENTER>\ref intro &nbsp;&nbsp; \ref download &nbsp;&nbsp; \ref start &nbsp;&nbsp; \ref error &nbsp;&nbsp; \ref probing &nbsp;&nbsp; \ref output &nbsp;&nbsp; \ref input &nbsp;&nbsp; \ref virtual &nbsp;&nbsp; \ref compiling &nbsp;&nbsp; \ref debug &nbsp;&nbsp; \ref apinotes &nbsp;&nbsp; \ref acknowledge &nbsp;&nbsp; \ref license</CENTER>
  3. \section intro Introduction
  4. RtMidi is a set of C++ classes (RtMidiIn and RtMidiOut) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA & Jack), Macintosh OS X, Windows (Multimedia Library), and SGI operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals:
  5. <UL>
  6. <LI>object oriented C++ design</LI>
  7. <LI>simple, common API across all supported platforms</LI>
  8. <LI>only two header files and one source file for easy inclusion in programming projects</LI>
  9. <LI>MIDI device enumeration</LI>
  10. </UL>
  11. MIDI input and output functionality are separated into two classes, RtMidiIn and RtMidiOut. Each class instance supports only a single MIDI connection. RtMidi does not provide timing functionality (i.e., output messages are sent immediately). Input messages are timestamped with delta times in seconds (via a \c double floating point type). MIDI data is passed to the user as raw bytes using an std::vector<unsigned char>.
  12. \section download Download
  13. Latest Release (7 April 2011): <A href="http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.13.tar.gz">Version 1.0.13</A>
  14. \section start Getting Started
  15. The first thing that must be done when using RtMidi is to create an instance of the RtMidiIn or RtMidiOut subclasses. RtMidi is an abstract base class, which itself cannot be instantiated. Each default constructor attempts to establish any necessary "connections" with the underlying MIDI system. RtMidi uses C++ exceptions to report errors, necessitating try/catch blocks around many member functions. An RtError can be thrown during instantiation in some circumstances. A warning message may also be reported if no MIDI devices are found during instantiation. The RtMidi classes have been designed to work with "hot pluggable" or virtual (software) MIDI devices, making it possible to connect to MIDI devices that may not have been present when the classes were instantiated. The following code example demonstrates default object construction and destruction:
  16. \code
  17. #include "RtMidi.h"
  18. int main()
  19. {
  20. RtMidiIn *midiin = 0;
  21. // RtMidiIn constructor
  22. try {
  23. midiin = new RtMidiIn();
  24. }
  25. catch (RtError &error) {
  26. // Handle the exception here
  27. error.printMessage();
  28. }
  29. // Clean up
  30. delete midiin;
  31. }
  32. \endcode
  33. Obviously, this example doesn't demonstrate any of the real functionality of RtMidi. However, all uses of RtMidi must begin with construction and must end with class destruction. Further, it is necessary that all class methods that can throw a C++ exception be called within a try/catch block.
  34. \section error Error Handling
  35. RtMidi uses a C++ exception handler called RtError, which is declared
  36. and defined in RtError.h. The RtError class is quite simple but it
  37. does allow errors to be "caught" by RtError::Type. Many RtMidi
  38. methods can "throw" an RtError, most typically if a driver error
  39. occurs or an invalid function argument is specified. There are a
  40. number of cases within RtMidi where warning messages may be displayed
  41. but an exception is not thrown. There is a protected RtMidi method,
  42. error(), that can be modified to globally control how these messages
  43. are handled and reported. By default, error messages are not
  44. automatically displayed in RtMidi unless the preprocessor definition
  45. __RTMIDI_DEBUG__ is defined during compilation. Messages associated
  46. with caught exceptions can be displayed with, for example, the
  47. RtError::printMessage() function.
  48. \section probing Probing Ports
  49. A programmer may wish to query the available MIDI ports before deciding which to use. The following example outlines how this can be done.
  50. \code
  51. // midiprobe.cpp
  52. #include <iostream>
  53. #include <cstdlib>
  54. #include "RtMidi.h"
  55. int main()
  56. {
  57. RtMidiIn *midiin = 0;
  58. RtMidiOut *midiout = 0;
  59. // RtMidiIn constructor
  60. try {
  61. midiin = new RtMidiIn();
  62. }
  63. catch ( RtError &error ) {
  64. error.printMessage();
  65. exit( EXIT_FAILURE );
  66. }
  67. // Check inputs.
  68. unsigned int nPorts = midiin->getPortCount();
  69. std::cout << "\nThere are " << nPorts << " MIDI input sources available.\n";
  70. std::string portName;
  71. for ( unsigned int i=0; i<nPorts; i++ ) {
  72. try {
  73. portName = midiin->getPortName(i);
  74. }
  75. catch ( RtError &error ) {
  76. error.printMessage();
  77. goto cleanup;
  78. }
  79. std::cout << " Input Port #" << i+1 << ": " << portName << '\n';
  80. }
  81. // RtMidiOut constructor
  82. try {
  83. midiout = new RtMidiOut();
  84. }
  85. catch ( RtError &error ) {
  86. error.printMessage();
  87. exit( EXIT_FAILURE );
  88. }
  89. // Check outputs.
  90. nPorts = midiout->getPortCount();
  91. std::cout << "\nThere are " << nPorts << " MIDI output ports available.\n";
  92. for ( unsigned int i=0; i<nPorts; i++ ) {
  93. try {
  94. portName = midiout->getPortName(i);
  95. }
  96. catch (RtError &error) {
  97. error.printMessage();
  98. goto cleanup;
  99. }
  100. std::cout << " Output Port #" << i+1 << ": " << portName << '\n';
  101. }
  102. std::cout << '\n';
  103. // Clean up
  104. cleanup:
  105. delete midiin;
  106. delete midiout;
  107. return 0;
  108. }
  109. \endcode
  110. \section output MIDI Output
  111. The RtMidiOut class provides simple functionality to immediately send messages over a MIDI connection. No timing functionality is provided.
  112. In the following example, we omit necessary error checking and details regarding OS-dependent sleep functions. For a complete example, see the \c midiout.cpp program in the \c tests directory.
  113. \code
  114. // midiout.cpp
  115. #include <iostream>
  116. #include <cstdlib>
  117. #include "RtMidi.h"
  118. int main()
  119. {
  120. RtMidiOut *midiout = new RtMidiOut();
  121. std::vector<unsigned char> message;
  122. // Check available ports.
  123. unsigned int nPorts = midiout->getPortCount();
  124. if ( nPorts == 0 ) {
  125. std::cout << "No ports available!\n";
  126. goto cleanup;
  127. }
  128. // Open first available port.
  129. midiout->openPort( 0 );
  130. // Send out a series of MIDI messages.
  131. // Program change: 192, 5
  132. message.push_back( 192 );
  133. message.push_back( 5 );
  134. midiout->sendMessage( &message );
  135. // Control Change: 176, 7, 100 (volume)
  136. message[0] = 176;
  137. message[1] = 7;
  138. message.push_back( 100 );
  139. midiout->sendMessage( &message );
  140. // Note On: 144, 64, 90
  141. message[0] = 144;
  142. message[1] = 64;
  143. message[2] = 90;
  144. midiout->sendMessage( &message );
  145. SLEEP( 500 ); // Platform-dependent ... see example in tests directory.
  146. // Note Off: 128, 64, 40
  147. message[0] = 128;
  148. message[1] = 64;
  149. message[2] = 40;
  150. midiout->sendMessage( &message );
  151. // Clean up
  152. cleanup:
  153. delete midiout;
  154. return 0;
  155. }
  156. \endcode
  157. \section input MIDI Input
  158. The RtMidiIn class uses an internal callback function or thread to receive incoming MIDI messages from a port or device. These messages are then either queued and read by the user via calls to the RtMidiIn::getMessage() function or immediately passed to a user-specified callback function (which must be "registered" using the RtMidiIn::setCallback() function). We'll provide examples of both usages.
  159. The RtMidiIn class provides the RtMidiIn::ignoreTypes() function to specify that certain MIDI message types be ignored. By default, sysem exclusive, timing, and active sensing messages are ignored.
  160. \subsection qmidiin Queued MIDI Input
  161. The RtMidiIn::getMessage() function does not block. If a MIDI message is available in the queue, it is copied to the user-provided \c std::vector<unsigned char> container. When no MIDI message is available, the function returns an empty container. The default maximum MIDI queue size is 1024 messages. This value may be modified with the RtMidiIn::setQueueSizeLimit() function. If the maximum queue size limit is reached, subsequent incoming MIDI messages are discarded until the queue size is reduced.
  162. In the following example, we omit some necessary error checking and details regarding OS-dependent sleep functions. For a more complete example, see the \c qmidiin.cpp program in the \c tests directory.
  163. \code
  164. // qmidiin.cpp
  165. #include <iostream>
  166. #include <cstdlib>
  167. #include <signal.h>
  168. #include "RtMidi.h"
  169. bool done;
  170. static void finish(int ignore){ done = true; }
  171. int main()
  172. {
  173. RtMidiIn *midiin = new RtMidiIn();
  174. std::vector<unsigned char> message;
  175. int nBytes, i;
  176. double stamp;
  177. // Check available ports.
  178. unsigned int nPorts = midiin->getPortCount();
  179. if ( nPorts == 0 ) {
  180. std::cout << "No ports available!\n";
  181. goto cleanup;
  182. }
  183. midiin->openPort( 0 );
  184. // Don't ignore sysex, timing, or active sensing messages.
  185. midiin->ignoreTypes( false, false, false );
  186. // Install an interrupt handler function.
  187. done = false;
  188. (void) signal(SIGINT, finish);
  189. // Periodically check input queue.
  190. std::cout << "Reading MIDI from port ... quit with Ctrl-C.\n";
  191. while ( !done ) {
  192. stamp = midiin->getMessage( &message );
  193. nBytes = message.size();
  194. for ( i=0; i<nBytes; i++ )
  195. std::cout << "Byte " << i << " = " << (int)message[i] << ", ";
  196. if ( nBytes > 0 )
  197. std::cout << "stamp = " << stamp << std::endl;
  198. // Sleep for 10 milliseconds ... platform-dependent.
  199. SLEEP( 10 );
  200. }
  201. // Clean up
  202. cleanup:
  203. delete midiin;
  204. return 0;
  205. }
  206. \endcode
  207. \subsection cmidiin MIDI Input with User Callback
  208. When set, a user-provided callback function will be invoked after the input of a complete MIDI message. It is possible to provide a pointer to user data that can be accessed in the callback function (not shown here). It is necessary to set the callback function immediately after opening the port to avoid having incoming messages written to the queue (which is not emptied when a callback function is set). If you are worried about this happening, you can check the queue using the RtMidi::getMessage() function to verify it is empty (after the callback function is set).
  209. In the following example, we omit some necessary error checking. For a more complete example, see the \c cmidiin.cpp program in the \c tests directory.
  210. \code
  211. // cmidiin.cpp
  212. #include <iostream>
  213. #include <cstdlib>
  214. #include "RtMidi.h"
  215. void mycallback( double deltatime, std::vector< unsigned char > *message, void *userData )
  216. {
  217. unsigned int nBytes = message->size();
  218. for ( unsigned int i=0; i<nBytes; i++ )
  219. std::cout << "Byte " << i << " = " << (int)message->at(i) << ", ";
  220. if ( nBytes > 0 )
  221. std::cout << "stamp = " << deltatime << std::endl;
  222. }
  223. int main()
  224. {
  225. RtMidiIn *midiin = new RtMidiIn();
  226. // Check available ports.
  227. unsigned int nPorts = midiin->getPortCount();
  228. if ( nPorts == 0 ) {
  229. std::cout << "No ports available!\n";
  230. goto cleanup;
  231. }
  232. midiin->openPort( 0 );
  233. // Set our callback function. This should be done immediately after
  234. // opening the port to avoid having incoming messages written to the
  235. // queue.
  236. midiin->setCallback( &mycallback );
  237. // Don't ignore sysex, timing, or active sensing messages.
  238. midiin->ignoreTypes( false, false, false );
  239. std::cout << "\nReading MIDI input ... press <enter> to quit.\n";
  240. char input;
  241. std::cin.get(input);
  242. // Clean up
  243. cleanup:
  244. delete midiin;
  245. return 0;
  246. }
  247. \endcode
  248. \section virtual Virtual Ports
  249. The Linux ALSA and Macintosh CoreMIDI APIs allow for the establishment of virtual input and output MIDI ports to which other software clients can connect. RtMidi incorporates this functionality with the RtMidiIn::openVirtualPort() and RtMidiOut::openVirtualPort() functions. Any messages sent with the RtMidiOut::sendMessage() function will also be transmitted through an open virtual output port. If a virtual input port is open and a user callback function is set, the callback function will be invoked when messages arrive via that port. If a callback function is not set, the user must poll the input queue to check whether messages have arrived. No notification is provided for the establishment of a client connection via a virtual port.
  250. \section compiling Compiling
  251. In order to compile RtMidi for a specific OS and API, it is necessary to supply the appropriate preprocessor definition and library within the compiler statement:
  252. <P>
  253. <TABLE BORDER=2 COLS=5 WIDTH="100%">
  254. <TR BGCOLOR="beige">
  255. <TD WIDTH="5%"><B>OS:</B></TD>
  256. <TD WIDTH="5%"><B>MIDI API:</B></TD>
  257. <TD WIDTH="5%"><B>Preprocessor Definition:</B></TD>
  258. <TD WIDTH="5%"><B>Library or Framework:</B></TD>
  259. <TD><B>Example Compiler Statement:</B></TD>
  260. </TR>
  261. <TR>
  262. <TD>Linux</TD>
  263. <TD>ALSA Sequencer</TD>
  264. <TD>__LINUX_ALSASEQ__</TD>
  265. <TD><TT>asound, pthread</TT></TD>
  266. <TD><TT>g++ -Wall -D__LINUX_ALSASEQ__ -o midiprobe midiprobe.cpp RtMidi.cpp -lasound -lpthread</TT></TD>
  267. </TR>
  268. <TR>
  269. <TD>Linux</TD>
  270. <TD>Jack MIDI</TD>
  271. <TD>__LINUX_JACK__</TD>
  272. <TD><TT>jack</TT></TD>
  273. <TD><TT>g++ -Wall -D__LINUX_JACK__ -o midiprobe midiprobe.cpp RtMidi.cpp -ljack</TT></TD>
  274. </TR>
  275. <TR>
  276. <TD>Macintosh OS X</TD>
  277. <TD>CoreMidi</TD>
  278. <TD>__MACOSX_CORE__</TD>
  279. <TD><TT>CoreMidi, CoreAudio, CoreFoundation</TT></TD>
  280. <TD><TT>g++ -Wall -D__MACOSX_CORE__ -o midiprobe midiprobe.cpp RtMidi.cpp -framework CoreMidi -framework CoreAudio -framework CoreFoundation</TT></TD>
  281. </TR>
  282. <TR>
  283. <TD>Irix</TD>
  284. <TD>MD</TD>
  285. <TD>__IRIX_MD__</TD>
  286. <TD><TT>md, pthread</TT></TD>
  287. <TD><TT>CC -Wall -D__IRIX_MD__ -o midiprobe midiprobe.cpp RtMidi.cpp -laudio -lpthread</TT></TD>
  288. </TR>
  289. <TR>
  290. <TD>Windows</TD>
  291. <TD>Multimedia Library</TD>
  292. <TD>__WINDOWS_MM__</TD>
  293. <TD><TT>winmm.lib, multithreaded</TT></TD>
  294. <TD><I>compiler specific</I></TD>
  295. </TR>
  296. </TABLE>
  297. <P>
  298. The example compiler statements above could be used to compile the <TT>midiprobe.cpp</TT> example file, assuming that <TT>midiprobe.cpp</TT>, <TT>RtMidi.h</TT>, <tt>RtError.h</tt>, and <TT>RtMidi.cpp</TT> all exist in the same directory.
  299. \section debug Debugging
  300. If you are having problems getting RtMidi to run on your system, try passing the preprocessor definition <TT>__RTMIDI_DEBUG__</TT> to the compiler (or define it in RtMidi.h). A variety of warning messages will be displayed that may help in determining the problem. Also try using the programs included in the <tt>test</tt> directory. The program <tt>midiprobe</tt> displays the queried capabilities of all MIDI ports found.
  301. \section apinotes API Notes
  302. RtMidi is designed to provide a common API across the various supported operating systems and audio libraries. Despite that, some issues should be mentioned with regard to each.
  303. \subsection linux Linux:
  304. RtMidi for Linux was developed using the Fedora distribution. A decision was made to not include support for the OSS API because the OSS API provides such limited functionality and because <A href="http://www.alsa-project.org/">ALSA</A> support is now incorporated in the Linux kernel. RtMidi uses the ALSA sequencer API, which allows for virtual software input and output ports.
  305. \subsection macosx Macintosh OS X (CoreAudio):
  306. The Apple CoreMidi API allows for the establishment of virtual input and output ports to which other software applications can connect.
  307. \subsection irix Irix (SGI):
  308. The Irix version of RtMidi was written and tested on an SGI Indy running Irix version 6.5.4 and the MD audio library.
  309. \subsection windowsds Windows (Multimedia Library):
  310. The \c configure script provides support for the MinGW compiler.
  311. The Windows Multimedia library MIDI calls used in RtMidi do not make use of streaming functionality. Incoming system exclusive messages read by RtMidiIn are limited to a length as defined by the preprocessor definition RT_SYSEX_BUFFER_SIZE (set in RtMidi.cpp). The default value is 1024. There is no such limit for outgoing sysex messages via RtMidiOut.
  312. RtMidi was originally developed with Visual C++ version 6.0.
  313. The \c configure script provides support for the MinGW compiler.
  314. \section acknowledge Acknowledgements
  315. Many thanks to the following people for providing bug fixes and improvements:
  316. <UL>
  317. <LI>Jean-Baptiste Berruchon (Windows sysex code)</LI>
  318. <LI>Pedro Lopez-Cabanillas (ALSA sequencer API, client naming)</LI>
  319. <LI>Jason Champion (MSW project file for library build)</LI>
  320. <LI>Eduardo Coutinho (Windows device names)</LI>
  321. <LI>Paul Dean (increment optimization)</LI>
  322. <LI>John Dey (OS-X timestamps)</LI>
  323. <LI>Christoph Eckert (ALSA sysex fixes)</LI>
  324. <LI>Immanuel Litzroth (OS-X sysex fix)</LI>
  325. <LI>Jon McCormack (Snow Leopard updates)</LI>
  326. <LI>Axel Schmidt (client naming)</LI>
  327. <LI>Alexander Svetalkin (Jack MIDI)</LI>
  328. <LI>Casey Tucker (OS-X driver information, sysex sending)</LI>
  329. <LI>Bastiaan Verreijt (Windows sysex multi-buffer code)</LI>
  330. </UL>
  331. \section license License
  332. RtMidi: realtime MIDI i/o C++ classes<BR>
  333. Copyright (c) 2003-2011 Gary P. Scavone
  334. Permission is hereby granted, free of charge, to any person
  335. obtaining a copy of this software and associated documentation files
  336. (the "Software"), to deal in the Software without restriction,
  337. including without limitation the rights to use, copy, modify, merge,
  338. publish, distribute, sublicense, and/or sell copies of the Software,
  339. and to permit persons to whom the Software is furnished to do so,
  340. subject to the following conditions:
  341. The above copyright notice and this permission notice shall be
  342. included in all copies or substantial portions of the Software.
  343. Any person wishing to distribute modifications to the Software is
  344. requested to send the modifications to the original developer so that
  345. they can be incorporated into the canonical version.
  346. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  347. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  348. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  349. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  350. ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  351. CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  352. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  353. */