mirror of
https://github.com/thestk/stk
synced 2026-02-04 00:26:15 +00:00
Version 4.2.0
This commit is contained in:
committed by
Stephen Sinclair
parent
cf06b7598b
commit
a6381b9d38
310
include/RtMidi.h
310
include/RtMidi.h
@@ -1,80 +1,282 @@
|
||||
/***************************************************/
|
||||
/**********************************************************************/
|
||||
/*! \class RtMidi
|
||||
\brief STK realtime MIDI class.
|
||||
\brief An abstract base class for realtime MIDI input/output.
|
||||
|
||||
At the moment, this object only handles MIDI
|
||||
input, though MIDI output code can go here
|
||||
when someone decides they need it (and writes
|
||||
it).
|
||||
This class implements some common functionality for the realtime
|
||||
MIDI input/output subclasses RtMidiIn and RtMidiOut.
|
||||
|
||||
This object opens a MIDI input device and
|
||||
parses MIDI messages into a MIDI buffer. Time
|
||||
stamp info is converted to a delta-time
|
||||
value. MIDI data is stored as MY_FLOAT to
|
||||
conform with SKINI. System exclusive messages
|
||||
are currently ignored.
|
||||
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
|
||||
|
||||
An optional argument to the constructor can be
|
||||
used to specify a device or card. When no
|
||||
argument is given, a default device is opened.
|
||||
If a device argument fails, a list of available
|
||||
devices is printed to allow selection by the user.
|
||||
RtMidi: realtime MIDI i/o C++ classes
|
||||
Copyright (c) 2003-2004 Gary P. Scavone
|
||||
|
||||
This code is based in part on work of Perry
|
||||
Cook (SGI), Paul Leonard (Linux), the
|
||||
RoseGarden team (Linux), and Bill Putnam
|
||||
(Windows).
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/***************************************************/
|
||||
/**********************************************************************/
|
||||
|
||||
#if !defined(__RTMIDI_H)
|
||||
#define __RTMIDI_H
|
||||
// RtMidi: Version 1.0.2, 21 September 2004
|
||||
|
||||
#include "Stk.h"
|
||||
#ifndef RTMIDI_H
|
||||
#define RTMIDI_H
|
||||
|
||||
class RtMidi : public Stk
|
||||
#include "RtError.h"
|
||||
#include <string>
|
||||
|
||||
class RtMidi
|
||||
{
|
||||
protected:
|
||||
|
||||
RtMidi();
|
||||
|
||||
virtual ~RtMidi() {};
|
||||
|
||||
// A basic error reporting function for internal use in the RtMidi
|
||||
// subclasses. The behavior of this function can be modified to
|
||||
// suit specific needs.
|
||||
void error( RtError::Type type );
|
||||
|
||||
virtual void openPort( unsigned int portNumber = 0 ) = 0;
|
||||
|
||||
void *apiData_;
|
||||
bool connected_;
|
||||
std::string errorString_;
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
/*! \class RtMidiIn
|
||||
\brief A realtime MIDI input class.
|
||||
|
||||
This class provides a common, platform-independent API for
|
||||
realtime MIDI input. It allows access to a single MIDI input
|
||||
port. Incoming MIDI messages are either saved to a queue for
|
||||
retrieval using the getMessage() function or immediately passed to
|
||||
a user-specified callback function. Create multiple instances of
|
||||
this class to connect to more than one MIDI device at the same
|
||||
time. With the OS-X and Linux ALSA MIDI APIs, it is also possible
|
||||
to open a virtual input port to which other MIDI software clients
|
||||
can connect.
|
||||
|
||||
by Gary P. Scavone, 2003-2004.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
class RtMidiIn : public RtMidi
|
||||
{
|
||||
public:
|
||||
//! Default constructor with optional device argument.
|
||||
RtMidi(int device = 0);
|
||||
|
||||
//! Class destructor.
|
||||
~RtMidi();
|
||||
//! User callback function type definition.
|
||||
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
|
||||
|
||||
//! Print out the current message values.
|
||||
void printMessage(void) const;
|
||||
|
||||
//! Check for and parse a new MIDI message in the queue, returning its type.
|
||||
//! Default constructor.
|
||||
/*!
|
||||
If a new message is found, the return value is greater than zero.
|
||||
An exception will be thrown if a MIDI system initialization error occurs.
|
||||
*/
|
||||
int nextMessage(void);
|
||||
RtMidiIn();
|
||||
|
||||
//! Return the current message type.
|
||||
int getType() const;
|
||||
//! If a MIDI connection is still open, it will be closed by the destructor.
|
||||
~RtMidiIn();
|
||||
|
||||
//! Return the current message channel value.
|
||||
int getChannel() const;
|
||||
//! Open a MIDI input connection.
|
||||
/*!
|
||||
An optional port number greater than 0 can be specified.
|
||||
Otherwise, the default or first port found is opened.
|
||||
*/
|
||||
void openPort( unsigned int portNumber = 0 );
|
||||
|
||||
//! Return the current message byte two value.
|
||||
MY_FLOAT getByteTwo() const;
|
||||
//! Create a virtual input port to allow software connections (OS X and ALSA only).
|
||||
/*!
|
||||
This function creates a virtual MIDI input port to which other
|
||||
software applications can connect. This type of functionality
|
||||
is currently only supported by the Macintosh OS-X and Linux ALSA
|
||||
APIs (the function does nothing for the other APIs).
|
||||
*/
|
||||
void openVirtualPort();
|
||||
|
||||
//! Return the current message byte three value.
|
||||
MY_FLOAT getByteThree() const;
|
||||
//! Set a callback function to be invoked for incoming MIDI messages.
|
||||
/*!
|
||||
The callback function will be called whenever an incoming MIDI
|
||||
message is received. While not absolutely necessary, it is best
|
||||
to set the callback function before opening a MIDI port to avoid
|
||||
leaving some messages in the queue.
|
||||
*/
|
||||
void setCallback( RtMidiCallback callback, void *userData = 0 );
|
||||
|
||||
//! Return the current message delta time value in seconds.
|
||||
MY_FLOAT getDeltaTime() const;
|
||||
//! Cancel use of the current callback function (if one exists).
|
||||
/*!
|
||||
Subsequent incoming MIDI messages will be written to the queue
|
||||
and can be retrieved with the \e getMessage function.
|
||||
*/
|
||||
void cancelCallback();
|
||||
|
||||
protected:
|
||||
int messageType;
|
||||
int channel;
|
||||
float byteTwo;
|
||||
float byteThree;
|
||||
MY_FLOAT deltaTime;
|
||||
int readIndex;
|
||||
//! Close an open MIDI connection (if one exists).
|
||||
void closePort( void );
|
||||
|
||||
//! Return the number of available MIDI input ports.
|
||||
unsigned int getPortCount();
|
||||
|
||||
//! Return a string identifier for the specified MIDI input port number.
|
||||
/*!
|
||||
An exception is thrown if an invalid port specifier is provided.
|
||||
*/
|
||||
std::string getPortName( unsigned int portNumber = 0 );
|
||||
|
||||
//! Set the maximum number of MIDI messages to be saved in the queue.
|
||||
/*!
|
||||
If the queue size limit is reached, incoming messages will be
|
||||
ignored. The default limit is 1024.
|
||||
*/
|
||||
void setQueueSizeLimit( unsigned int queueSize );
|
||||
|
||||
//! Specify whether certain MIDI message types should be queued or ignored during input.
|
||||
/*!
|
||||
By default, MIDI timing and active sensing messages are ignored
|
||||
during message input because of their relative high data rates.
|
||||
MIDI sysex messages are ignored by default as well. Variable
|
||||
values of "true" imply that the respective message type will be
|
||||
ignored.
|
||||
*/
|
||||
void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
|
||||
|
||||
//! 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.
|
||||
/*!
|
||||
This function returns immediately whether a new message is
|
||||
available or not. A valid message is indicated by a non-zero
|
||||
vector size. An exception is thrown if an error occurs during
|
||||
message retrieval or an input connection was not previously
|
||||
established.
|
||||
*/
|
||||
double getMessage( std::vector<unsigned char> *message );
|
||||
|
||||
// A MIDI structure used internally by the class to store incoming
|
||||
// messages. Each message represents one and only one MIDI message.
|
||||
struct MidiMessage {
|
||||
std::vector<unsigned char> bytes;
|
||||
double timeStamp;
|
||||
|
||||
// Default constructor.
|
||||
MidiMessage()
|
||||
:bytes(3), timeStamp(0.0) {}
|
||||
};
|
||||
|
||||
// The RtMidiInData structure is used to pass private class data to
|
||||
// the MIDI input handling function or thread.
|
||||
struct RtMidiInData {
|
||||
std::queue<MidiMessage> queue;
|
||||
unsigned int queueLimit;
|
||||
unsigned char ignoreFlags;
|
||||
bool doInput;
|
||||
bool firstMessage;
|
||||
void *apiData;
|
||||
bool usingCallback;
|
||||
void *userCallback;
|
||||
void *userData;
|
||||
|
||||
// Default constructor.
|
||||
RtMidiInData()
|
||||
: queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
|
||||
apiData(0), usingCallback(false), userCallback(0), userData(0) {}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void initialize( void );
|
||||
RtMidiInData inputData_;
|
||||
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
/*! \class RtMidiOut
|
||||
\brief A realtime MIDI output class.
|
||||
|
||||
This class provides a common, platform-independent API for MIDI
|
||||
output. It allows one to probe available MIDI output ports, to
|
||||
connect to one such port, and to send MIDI bytes immediately over
|
||||
the connection. Create multiple instances of this class to
|
||||
connect to more than one MIDI device at the same time.
|
||||
|
||||
by Gary P. Scavone, 2003-2004.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
class RtMidiOut : public RtMidi
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
/*!
|
||||
An exception will be thrown if a MIDI system initialization error occurs.
|
||||
*/
|
||||
RtMidiOut();
|
||||
|
||||
//! The destructor closes any open MIDI connections.
|
||||
~RtMidiOut();
|
||||
|
||||
//! Open a MIDI output connection.
|
||||
/*!
|
||||
An optional port number greater than 0 can be specified.
|
||||
Otherwise, the default or first port found is opened. An
|
||||
exception is thrown if an error occurs while attempting to make
|
||||
the port connection.
|
||||
*/
|
||||
void openPort( unsigned int portNumber = 0 );
|
||||
|
||||
//! Close an open MIDI connection (if one exists).
|
||||
void closePort();
|
||||
|
||||
//! Create a virtual output port to allow software connections (OS X and ALSA only).
|
||||
/*!
|
||||
This function creates a virtual MIDI output port to which other
|
||||
software applications can connect. This type of functionality
|
||||
is currently only supported by the Macintosh OS-X and Linux ALSA
|
||||
APIs (the function does nothing with the other APIs). An
|
||||
exception is thrown if an error occurs while attempting to create
|
||||
the virtual port.
|
||||
*/
|
||||
void openVirtualPort();
|
||||
|
||||
//! Return the number of available MIDI output ports.
|
||||
unsigned int getPortCount();
|
||||
|
||||
//! Return a string identifier for the specified MIDI port type and number.
|
||||
/*!
|
||||
An exception is thrown if an invalid port specifier is provided.
|
||||
*/
|
||||
std::string getPortName( unsigned int portNumber );
|
||||
|
||||
//! Immediately send a single message out an open MIDI output port.
|
||||
/*!
|
||||
An exception is thrown if an error occurs during output or an
|
||||
output connection was not previously established.
|
||||
*/
|
||||
void sendMessage( std::vector<unsigned char> *message );
|
||||
|
||||
private:
|
||||
|
||||
void initialize( void );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user