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