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