Chris@559: /**********************************************************************/ Chris@559: /*! \class RtMidi Chris@559: \brief An abstract base class for realtime MIDI input/output. Chris@559: Chris@559: This class implements some common functionality for the realtime Chris@559: MIDI input/output subclasses RtMidiIn and RtMidiOut. Chris@559: Chris@559: RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/ Chris@559: Chris@559: RtMidi: realtime MIDI i/o C++ classes Chris@565: Copyright (c) 2003-2009 Gary P. Scavone Chris@559: Chris@559: Permission is hereby granted, free of charge, to any person Chris@559: obtaining a copy of this software and associated documentation files Chris@559: (the "Software"), to deal in the Software without restriction, Chris@559: including without limitation the rights to use, copy, modify, merge, Chris@559: publish, distribute, sublicense, and/or sell copies of the Software, Chris@559: and to permit persons to whom the Software is furnished to do so, Chris@559: subject to the following conditions: Chris@559: Chris@559: The above copyright notice and this permission notice shall be Chris@559: included in all copies or substantial portions of the Software. Chris@559: Chris@559: Any person wishing to distribute modifications to the Software is Chris@559: requested to send the modifications to the original developer so that Chris@559: they can be incorporated into the canonical version. Chris@559: Chris@559: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@559: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@559: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. Chris@559: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR Chris@559: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@559: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@559: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@559: */ Chris@559: /**********************************************************************/ Chris@559: Chris@565: // RtMidi: Version 1.0.8 Chris@559: Chris@559: #ifndef RTMIDI_H Chris@559: #define RTMIDI_H Chris@559: Chris@559: #include "RtError.h" Chris@559: #include Chris@559: Chris@559: class RtMidi Chris@559: { Chris@559: public: Chris@559: Chris@559: //! Pure virtual openPort() function. Chris@565: virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; Chris@559: Chris@559: //! Pure virtual openVirtualPort() function. Chris@559: virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; Chris@559: Chris@559: //! Pure virtual getPortCount() function. Chris@559: virtual unsigned int getPortCount() = 0; Chris@559: Chris@559: //! Pure virtual getPortName() function. Chris@559: virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; Chris@559: Chris@559: //! Pure virtual closePort() function. Chris@559: virtual void closePort( void ) = 0; Chris@559: Chris@559: protected: Chris@559: Chris@559: RtMidi(); Chris@559: virtual ~RtMidi() {}; Chris@559: Chris@559: // A basic error reporting function for internal use in the RtMidi Chris@559: // subclasses. The behavior of this function can be modified to Chris@559: // suit specific needs. Chris@559: void error( RtError::Type type ); Chris@559: Chris@559: void *apiData_; Chris@559: bool connected_; Chris@559: std::string errorString_; Chris@559: }; Chris@559: Chris@559: /**********************************************************************/ Chris@559: /*! \class RtMidiIn Chris@559: \brief A realtime MIDI input class. Chris@559: Chris@559: This class provides a common, platform-independent API for Chris@559: realtime MIDI input. It allows access to a single MIDI input Chris@559: port. Incoming MIDI messages are either saved to a queue for Chris@559: retrieval using the getMessage() function or immediately passed to Chris@559: a user-specified callback function. Create multiple instances of Chris@559: this class to connect to more than one MIDI device at the same Chris@559: time. With the OS-X and Linux ALSA MIDI APIs, it is also possible Chris@559: to open a virtual input port to which other MIDI software clients Chris@559: can connect. Chris@559: Chris@565: by Gary P. Scavone, 2003-2008. Chris@559: */ Chris@559: /**********************************************************************/ Chris@559: Chris@559: #include Chris@559: #include Chris@559: Chris@559: class RtMidiIn : public RtMidi Chris@559: { Chris@559: public: Chris@559: Chris@559: //! User callback function type definition. Chris@559: typedef void (*RtMidiCallback)( double timeStamp, std::vector *message, void *userData); Chris@559: Chris@565: //! Default constructor that allows an optional client name. Chris@559: /*! Chris@559: An exception will be thrown if a MIDI system initialization error occurs. Chris@559: */ Chris@565: RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client") ); Chris@559: Chris@559: //! If a MIDI connection is still open, it will be closed by the destructor. Chris@559: ~RtMidiIn(); Chris@559: Chris@559: //! Open a MIDI input connection. Chris@559: /*! Chris@559: An optional port number greater than 0 can be specified. Chris@559: Otherwise, the default or first port found is opened. Chris@559: */ Chris@565: void openPort( unsigned int portNumber = 0, const std::string Portname = std::string( "RtMidi Input" ) ); Chris@559: Chris@559: //! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only). Chris@559: /*! Chris@559: This function creates a virtual MIDI input port to which other Chris@559: software applications can connect. This type of functionality Chris@559: is currently only supported by the Macintosh OS-X and Linux ALSA Chris@559: APIs (the function does nothing for the other APIs). Chris@559: */ Chris@559: void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); Chris@559: Chris@559: //! Set a callback function to be invoked for incoming MIDI messages. Chris@559: /*! Chris@559: The callback function will be called whenever an incoming MIDI Chris@559: message is received. While not absolutely necessary, it is best Chris@559: to set the callback function before opening a MIDI port to avoid Chris@559: leaving some messages in the queue. Chris@559: */ Chris@559: void setCallback( RtMidiCallback callback, void *userData = 0 ); Chris@559: Chris@559: //! Cancel use of the current callback function (if one exists). Chris@559: /*! Chris@559: Subsequent incoming MIDI messages will be written to the queue Chris@559: and can be retrieved with the \e getMessage function. Chris@559: */ Chris@559: void cancelCallback(); Chris@559: Chris@559: //! Close an open MIDI connection (if one exists). Chris@559: void closePort( void ); Chris@559: Chris@559: //! Return the number of available MIDI input ports. Chris@559: unsigned int getPortCount(); Chris@559: Chris@559: //! Return a string identifier for the specified MIDI input port number. Chris@559: /*! Chris@559: An exception is thrown if an invalid port specifier is provided. Chris@559: */ Chris@559: std::string getPortName( unsigned int portNumber = 0 ); Chris@559: Chris@559: //! Set the maximum number of MIDI messages to be saved in the queue. Chris@559: /*! Chris@559: If the queue size limit is reached, incoming messages will be Chris@559: ignored. The default limit is 1024. Chris@559: */ Chris@559: void setQueueSizeLimit( unsigned int queueSize ); Chris@559: Chris@559: //! Specify whether certain MIDI message types should be queued or ignored during input. Chris@559: /*! Chris@559: By default, MIDI timing and active sensing messages are ignored Chris@559: during message input because of their relative high data rates. Chris@559: MIDI sysex messages are ignored by default as well. Variable Chris@559: values of "true" imply that the respective message type will be Chris@559: ignored. Chris@559: */ Chris@559: void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); Chris@559: Chris@559: //! 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: /*! Chris@559: This function returns immediately whether a new message is Chris@559: available or not. A valid message is indicated by a non-zero Chris@559: vector size. An exception is thrown if an error occurs during Chris@559: message retrieval or an input connection was not previously Chris@559: established. Chris@559: */ Chris@559: double getMessage( std::vector *message ); Chris@559: Chris@559: // A MIDI structure used internally by the class to store incoming Chris@559: // messages. Each message represents one and only one MIDI message. Chris@559: struct MidiMessage { Chris@559: std::vector bytes; Chris@559: double timeStamp; Chris@559: Chris@559: // Default constructor. Chris@559: MidiMessage() Chris@559: :bytes(3), timeStamp(0.0) {} Chris@559: }; Chris@559: Chris@559: // The RtMidiInData structure is used to pass private class data to Chris@559: // the MIDI input handling function or thread. Chris@559: struct RtMidiInData { Chris@559: std::queue queue; Chris@565: MidiMessage message; Chris@559: unsigned int queueLimit; Chris@559: unsigned char ignoreFlags; Chris@559: bool doInput; Chris@559: bool firstMessage; Chris@559: void *apiData; Chris@559: bool usingCallback; Chris@559: void *userCallback; Chris@559: void *userData; Chris@565: bool continueSysex; Chris@559: Chris@559: // Default constructor. Chris@559: RtMidiInData() Chris@559: : queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true), Chris@565: apiData(0), usingCallback(false), userCallback(0), userData(0), Chris@565: continueSysex(false) {} Chris@559: }; Chris@559: Chris@559: private: Chris@559: Chris@565: void initialize( const std::string& clientName ); Chris@559: RtMidiInData inputData_; Chris@559: Chris@559: }; Chris@559: Chris@559: /**********************************************************************/ Chris@559: /*! \class RtMidiOut Chris@559: \brief A realtime MIDI output class. Chris@559: Chris@559: This class provides a common, platform-independent API for MIDI Chris@559: output. It allows one to probe available MIDI output ports, to Chris@559: connect to one such port, and to send MIDI bytes immediately over Chris@559: the connection. Create multiple instances of this class to Chris@559: connect to more than one MIDI device at the same time. Chris@559: Chris@565: by Gary P. Scavone, 2003-2008. Chris@559: */ Chris@559: /**********************************************************************/ Chris@559: Chris@559: class RtMidiOut : public RtMidi Chris@559: { Chris@559: public: Chris@559: Chris@565: //! Default constructor that allows an optional client name. Chris@559: /*! Chris@559: An exception will be thrown if a MIDI system initialization error occurs. Chris@559: */ Chris@565: RtMidiOut( const std::string clientName = std::string( "RtMidi Output Client" ) ); Chris@559: Chris@559: //! The destructor closes any open MIDI connections. Chris@559: ~RtMidiOut(); Chris@559: Chris@559: //! Open a MIDI output connection. Chris@559: /*! Chris@559: An optional port number greater than 0 can be specified. Chris@559: Otherwise, the default or first port found is opened. An Chris@559: exception is thrown if an error occurs while attempting to make Chris@559: the port connection. Chris@559: */ Chris@565: void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) ); Chris@559: Chris@559: //! Close an open MIDI connection (if one exists). Chris@559: void closePort(); Chris@559: Chris@559: //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only). Chris@559: /*! Chris@559: This function creates a virtual MIDI output port to which other Chris@559: software applications can connect. This type of functionality Chris@559: is currently only supported by the Macintosh OS-X and Linux ALSA Chris@559: APIs (the function does nothing with the other APIs). An Chris@559: exception is thrown if an error occurs while attempting to create Chris@559: the virtual port. Chris@559: */ Chris@559: void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); Chris@559: Chris@559: //! Return the number of available MIDI output ports. Chris@559: unsigned int getPortCount(); Chris@559: Chris@559: //! Return a string identifier for the specified MIDI port type and number. Chris@559: /*! Chris@559: An exception is thrown if an invalid port specifier is provided. Chris@559: */ Chris@559: std::string getPortName( unsigned int portNumber = 0 ); Chris@559: Chris@559: //! Immediately send a single message out an open MIDI output port. Chris@559: /*! Chris@559: An exception is thrown if an error occurs during output or an Chris@559: output connection was not previously established. Chris@559: */ Chris@559: void sendMessage( std::vector *message ); Chris@559: Chris@559: private: Chris@559: Chris@565: void initialize( const std::string& clientName ); Chris@559: }; Chris@559: Chris@559: #endif