Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/src/jackbridge/rtmidi/RtMidi.h @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
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 GitHub site: https://github.com/thestk/rtmidi | |
9 RtMidi WWW site: http://www.music.mcgill.ca/~gary/rtmidi/ | |
10 | |
11 RtMidi: realtime MIDI i/o C++ classes | |
12 Copyright (c) 2003-2021 Gary P. Scavone | |
13 | |
14 Permission is hereby granted, free of charge, to any person | |
15 obtaining a copy of this software and associated documentation files | |
16 (the "Software"), to deal in the Software without restriction, | |
17 including without limitation the rights to use, copy, modify, merge, | |
18 publish, distribute, sublicense, and/or sell copies of the Software, | |
19 and to permit persons to whom the Software is furnished to do so, | |
20 subject to the following conditions: | |
21 | |
22 The above copyright notice and this permission notice shall be | |
23 included in all copies or substantial portions of the Software. | |
24 | |
25 Any person wishing to distribute modifications to the Software is | |
26 asked to send the modifications to the original developer so that | |
27 they can be incorporated into the canonical version. This is, | |
28 however, not a binding provision of this license. | |
29 | |
30 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
31 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
32 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
33 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
34 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
35 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
36 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
37 */ | |
38 /**********************************************************************/ | |
39 | |
40 /*! | |
41 \file RtMidi.h | |
42 */ | |
43 | |
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 /************************************************************************/ | |
70 /*! \class RtMidiError | |
71 \brief Exception handling class for RtMidi. | |
72 | |
73 The RtMidiError class is quite simple but it does allow errors to be | |
74 "caught" by RtMidiError::Type. See the RtMidi documentation to know | |
75 which methods can throw an RtMidiError. | |
76 */ | |
77 /************************************************************************/ | |
78 | |
79 class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception | |
80 { | |
81 public: | |
82 //! Defined RtMidiError types. | |
83 enum Type { | |
84 WARNING, /*!< A non-critical error. */ | |
85 DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ | |
86 UNSPECIFIED, /*!< The default, unspecified error type. */ | |
87 NO_DEVICES_FOUND, /*!< No devices found on system. */ | |
88 INVALID_DEVICE, /*!< An invalid device ID was specified. */ | |
89 MEMORY_ERROR, /*!< An error occured during memory allocation. */ | |
90 INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */ | |
91 INVALID_USE, /*!< The function was called incorrectly. */ | |
92 DRIVER_ERROR, /*!< A system driver error occured. */ | |
93 SYSTEM_ERROR, /*!< A system error occured. */ | |
94 THREAD_ERROR /*!< A thread error occured. */ | |
95 }; | |
96 | |
97 //! The constructor. | |
98 RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() | |
99 : message_(message), type_(type) {} | |
100 | |
101 //! The destructor. | |
102 virtual ~RtMidiError( void ) throw() {} | |
103 | |
104 //! Prints thrown error message to stderr. | |
105 virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; } | |
106 | |
107 //! Returns the thrown error message type. | |
108 virtual const Type& getType( void ) const throw() { return type_; } | |
109 | |
110 //! Returns the thrown error message string. | |
111 virtual const std::string& getMessage( void ) const throw() { return message_; } | |
112 | |
113 //! Returns the thrown error message as a c-style string. | |
114 virtual const char* what( void ) const throw() { return message_.c_str(); } | |
115 | |
116 protected: | |
117 std::string message_; | |
118 Type type_; | |
119 }; | |
120 | |
121 //! RtMidi error callback function prototype. | |
122 /*! | |
123 \param type Type of error. | |
124 \param errorText Error description. | |
125 | |
126 Note that class behaviour is undefined after a critical error (not | |
127 a warning) is reported. | |
128 */ | |
129 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData ); | |
130 | |
131 class MidiApi; | |
132 | |
133 class RTMIDI_DLL_PUBLIC RtMidi | |
134 { | |
135 public: | |
136 | |
137 RtMidi(RtMidi&& other) noexcept; | |
138 //! MIDI API specifier arguments. | |
139 enum Api { | |
140 UNSPECIFIED, /*!< Search for a working compiled API. */ | |
141 MACOSX_CORE, /*!< Macintosh OS-X CoreMIDI API. */ | |
142 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ | |
143 UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ | |
144 WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ | |
145 RTMIDI_DUMMY, /*!< A compilable but non-functional API. */ | |
146 WEB_MIDI_API, /*!< W3C Web MIDI API. */ | |
147 NUM_APIS /*!< Number of values in this enum. */ | |
148 }; | |
149 | |
150 //! A static function to determine the current RtMidi version. | |
151 static std::string getVersion( void ) throw(); | |
152 | |
153 //! A static function to determine the available compiled MIDI APIs. | |
154 /*! | |
155 The values returned in the std::vector can be compared against | |
156 the enumerated list values. Note that there can be more than one | |
157 API compiled for certain operating systems. | |
158 */ | |
159 static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw(); | |
160 | |
161 //! Return the name of a specified compiled MIDI API. | |
162 /*! | |
163 This obtains a short lower-case name used for identification purposes. | |
164 This value is guaranteed to remain identical across library versions. | |
165 If the API is unknown, this function will return the empty string. | |
166 */ | |
167 static std::string getApiName( RtMidi::Api api ); | |
168 | |
169 //! Return the display name of a specified compiled MIDI API. | |
170 /*! | |
171 This obtains a long name used for display purposes. | |
172 If the API is unknown, this function will return the empty string. | |
173 */ | |
174 static std::string getApiDisplayName( RtMidi::Api api ); | |
175 | |
176 //! Return the compiled MIDI API having the given name. | |
177 /*! | |
178 A case insensitive comparison will check the specified name | |
179 against the list of compiled APIs, and return the one which | |
180 matches. On failure, the function returns UNSPECIFIED. | |
181 */ | |
182 static RtMidi::Api getCompiledApiByName( const std::string &name ); | |
183 | |
184 //! Pure virtual openPort() function. | |
185 virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0; | |
186 | |
187 //! Pure virtual openVirtualPort() function. | |
188 virtual void openVirtualPort( const std::string &portName = std::string( "RtMidi" ) ) = 0; | |
189 | |
190 //! Pure virtual getPortCount() function. | |
191 virtual unsigned int getPortCount() = 0; | |
192 | |
193 //! Pure virtual getPortName() function. | |
194 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; | |
195 | |
196 //! Pure virtual closePort() function. | |
197 virtual void closePort( void ) = 0; | |
198 | |
199 void setClientName( const std::string &clientName ); | |
200 void setPortName( const std::string &portName ); | |
201 | |
202 //! Returns true if a port is open and false if not. | |
203 /*! | |
204 Note that this only applies to connections made with the openPort() | |
205 function, not to virtual ports. | |
206 */ | |
207 virtual bool isPortOpen( void ) const = 0; | |
208 | |
209 //! Set an error callback function to be invoked when an error has occured. | |
210 /*! | |
211 The callback function will be called whenever an error has occured. It is best | |
212 to set the error callback function before opening a port. | |
213 */ | |
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 /**********************************************************************/ | |
227 /*! \class RtMidiIn | |
228 \brief A realtime MIDI input class. | |
229 | |
230 This class provides a common, platform-independent API for | |
231 realtime MIDI input. It allows access to a single MIDI input | |
232 port. Incoming MIDI messages are either saved to a queue for | |
233 retrieval using the getMessage() function or immediately passed to | |
234 a user-specified callback function. Create multiple instances of | |
235 this class to connect to more than one MIDI device at the same | |
236 time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also | |
237 possible to open a virtual input port to which other MIDI software | |
238 clients can connect. | |
239 */ | |
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: | |
259 //! User callback function type definition. | |
260 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData ); | |
261 | |
262 //! Default constructor that allows an optional api, client name and queue size. | |
263 /*! | |
264 An exception will be thrown if a MIDI system initialization | |
265 error occurs. The queue size defines the maximum number of | |
266 messages that can be held in the MIDI queue (when not using a | |
267 callback function). If the queue size limit is reached, | |
268 incoming messages will be ignored. | |
269 | |
270 If no API argument is specified and multiple API support has been | |
271 compiled, the default order of use is ALSA, JACK (Linux) and CORE, | |
272 JACK (OS-X). | |
273 | |
274 \param api An optional API id can be specified. | |
275 \param clientName An optional client name can be specified. This | |
276 will be used to group the ports that are created | |
277 by the application. | |
278 \param queueSizeLimit An optional size of the MIDI input queue can be specified. | |
279 */ | |
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 | |
286 //! If a MIDI connection is still open, it will be closed by the destructor. | |
287 ~RtMidiIn ( void ) throw(); | |
288 | |
289 //! Returns the MIDI API specifier for the current instance of RtMidiIn. | |
290 RtMidi::Api getCurrentApi( void ) throw(); | |
291 | |
292 //! Open a MIDI input connection given by enumeration number. | |
293 /*! | |
294 \param portNumber An optional port number greater than 0 can be specified. | |
295 Otherwise, the default or first port found is opened. | |
296 \param portName An optional name for the application port that is used to connect to portId can be specified. | |
297 */ | |
298 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) ); | |
299 | |
300 //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). | |
301 /*! | |
302 This function creates a virtual MIDI input port to which other | |
303 software applications can connect. This type of functionality | |
304 is currently only supported by the Macintosh OS-X, any JACK, | |
305 and Linux ALSA APIs (the function returns an error for the other APIs). | |
306 | |
307 \param portName An optional name for the application port that is | |
308 used to connect to portId can be specified. | |
309 */ | |
310 void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) ); | |
311 | |
312 //! Set a callback function to be invoked for incoming MIDI messages. | |
313 /*! | |
314 The callback function will be called whenever an incoming MIDI | |
315 message is received. While not absolutely necessary, it is best | |
316 to set the callback function before opening a MIDI port to avoid | |
317 leaving some messages in the queue. | |
318 | |
319 \param callback A callback function must be given. | |
320 \param userData Optionally, a pointer to additional data can be | |
321 passed to the callback function whenever it is called. | |
322 */ | |
323 void setCallback( RtMidiCallback callback, void *userData = 0 ); | |
324 | |
325 //! Cancel use of the current callback function (if one exists). | |
326 /*! | |
327 Subsequent incoming MIDI messages will be written to the queue | |
328 and can be retrieved with the \e getMessage function. | |
329 */ | |
330 void cancelCallback(); | |
331 | |
332 //! Close an open MIDI connection (if one exists). | |
333 void closePort( void ); | |
334 | |
335 //! Returns true if a port is open and false if not. | |
336 /*! | |
337 Note that this only applies to connections made with the openPort() | |
338 function, not to virtual ports. | |
339 */ | |
340 virtual bool isPortOpen() const; | |
341 | |
342 //! Return the number of available MIDI input ports. | |
343 /*! | |
344 \return This function returns the number of MIDI ports of the selected API. | |
345 */ | |
346 unsigned int getPortCount(); | |
347 | |
348 //! Return a string identifier for the specified MIDI input port number. | |
349 /*! | |
350 \return The name of the port with the given Id is returned. | |
351 \retval An empty string is returned if an invalid port specifier | |
352 is provided. User code should assume a UTF-8 encoding. | |
353 */ | |
354 std::string getPortName( unsigned int portNumber = 0 ); | |
355 | |
356 //! Specify whether certain MIDI message types should be queued or ignored during input. | |
357 /*! | |
358 By default, MIDI timing and active sensing messages are ignored | |
359 during message input because of their relative high data rates. | |
360 MIDI sysex messages are ignored by default as well. Variable | |
361 values of "true" imply that the respective message type will be | |
362 ignored. | |
363 */ | |
364 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); | |
365 | |
366 //! 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. | |
367 /*! | |
368 This function returns immediately whether a new message is | |
369 available or not. A valid message is indicated by a non-zero | |
370 vector size. An exception is thrown if an error occurs during | |
371 message retrieval or an input connection was not previously | |
372 established. | |
373 */ | |
374 double getMessage( std::vector<unsigned char> *message ); | |
375 | |
376 //! Set an error callback function to be invoked when an error has occured. | |
377 /*! | |
378 The callback function will be called whenever an error has occured. It is best | |
379 to set the error callback function before opening a port. | |
380 */ | |
381 virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ); | |
382 | |
383 //! Set maximum expected incoming message size. | |
384 /*! | |
385 For APIs that require manual buffer management, it can be useful to set the buffer | |
386 size and buffer count when expecting to receive large SysEx messages. Note that | |
387 currently this function has no effect when called after openPort(). The default | |
388 buffer size is 1024 with a count of 4 buffers, which should be sufficient for most | |
389 cases; as mentioned, this does not affect all API backends, since most either support | |
390 dynamically scalable buffers or take care of buffer handling themselves. It is | |
391 principally intended for users of the Windows MM backend who must support receiving | |
392 especially large messages. | |
393 */ | |
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 /**********************************************************************/ | |
401 /*! \class RtMidiOut | |
402 \brief A realtime MIDI output class. | |
403 | |
404 This class provides a common, platform-independent API for MIDI | |
405 output. It allows one to probe available MIDI output ports, to | |
406 connect to one such port, and to send MIDI bytes immediately over | |
407 the connection. Create multiple instances of this class to | |
408 connect to more than one MIDI device at the same time. With the | |
409 OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a | |
410 virtual port to which other MIDI software clients can connect. | |
411 */ | |
412 /**********************************************************************/ | |
413 | |
414 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi | |
415 { | |
416 public: | |
417 //! Default constructor that allows an optional client name. | |
418 /*! | |
419 An exception will be thrown if a MIDI system initialization error occurs. | |
420 | |
421 If no API argument is specified and multiple API support has been | |
422 compiled, the default order of use is ALSA, JACK (Linux) and CORE, | |
423 JACK (OS-X). | |
424 */ | |
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 | |
430 //! The destructor closes any open MIDI connections. | |
431 ~RtMidiOut( void ) throw(); | |
432 | |
433 //! Returns the MIDI API specifier for the current instance of RtMidiOut. | |
434 RtMidi::Api getCurrentApi( void ) throw(); | |
435 | |
436 //! Open a MIDI output connection. | |
437 /*! | |
438 An optional port number greater than 0 can be specified. | |
439 Otherwise, the default or first port found is opened. An | |
440 exception is thrown if an error occurs while attempting to make | |
441 the port connection. | |
442 */ | |
443 void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) ); | |
444 | |
445 //! Close an open MIDI connection (if one exists). | |
446 void closePort( void ); | |
447 | |
448 //! Returns true if a port is open and false if not. | |
449 /*! | |
450 Note that this only applies to connections made with the openPort() | |
451 function, not to virtual ports. | |
452 */ | |
453 virtual bool isPortOpen() const; | |
454 | |
455 //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only). | |
456 /*! | |
457 This function creates a virtual MIDI output port to which other | |
458 software applications can connect. This type of functionality | |
459 is currently only supported by the Macintosh OS-X, Linux ALSA | |
460 and JACK APIs (the function does nothing with the other APIs). | |
461 An exception is thrown if an error occurs while attempting to | |
462 create the virtual port. | |
463 */ | |
464 void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) ); | |
465 | |
466 //! Return the number of available MIDI output ports. | |
467 unsigned int getPortCount( void ); | |
468 | |
469 //! Return a string identifier for the specified MIDI port type and number. | |
470 /*! | |
471 \return The name of the port with the given Id is returned. | |
472 \retval An empty string is returned if an invalid port specifier | |
473 is provided. User code should assume a UTF-8 encoding. | |
474 */ | |
475 std::string getPortName( unsigned int portNumber = 0 ); | |
476 | |
477 //! Immediately send a single message out an open MIDI output port. | |
478 /*! | |
479 An exception is thrown if an error occurs during output or an | |
480 output connection was not previously established. | |
481 */ | |
482 void sendMessage( const std::vector<unsigned char> *message ); | |
483 | |
484 //! Immediately send a single message out an open MIDI output port. | |
485 /*! | |
486 An exception is thrown if an error occurs during output or an | |
487 output connection was not previously established. | |
488 | |
489 \param message A pointer to the MIDI message as raw bytes | |
490 \param size Length of the MIDI message in bytes | |
491 */ | |
492 void sendMessage( const unsigned char *message, size_t size ); | |
493 | |
494 //! Set an error callback function to be invoked when an error has occured. | |
495 /*! | |
496 The callback function will be called whenever an error has occured. It is best | |
497 to set the error callback function before opening a port. | |
498 */ | |
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 | |
538 //! A basic error reporting function for RtMidi classes. | |
539 void error( RtMidiError::Type type, std::string errorString ); | |
540 | |
541 protected: | |
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 | |
570 //! Time in seconds elapsed since the previous message | |
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 |