mirror of
https://github.com/thestk/stk
synced 2026-05-03 20:38:12 +00:00
Updated RtAudio/RtMidi for new release, plus additional documentation updates.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT(STK, 4.6.0, gary@music.mcgill.ca, stk)
|
AC_INIT(STK, 4.6.1, gary@music.mcgill.ca, stk)
|
||||||
AC_CONFIG_AUX_DIR(config)
|
AC_CONFIG_AUX_DIR(config)
|
||||||
AC_CONFIG_SRCDIR(src/Stk.cpp)
|
AC_CONFIG_SRCDIR(src/Stk.cpp)
|
||||||
AC_CONFIG_FILES(Makefile src/Makefile projects/demo/Makefile projects/effects/Makefile projects/ragamatic/Makefile projects/examples/Makefile projects/examples/libMakefile projects/eguitar/Makefile)
|
AC_CONFIG_FILES(Makefile src/Makefile projects/demo/Makefile projects/effects/Makefile projects/ragamatic/Makefile projects/examples/Makefile projects/examples/libMakefile projects/eguitar/Makefile)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ The Synthesis ToolKit in C++ (STK)
|
|||||||
|
|
||||||
By Perry R. Cook and Gary P. Scavone, 1995--2019.
|
By Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
|
|
||||||
v.4.6.1 (18 April 2017)
|
v.4.6.1 (18 April 2019)
|
||||||
- see github site for complete details (github.com/thestk/stk)
|
- see github site for complete details (github.com/thestk/stk)
|
||||||
- various documentation updates
|
- various documentation updates
|
||||||
- new Recorder (flute a la Verge) class (thanks to Mathias Bredholt)
|
- new Recorder (flute a la Verge) class (thanks to Mathias Bredholt)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
|
and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
|
||||||
(DirectSound, ASIO and WASAPI) operating systems.
|
(DirectSound, ASIO and WASAPI) operating systems.
|
||||||
|
|
||||||
|
RtAudio GitHub site: https://github.com/thestk/rtaudio
|
||||||
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
|
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
|
||||||
|
|
||||||
RtAudio: realtime audio i/o C++ classes
|
RtAudio: realtime audio i/o C++ classes
|
||||||
@@ -45,7 +46,21 @@
|
|||||||
#ifndef __RTAUDIO_H
|
#ifndef __RTAUDIO_H
|
||||||
#define __RTAUDIO_H
|
#define __RTAUDIO_H
|
||||||
|
|
||||||
#define RTAUDIO_VERSION "5.0.0"
|
#define RTAUDIO_VERSION "5.1.0"
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#if defined(RTAUDIO_EXPORT)
|
||||||
|
#define RTAUDIO_DLL_PUBLIC __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define RTAUDIO_DLL_PUBLIC
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) )
|
||||||
|
#else
|
||||||
|
#define RTAUDIO_DLL_PUBLIC
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -179,6 +194,7 @@ static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output
|
|||||||
\param userData A pointer to optional data provided by the client
|
\param userData A pointer to optional data provided by the client
|
||||||
when opening the stream (default = NULL).
|
when opening the stream (default = NULL).
|
||||||
|
|
||||||
|
\return
|
||||||
To continue normal stream operation, the RtAudioCallback function
|
To continue normal stream operation, the RtAudioCallback function
|
||||||
should return a value of zero. To stop the stream and drain the
|
should return a value of zero. To stop the stream and drain the
|
||||||
output buffer, the function should return a value of one. To abort
|
output buffer, the function should return a value of one. To abort
|
||||||
@@ -200,7 +216,7 @@ typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
|
|||||||
*/
|
*/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
class RtAudioError : public std::runtime_error
|
class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Defined RtAudioError types.
|
//! Defined RtAudioError types.
|
||||||
@@ -260,7 +276,7 @@ typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string
|
|||||||
|
|
||||||
class RtApi;
|
class RtApi;
|
||||||
|
|
||||||
class RtAudio
|
class RTAUDIO_DLL_PUBLIC RtAudio
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -275,7 +291,8 @@ class RtAudio
|
|||||||
WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
|
WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
|
||||||
WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
|
WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
|
||||||
WINDOWS_DS, /*!< The Microsoft DirectSound API. */
|
WINDOWS_DS, /*!< The Microsoft DirectSound API. */
|
||||||
RTAUDIO_DUMMY /*!< A compilable but non-functional API. */
|
RTAUDIO_DUMMY, /*!< A compilable but non-functional API. */
|
||||||
|
NUM_APIS /*!< Number of values in this enum. */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! The public device information structure for returning queried values.
|
//! The public device information structure for returning queried values.
|
||||||
@@ -387,6 +404,29 @@ class RtAudio
|
|||||||
*/
|
*/
|
||||||
static void getCompiledApi( std::vector<RtAudio::Api> &apis );
|
static void getCompiledApi( std::vector<RtAudio::Api> &apis );
|
||||||
|
|
||||||
|
//! Return the name of a specified compiled audio API.
|
||||||
|
/*!
|
||||||
|
This obtains a short lower-case name used for identification purposes.
|
||||||
|
This value is guaranteed to remain identical across library versions.
|
||||||
|
If the API is unknown, this function will return the empty string.
|
||||||
|
*/
|
||||||
|
static std::string getApiName( RtAudio::Api api );
|
||||||
|
|
||||||
|
//! Return the display name of a specified compiled audio API.
|
||||||
|
/*!
|
||||||
|
This obtains a long name used for display purposes.
|
||||||
|
If the API is unknown, this function will return the empty string.
|
||||||
|
*/
|
||||||
|
static std::string getApiDisplayName( RtAudio::Api api );
|
||||||
|
|
||||||
|
//! Return the compiled audio API having the given name.
|
||||||
|
/*!
|
||||||
|
A case insensitive comparison will check the specified name
|
||||||
|
against the list of compiled APIs, and return the one which
|
||||||
|
matches. On failure, the function returns UNSPECIFIED.
|
||||||
|
*/
|
||||||
|
static RtAudio::Api getCompiledApiByName( const std::string &name );
|
||||||
|
|
||||||
//! The class constructor.
|
//! The class constructor.
|
||||||
/*!
|
/*!
|
||||||
The constructor performs minor initialization tasks. An exception
|
The constructor performs minor initialization tasks. An exception
|
||||||
@@ -583,6 +623,7 @@ class RtAudio
|
|||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef uintptr_t ThreadHandle;
|
typedef uintptr_t ThreadHandle;
|
||||||
typedef CRITICAL_SECTION StreamMutex;
|
typedef CRITICAL_SECTION StreamMutex;
|
||||||
@@ -651,7 +692,6 @@ class S24 {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
S24( const S24& v ) { *this = v; }
|
|
||||||
S24( const double& d ) { *this = (int) d; }
|
S24( const double& d ) { *this = (int) d; }
|
||||||
S24( const float& f ) { *this = (int) f; }
|
S24( const float& f ) { *this = (int) f; }
|
||||||
S24( const signed short& s ) { *this = (int) s; }
|
S24( const signed short& s ) { *this = (int) s; }
|
||||||
@@ -671,7 +711,7 @@ class S24 {
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
class RtApi
|
class RTAUDIO_DLL_PUBLIC RtApi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -864,7 +904,6 @@ public:
|
|||||||
void startStream( void );
|
void startStream( void );
|
||||||
void stopStream( void );
|
void stopStream( void );
|
||||||
void abortStream( void );
|
void abortStream( void );
|
||||||
long getStreamLatency( void );
|
|
||||||
|
|
||||||
// This function is intended for internal use only. It must be
|
// This function is intended for internal use only. It must be
|
||||||
// public because it is called by the internal callback handler,
|
// public because it is called by the internal callback handler,
|
||||||
@@ -900,7 +939,6 @@ public:
|
|||||||
void startStream( void );
|
void startStream( void );
|
||||||
void stopStream( void );
|
void stopStream( void );
|
||||||
void abortStream( void );
|
void abortStream( void );
|
||||||
long getStreamLatency( void );
|
|
||||||
|
|
||||||
// This function is intended for internal use only. It must be
|
// This function is intended for internal use only. It must be
|
||||||
// public because it is called by the internal callback handler,
|
// public because it is called by the internal callback handler,
|
||||||
@@ -935,7 +973,6 @@ public:
|
|||||||
void startStream( void );
|
void startStream( void );
|
||||||
void stopStream( void );
|
void stopStream( void );
|
||||||
void abortStream( void );
|
void abortStream( void );
|
||||||
long getStreamLatency( void );
|
|
||||||
|
|
||||||
// This function is intended for internal use only. It must be
|
// This function is intended for internal use only. It must be
|
||||||
// public because it is called by the internal callback handler,
|
// public because it is called by the internal callback handler,
|
||||||
@@ -973,7 +1010,6 @@ public:
|
|||||||
void startStream( void );
|
void startStream( void );
|
||||||
void stopStream( void );
|
void stopStream( void );
|
||||||
void abortStream( void );
|
void abortStream( void );
|
||||||
long getStreamLatency( void );
|
|
||||||
|
|
||||||
// This function is intended for internal use only. It must be
|
// This function is intended for internal use only. It must be
|
||||||
// public because it is called by the internal callback handler,
|
// public because it is called by the internal callback handler,
|
||||||
@@ -1003,7 +1039,7 @@ class RtApiWasapi : public RtApi
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RtApiWasapi();
|
RtApiWasapi();
|
||||||
~RtApiWasapi();
|
virtual ~RtApiWasapi();
|
||||||
|
|
||||||
RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
|
RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
|
||||||
unsigned int getDeviceCount( void );
|
unsigned int getDeviceCount( void );
|
||||||
|
|||||||
295
include/RtMidi.h
295
include/RtMidi.h
@@ -5,7 +5,8 @@
|
|||||||
This class implements some common functionality for the realtime
|
This class implements some common functionality for the realtime
|
||||||
MIDI input/output subclasses RtMidiIn and RtMidiOut.
|
MIDI input/output subclasses RtMidiIn and RtMidiOut.
|
||||||
|
|
||||||
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
|
RtMidi GitHub site: https://github.com/thestk/rtmidi
|
||||||
|
RtMidi WWW site: http://www.music.mcgill.ca/~gary/rtmidi/
|
||||||
|
|
||||||
RtMidi: realtime MIDI i/o C++ classes
|
RtMidi: realtime MIDI i/o C++ classes
|
||||||
Copyright (c) 2003-2019 Gary P. Scavone
|
Copyright (c) 2003-2019 Gary P. Scavone
|
||||||
@@ -43,7 +44,21 @@
|
|||||||
#ifndef RTMIDI_H
|
#ifndef RTMIDI_H
|
||||||
#define RTMIDI_H
|
#define RTMIDI_H
|
||||||
|
|
||||||
#define RTMIDI_VERSION "3.0.0"
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#if defined(RTMIDI_EXPORT)
|
||||||
|
#define RTMIDI_DLL_PUBLIC __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define RTMIDI_DLL_PUBLIC
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define RTMIDI_DLL_PUBLIC __attribute__( (visibility( "default" )) )
|
||||||
|
#else
|
||||||
|
#define RTMIDI_DLL_PUBLIC
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RTMIDI_VERSION "4.0.0"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -60,7 +75,7 @@
|
|||||||
*/
|
*/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
class RtMidiError : public std::exception
|
class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Defined RtMidiError types.
|
//! Defined RtMidiError types.
|
||||||
@@ -79,7 +94,8 @@ class RtMidiError : public std::exception
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! The constructor.
|
//! The constructor.
|
||||||
RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
|
RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw()
|
||||||
|
: message_(message), type_(type) {}
|
||||||
|
|
||||||
//! The destructor.
|
//! The destructor.
|
||||||
virtual ~RtMidiError( void ) throw() {}
|
virtual ~RtMidiError( void ) throw() {}
|
||||||
@@ -113,10 +129,9 @@ typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &
|
|||||||
|
|
||||||
class MidiApi;
|
class MidiApi;
|
||||||
|
|
||||||
class RtMidi
|
class RTMIDI_DLL_PUBLIC RtMidi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! MIDI API specifier arguments.
|
//! MIDI API specifier arguments.
|
||||||
enum Api {
|
enum Api {
|
||||||
UNSPECIFIED, /*!< Search for a working compiled API. */
|
UNSPECIFIED, /*!< Search for a working compiled API. */
|
||||||
@@ -124,7 +139,8 @@ class RtMidi
|
|||||||
LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
|
LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
|
||||||
UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */
|
UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */
|
||||||
WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
|
WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
|
||||||
RTMIDI_DUMMY /*!< A compilable but non-functional API. */
|
RTMIDI_DUMMY, /*!< A compilable but non-functional API. */
|
||||||
|
NUM_APIS /*!< Number of values in this enum. */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! A static function to determine the current RtMidi version.
|
//! A static function to determine the current RtMidi version.
|
||||||
@@ -138,6 +154,29 @@ class RtMidi
|
|||||||
*/
|
*/
|
||||||
static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
|
static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
|
||||||
|
|
||||||
|
//! Return the name of a specified compiled MIDI API.
|
||||||
|
/*!
|
||||||
|
This obtains a short lower-case name used for identification purposes.
|
||||||
|
This value is guaranteed to remain identical across library versions.
|
||||||
|
If the API is unknown, this function will return the empty string.
|
||||||
|
*/
|
||||||
|
static std::string getApiName( RtMidi::Api api );
|
||||||
|
|
||||||
|
//! Return the display name of a specified compiled MIDI API.
|
||||||
|
/*!
|
||||||
|
This obtains a long name used for display purposes.
|
||||||
|
If the API is unknown, this function will return the empty string.
|
||||||
|
*/
|
||||||
|
static std::string getApiDisplayName( RtMidi::Api api );
|
||||||
|
|
||||||
|
//! Return the compiled MIDI API having the given name.
|
||||||
|
/*!
|
||||||
|
A case insensitive comparison will check the specified name
|
||||||
|
against the list of compiled APIs, and return the one which
|
||||||
|
matches. On failure, the function returns UNSPECIFIED.
|
||||||
|
*/
|
||||||
|
static RtMidi::Api getCompiledApiByName( const std::string &name );
|
||||||
|
|
||||||
//! Pure virtual openPort() function.
|
//! Pure virtual openPort() function.
|
||||||
virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0;
|
virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0;
|
||||||
|
|
||||||
@@ -153,6 +192,9 @@ class RtMidi
|
|||||||
//! Pure virtual closePort() function.
|
//! Pure virtual closePort() function.
|
||||||
virtual void closePort( void ) = 0;
|
virtual void closePort( void ) = 0;
|
||||||
|
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
|
||||||
//! Returns true if a port is open and false if not.
|
//! Returns true if a port is open and false if not.
|
||||||
/*!
|
/*!
|
||||||
Note that this only applies to connections made with the openPort()
|
Note that this only applies to connections made with the openPort()
|
||||||
@@ -168,10 +210,8 @@ class RtMidi
|
|||||||
virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
|
virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
RtMidi();
|
RtMidi();
|
||||||
virtual ~RtMidi();
|
virtual ~RtMidi();
|
||||||
|
|
||||||
MidiApi *rtapi_;
|
MidiApi *rtapi_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -188,8 +228,6 @@ class RtMidi
|
|||||||
time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also
|
time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also
|
||||||
possible to open a virtual input port to which other MIDI software
|
possible to open a virtual input port to which other MIDI software
|
||||||
clients can connect.
|
clients can connect.
|
||||||
|
|
||||||
by Gary P. Scavone, 2003-2019.
|
|
||||||
*/
|
*/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
@@ -207,7 +245,7 @@ class RtMidi
|
|||||||
//
|
//
|
||||||
// **************************************************************** //
|
// **************************************************************** //
|
||||||
|
|
||||||
class RtMidiIn : public RtMidi
|
class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -335,7 +373,6 @@ class RtMidiIn : public RtMidi
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
|
void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@@ -349,15 +386,12 @@ class RtMidiIn : public RtMidi
|
|||||||
connect to more than one MIDI device at the same time. With the
|
connect to more than one MIDI device at the same time. With the
|
||||||
OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a
|
OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a
|
||||||
virtual port to which other MIDI software clients can connect.
|
virtual port to which other MIDI software clients can connect.
|
||||||
|
|
||||||
by Gary P. Scavone, 2003-2019.
|
|
||||||
*/
|
*/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
class RtMidiOut : public RtMidi
|
class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor that allows an optional client name.
|
//! Default constructor that allows an optional client name.
|
||||||
/*!
|
/*!
|
||||||
An exception will be thrown if a MIDI system initialization error occurs.
|
An exception will be thrown if a MIDI system initialization error occurs.
|
||||||
@@ -458,7 +492,7 @@ class RtMidiOut : public RtMidi
|
|||||||
//
|
//
|
||||||
// **************************************************************** //
|
// **************************************************************** //
|
||||||
|
|
||||||
class MidiApi
|
class RTMIDI_DLL_PUBLIC MidiApi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -468,6 +502,8 @@ class MidiApi
|
|||||||
virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0;
|
virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0;
|
||||||
virtual void openVirtualPort( const std::string &portName ) = 0;
|
virtual void openVirtualPort( const std::string &portName ) = 0;
|
||||||
virtual void closePort( void ) = 0;
|
virtual void closePort( void ) = 0;
|
||||||
|
virtual void setClientName( const std::string &clientName ) = 0;
|
||||||
|
virtual void setPortName( const std::string &portName ) = 0;
|
||||||
|
|
||||||
virtual unsigned int getPortCount( void ) = 0;
|
virtual unsigned int getPortCount( void ) = 0;
|
||||||
virtual std::string getPortName( unsigned int portNumber ) = 0;
|
virtual std::string getPortName( unsigned int portNumber ) = 0;
|
||||||
@@ -489,7 +525,7 @@ protected:
|
|||||||
void *errorCallbackUserData_;
|
void *errorCallbackUserData_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MidiInApi : public MidiApi
|
class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -524,8 +560,7 @@ class MidiInApi : public MidiApi
|
|||||||
: front(0), back(0), ringSize(0), ring(0) {}
|
: front(0), back(0), ringSize(0), ring(0) {}
|
||||||
bool push( const MidiMessage& );
|
bool push( const MidiMessage& );
|
||||||
bool pop( std::vector<unsigned char>*, double* );
|
bool pop( std::vector<unsigned char>*, double* );
|
||||||
unsigned int size(unsigned int *back=0,
|
unsigned int size( unsigned int *back=0, unsigned int *front=0 );
|
||||||
unsigned int *front=0);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The RtMidiInData structure is used to pass private class data to
|
// The RtMidiInData structure is used to pass private class data to
|
||||||
@@ -544,16 +579,15 @@ class MidiInApi : public MidiApi
|
|||||||
|
|
||||||
// Default constructor.
|
// Default constructor.
|
||||||
RtMidiInData()
|
RtMidiInData()
|
||||||
: ignoreFlags(7), doInput(false), firstMessage(true),
|
: ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false),
|
||||||
apiData(0), usingCallback(false), userCallback(0), userData(0),
|
userCallback(0), userData(0), continueSysex(false) {}
|
||||||
continueSysex(false) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RtMidiInData inputData_;
|
RtMidiInData inputData_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MidiOutApi : public MidiApi
|
class RTMIDI_DLL_PUBLIC MidiOutApi : public MidiApi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -573,12 +607,12 @@ inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string &po
|
|||||||
inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
|
inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
|
||||||
inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
|
inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
|
||||||
inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
|
inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
|
||||||
inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
|
inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { static_cast<MidiInApi *>(rtapi_)->setCallback( callback, userData ); }
|
||||||
inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
|
inline void RtMidiIn :: cancelCallback( void ) { static_cast<MidiInApi *>(rtapi_)->cancelCallback(); }
|
||||||
inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
|
inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
|
||||||
inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
|
inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
|
||||||
inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
|
inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
|
||||||
inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
|
inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); }
|
||||||
inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
|
inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
|
||||||
|
|
||||||
inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
|
inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
|
||||||
@@ -588,207 +622,8 @@ inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
|
|||||||
inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
|
inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
|
||||||
inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
|
inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
|
||||||
inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
|
inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
|
||||||
inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( &message->at(0), message->size() ); }
|
inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( &message->at(0), message->size() ); }
|
||||||
inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { ((MidiOutApi *)rtapi_)->sendMessage( message, size ); }
|
inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( message, size ); }
|
||||||
inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
|
inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
|
||||||
|
|
||||||
// **************************************************************** //
|
|
||||||
//
|
|
||||||
// MidiInApi and MidiOutApi subclass prototypes.
|
|
||||||
//
|
|
||||||
// **************************************************************** //
|
|
||||||
|
|
||||||
#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
|
|
||||||
#define __RTMIDI_DUMMY__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__MACOSX_CORE__)
|
|
||||||
|
|
||||||
class MidiInCore: public MidiInApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiInCore( const std::string &clientName, unsigned int queueSizeLimit );
|
|
||||||
~MidiInCore( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
class MidiOutCore: public MidiOutApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiOutCore( const std::string &clientName );
|
|
||||||
~MidiOutCore( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
void sendMessage( const unsigned char *message, size_t size );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__UNIX_JACK__)
|
|
||||||
|
|
||||||
class MidiInJack: public MidiInApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiInJack( const std::string &clientName, unsigned int queueSizeLimit );
|
|
||||||
~MidiInJack( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string clientName;
|
|
||||||
|
|
||||||
void connect( void );
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
class MidiOutJack: public MidiOutApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiOutJack( const std::string &clientName );
|
|
||||||
~MidiOutJack( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
void sendMessage( const unsigned char *message, size_t size );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string clientName;
|
|
||||||
|
|
||||||
void connect( void );
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__LINUX_ALSA__)
|
|
||||||
|
|
||||||
class MidiInAlsa: public MidiInApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiInAlsa( const std::string &clientName, unsigned int queueSizeLimit );
|
|
||||||
~MidiInAlsa( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
class MidiOutAlsa: public MidiOutApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiOutAlsa( const std::string &clientName );
|
|
||||||
~MidiOutAlsa( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
void sendMessage( const unsigned char *message, size_t size );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__WINDOWS_MM__)
|
|
||||||
|
|
||||||
class MidiInWinMM: public MidiInApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiInWinMM( const std::string &clientName, unsigned int queueSizeLimit );
|
|
||||||
~MidiInWinMM( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
class MidiOutWinMM: public MidiOutApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiOutWinMM( const std::string &clientName );
|
|
||||||
~MidiOutWinMM( void );
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
|
|
||||||
void openPort( unsigned int portNumber, const std::string &portName );
|
|
||||||
void openVirtualPort( const std::string &portName );
|
|
||||||
void closePort( void );
|
|
||||||
unsigned int getPortCount( void );
|
|
||||||
std::string getPortName( unsigned int portNumber );
|
|
||||||
void sendMessage( const unsigned char *message, size_t size );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& clientName );
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__RTMIDI_DUMMY__)
|
|
||||||
|
|
||||||
class MidiInDummy: public MidiInApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiInDummy( const std::string &/*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
|
|
||||||
void openPort( unsigned int /*portNumber*/, const std::string &/*portName*/ ) {}
|
|
||||||
void openVirtualPort( const std::string &/*portName*/ ) {}
|
|
||||||
void closePort( void ) {}
|
|
||||||
unsigned int getPortCount( void ) { return 0; }
|
|
||||||
std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& /*clientName*/ ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MidiOutDummy: public MidiOutApi
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MidiOutDummy( const std::string &/*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
|
|
||||||
RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
|
|
||||||
void openPort( unsigned int /*portNumber*/, const std::string &/*portName*/ ) {}
|
|
||||||
void openVirtualPort( const std::string &/*portName*/ ) {}
|
|
||||||
void closePort( void ) {}
|
|
||||||
unsigned int getPortCount( void ) { return 0; }
|
|
||||||
std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
|
|
||||||
void sendMessage( const unsigned char * /*message*/, size_t /*size*/ ) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void initialize( const std::string& /*clientName*/ ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK)
|
# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK)
|
||||||
# by Gary P. Scavone, CCRMA, Stanford University, 1995--2017.
|
# by Gary P. Scavone, CCRMA, CAML, Stanford & McGill Universities, 1995--2019.
|
||||||
|
|
||||||
# Set initial control values
|
# Set initial control values
|
||||||
set pitch 64.0
|
set pitch 64.0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The Synthesis ToolKit in C++ (STK)
|
The Synthesis ToolKit in C++ (STK)
|
||||||
|
|
||||||
By Perry R. Cook and Gary P. Scavone, 1995--2017.
|
By Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
|
|
||||||
EFFECTS PROJECT:
|
EFFECTS PROJECT:
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
Stanford, bearing the names of Karplus and/or
|
Stanford, bearing the names of Karplus and/or
|
||||||
Strong.
|
Strong.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace stk {
|
|||||||
Stanford, bearing the names of Karplus and/or
|
Stanford, bearing the names of Karplus and/or
|
||||||
Strong.
|
Strong.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
sample rates. You can specify the maximum polyphony (maximum
|
sample rates. You can specify the maximum polyphony (maximum
|
||||||
number of simultaneous voices) in Tabla.h.
|
number of simultaneous voices) in Tabla.h.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace stk {
|
|||||||
sample rates. You can specify the maximum polyphony (maximum
|
sample rates. You can specify the maximum polyphony (maximum
|
||||||
number of simultaneous voices) in Tabla.h.
|
number of simultaneous voices) in Tabla.h.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
sample rates. You can specify the maximum polyphony (maximum
|
sample rates. You can specify the maximum polyphony (maximum
|
||||||
number of simultaneous voices) in VoicDrum.h.
|
number of simultaneous voices) in VoicDrum.h.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace stk {
|
|||||||
sample rates. You can specify the maximum polyphony (maximum
|
sample rates. You can specify the maximum polyphony (maximum
|
||||||
number of simultaneous voices) in VoicDrum.h.
|
number of simultaneous voices) in VoicDrum.h.
|
||||||
|
|
||||||
by Perry R. Cook and Gary P. Scavone, 1995--2017.
|
by Perry R. Cook and Gary P. Scavone, 1995--2019.
|
||||||
*/
|
*/
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
|||||||
985
src/RtAudio.cpp
985
src/RtAudio.cpp
File diff suppressed because it is too large
Load Diff
637
src/RtMidi.cpp
637
src/RtMidi.cpp
@@ -5,7 +5,8 @@
|
|||||||
This class implements some common functionality for the realtime
|
This class implements some common functionality for the realtime
|
||||||
MIDI input/output subclasses RtMidiIn and RtMidiOut.
|
MIDI input/output subclasses RtMidiIn and RtMidiOut.
|
||||||
|
|
||||||
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
|
RtMidi GitHub site: https://github.com/thestk/rtmidi
|
||||||
|
RtMidi WWW site: http://www.music.mcgill.ca/~gary/rtmidi/
|
||||||
|
|
||||||
RtMidi: realtime MIDI i/o C++ classes
|
RtMidi: realtime MIDI i/o C++ classes
|
||||||
Copyright (c) 2003-2019 Gary P. Scavone
|
Copyright (c) 2003-2019 Gary P. Scavone
|
||||||
@@ -47,8 +48,227 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Default for Windows is to add an identifier to the port names; this
|
// Default for Windows is to add an identifier to the port names; this
|
||||||
// flag can be undefined to disable this behaviour.
|
// flag can be defined (e.g. in your project file) to disable this behaviour.
|
||||||
#define RTMIDI_ENSURE_UNIQUE_PORTNAMES
|
//#define RTMIDI_DO_NOT_ENSURE_UNIQUE_PORTNAMES
|
||||||
|
|
||||||
|
// **************************************************************** //
|
||||||
|
//
|
||||||
|
// MidiInApi and MidiOutApi subclass prototypes.
|
||||||
|
//
|
||||||
|
// **************************************************************** //
|
||||||
|
|
||||||
|
#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
|
||||||
|
#define __RTMIDI_DUMMY__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MACOSX_CORE__)
|
||||||
|
|
||||||
|
class MidiInCore: public MidiInApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiInCore( const std::string &clientName, unsigned int queueSizeLimit );
|
||||||
|
~MidiInCore( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
class MidiOutCore: public MidiOutApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiOutCore( const std::string &clientName );
|
||||||
|
~MidiOutCore( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
void sendMessage( const unsigned char *message, size_t size );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__UNIX_JACK__)
|
||||||
|
|
||||||
|
class MidiInJack: public MidiInApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiInJack( const std::string &clientName, unsigned int queueSizeLimit );
|
||||||
|
~MidiInJack( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName);
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string clientName;
|
||||||
|
|
||||||
|
void connect( void );
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
class MidiOutJack: public MidiOutApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiOutJack( const std::string &clientName );
|
||||||
|
~MidiOutJack( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName);
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
void sendMessage( const unsigned char *message, size_t size );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string clientName;
|
||||||
|
|
||||||
|
void connect( void );
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__LINUX_ALSA__)
|
||||||
|
|
||||||
|
class MidiInAlsa: public MidiInApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiInAlsa( const std::string &clientName, unsigned int queueSizeLimit );
|
||||||
|
~MidiInAlsa( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName);
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
class MidiOutAlsa: public MidiOutApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiOutAlsa( const std::string &clientName );
|
||||||
|
~MidiOutAlsa( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
void sendMessage( const unsigned char *message, size_t size );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__WINDOWS_MM__)
|
||||||
|
|
||||||
|
class MidiInWinMM: public MidiInApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiInWinMM( const std::string &clientName, unsigned int queueSizeLimit );
|
||||||
|
~MidiInWinMM( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
class MidiOutWinMM: public MidiOutApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiOutWinMM( const std::string &clientName );
|
||||||
|
~MidiOutWinMM( void );
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
|
||||||
|
void openPort( unsigned int portNumber, const std::string &portName );
|
||||||
|
void openVirtualPort( const std::string &portName );
|
||||||
|
void closePort( void );
|
||||||
|
void setClientName( const std::string &clientName );
|
||||||
|
void setPortName( const std::string &portName );
|
||||||
|
unsigned int getPortCount( void );
|
||||||
|
std::string getPortName( unsigned int portNumber );
|
||||||
|
void sendMessage( const unsigned char *message, size_t size );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& clientName );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__RTMIDI_DUMMY__)
|
||||||
|
|
||||||
|
class MidiInDummy: public MidiInApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiInDummy( const std::string &/*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
|
||||||
|
void openPort( unsigned int /*portNumber*/, const std::string &/*portName*/ ) {}
|
||||||
|
void openVirtualPort( const std::string &/*portName*/ ) {}
|
||||||
|
void closePort( void ) {}
|
||||||
|
void setClientName( const std::string &/*clientName*/ ) {};
|
||||||
|
void setPortName( const std::string &/*portName*/ ) {};
|
||||||
|
unsigned int getPortCount( void ) { return 0; }
|
||||||
|
std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& /*clientName*/ ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MidiOutDummy: public MidiOutApi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiOutDummy( const std::string &/*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
|
||||||
|
RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
|
||||||
|
void openPort( unsigned int /*portNumber*/, const std::string &/*portName*/ ) {}
|
||||||
|
void openVirtualPort( const std::string &/*portName*/ ) {}
|
||||||
|
void closePort( void ) {}
|
||||||
|
void setClientName( const std::string &/*clientName*/ ) {};
|
||||||
|
void setPortName( const std::string &/*portName*/ ) {};
|
||||||
|
unsigned int getPortCount( void ) { return 0; }
|
||||||
|
std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
|
||||||
|
void sendMessage( const unsigned char * /*message*/, size_t /*size*/ ) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const std::string& /*clientName*/ ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
// RtMidi Definitions
|
// RtMidi Definitions
|
||||||
@@ -70,29 +290,92 @@ std::string RtMidi :: getVersion( void ) throw()
|
|||||||
return std::string( RTMIDI_VERSION );
|
return std::string( RTMIDI_VERSION );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtMidi :: getCompiledApi( std::vector<RtMidi::Api> &apis ) throw()
|
// Define API names and display names.
|
||||||
{
|
// Must be in same order as API enum.
|
||||||
apis.clear();
|
extern "C" {
|
||||||
|
const char* rtmidi_api_names[][2] = {
|
||||||
|
{ "unspecified" , "Unknown" },
|
||||||
|
{ "core" , "CoreMidi" },
|
||||||
|
{ "alsa" , "ALSA" },
|
||||||
|
{ "jack" , "Jack" },
|
||||||
|
{ "winmm" , "Windows MultiMedia" },
|
||||||
|
{ "dummy" , "Dummy" },
|
||||||
|
};
|
||||||
|
const unsigned int rtmidi_num_api_names =
|
||||||
|
sizeof(rtmidi_api_names)/sizeof(rtmidi_api_names[0]);
|
||||||
|
|
||||||
// The order here will control the order of RtMidi's API search in
|
// The order here will control the order of RtMidi's API search in
|
||||||
// the constructor.
|
// the constructor.
|
||||||
|
extern "C" const RtMidi::Api rtmidi_compiled_apis[] = {
|
||||||
#if defined(__MACOSX_CORE__)
|
#if defined(__MACOSX_CORE__)
|
||||||
apis.push_back( MACOSX_CORE );
|
RtMidi::MACOSX_CORE,
|
||||||
#endif
|
#endif
|
||||||
#if defined(__LINUX_ALSA__)
|
#if defined(__LINUX_ALSA__)
|
||||||
apis.push_back( LINUX_ALSA );
|
RtMidi::LINUX_ALSA,
|
||||||
#endif
|
#endif
|
||||||
#if defined(__UNIX_JACK__)
|
#if defined(__UNIX_JACK__)
|
||||||
apis.push_back( UNIX_JACK );
|
RtMidi::UNIX_JACK,
|
||||||
#endif
|
#endif
|
||||||
#if defined(__WINDOWS_MM__)
|
#if defined(__WINDOWS_MM__)
|
||||||
apis.push_back( WINDOWS_MM );
|
RtMidi::WINDOWS_MM,
|
||||||
#endif
|
#endif
|
||||||
#if defined(__RTMIDI_DUMMY__)
|
#if defined(__RTMIDI_DUMMY__)
|
||||||
apis.push_back( RTMIDI_DUMMY );
|
RtMidi::RTMIDI_DUMMY,
|
||||||
#endif
|
#endif
|
||||||
|
RtMidi::UNSPECIFIED,
|
||||||
|
};
|
||||||
|
extern "C" const unsigned int rtmidi_num_compiled_apis =
|
||||||
|
sizeof(rtmidi_compiled_apis)/sizeof(rtmidi_compiled_apis[0])-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a compile-time check that rtmidi_num_api_names == RtMidi::NUM_APIS.
|
||||||
|
// If the build breaks here, check that they match.
|
||||||
|
template<bool b> class StaticAssert { private: StaticAssert() {} };
|
||||||
|
template<> class StaticAssert<true>{ public: StaticAssert() {} };
|
||||||
|
class StaticAssertions { StaticAssertions() {
|
||||||
|
StaticAssert<rtmidi_num_api_names == RtMidi::NUM_APIS>();
|
||||||
|
}};
|
||||||
|
|
||||||
|
void RtMidi :: getCompiledApi( std::vector<RtMidi::Api> &apis ) throw()
|
||||||
|
{
|
||||||
|
apis = std::vector<RtMidi::Api>(rtmidi_compiled_apis,
|
||||||
|
rtmidi_compiled_apis + rtmidi_num_compiled_apis);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RtMidi :: getApiName( RtMidi::Api api )
|
||||||
|
{
|
||||||
|
if (api < 0 || api >= RtMidi::NUM_APIS)
|
||||||
|
return "";
|
||||||
|
return rtmidi_api_names[api][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RtMidi :: getApiDisplayName( RtMidi::Api api )
|
||||||
|
{
|
||||||
|
if (api < 0 || api >= RtMidi::NUM_APIS)
|
||||||
|
return "Unknown";
|
||||||
|
return rtmidi_api_names[api][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
RtMidi::Api RtMidi :: getCompiledApiByName( const std::string &name )
|
||||||
|
{
|
||||||
|
unsigned int i=0;
|
||||||
|
for (i = 0; i < rtmidi_num_compiled_apis; ++i)
|
||||||
|
if (name == rtmidi_api_names[rtmidi_compiled_apis[i]][0])
|
||||||
|
return rtmidi_compiled_apis[i];
|
||||||
|
return RtMidi::UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtMidi :: setClientName( const std::string &clientName )
|
||||||
|
{
|
||||||
|
rtapi_->setClientName( clientName );
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtMidi :: setPortName( const std::string &portName )
|
||||||
|
{
|
||||||
|
rtapi_->setPortName( portName );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
// RtMidiIn Definitions
|
// RtMidiIn Definitions
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
@@ -124,7 +407,7 @@ void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string &clientName, un
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit )
|
RTMIDI_DLL_PUBLIC RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit )
|
||||||
: RtMidi()
|
: RtMidi()
|
||||||
{
|
{
|
||||||
if ( api != UNSPECIFIED ) {
|
if ( api != UNSPECIFIED ) {
|
||||||
@@ -192,7 +475,7 @@ void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string &clientName )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string &clientName)
|
RTMIDI_DLL_PUBLIC RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string &clientName)
|
||||||
{
|
{
|
||||||
if ( api != UNSPECIFIED ) {
|
if ( api != UNSPECIFIED ) {
|
||||||
// Attempt to open the specified API.
|
// Attempt to open the specified API.
|
||||||
@@ -479,10 +762,12 @@ static void midiInputCallback( const MIDIPacketList *list, void *procRef, void *
|
|||||||
// function.
|
// function.
|
||||||
|
|
||||||
nBytes = packet->length;
|
nBytes = packet->length;
|
||||||
if ( nBytes == 0 ) continue;
|
if ( nBytes == 0 ) {
|
||||||
|
packet = MIDIPacketNext( packet );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate time stamp.
|
// Calculate time stamp.
|
||||||
|
|
||||||
if ( data->firstMessage ) {
|
if ( data->firstMessage ) {
|
||||||
message.timeStamp = 0.0;
|
message.timeStamp = 0.0;
|
||||||
data->firstMessage = false;
|
data->firstMessage = false;
|
||||||
@@ -497,11 +782,10 @@ static void midiInputCallback( const MIDIPacketList *list, void *procRef, void *
|
|||||||
if ( !continueSysex )
|
if ( !continueSysex )
|
||||||
message.timeStamp = time * 0.000000001;
|
message.timeStamp = time * 0.000000001;
|
||||||
}
|
}
|
||||||
apiData->lastTime = packet->timeStamp;
|
|
||||||
if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages
|
// Track whether any non-filtered messages were found in this
|
||||||
apiData->lastTime = AudioGetCurrentHostTime();
|
// packet for timestamp calculation
|
||||||
}
|
bool foundNonFiltered = false;
|
||||||
//std::cout << "TimeStamp = " << packet->timeStamp << std::endl;
|
|
||||||
|
|
||||||
iByte = 0;
|
iByte = 0;
|
||||||
if ( continueSysex ) {
|
if ( continueSysex ) {
|
||||||
@@ -570,6 +854,7 @@ static void midiInputCallback( const MIDIPacketList *list, void *procRef, void *
|
|||||||
|
|
||||||
// Copy the MIDI data to our vector.
|
// Copy the MIDI data to our vector.
|
||||||
if ( size ) {
|
if ( size ) {
|
||||||
|
foundNonFiltered = true;
|
||||||
message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] );
|
message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] );
|
||||||
if ( !continueSysex ) {
|
if ( !continueSysex ) {
|
||||||
// If not a continuing sysex message, invoke the user callback function or queue the message.
|
// If not a continuing sysex message, invoke the user callback function or queue the message.
|
||||||
@@ -588,19 +873,29 @@ static void midiInputCallback( const MIDIPacketList *list, void *procRef, void *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the time of the last non-filtered message
|
||||||
|
if ( foundNonFiltered ) {
|
||||||
|
apiData->lastTime = packet->timeStamp;
|
||||||
|
if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages
|
||||||
|
apiData->lastTime = AudioGetCurrentHostTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packet = MIDIPacketNext(packet);
|
packet = MIDIPacketNext(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInCore :: MidiInCore( const std::string &clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
|
MidiInCore :: MidiInCore( const std::string &clientName, unsigned int queueSizeLimit )
|
||||||
|
: MidiInApi( queueSizeLimit )
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiInCore::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInCore :: ~MidiInCore( void )
|
MidiInCore :: ~MidiInCore( void )
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiInCore::closePort();
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||||
@@ -658,9 +953,12 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string &portNam
|
|||||||
|
|
||||||
MIDIPortRef port;
|
MIDIPortRef port;
|
||||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||||
|
CFStringRef portNameRef = CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII );
|
||||||
OSStatus result = MIDIInputPortCreate( data->client,
|
OSStatus result = MIDIInputPortCreate( data->client,
|
||||||
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
|
portNameRef,
|
||||||
midiInputCallback, (void *)&inputData_, &port );
|
midiInputCallback, (void *)&inputData_, &port );
|
||||||
|
CFRelease( portNameRef );
|
||||||
|
|
||||||
if ( result != noErr ) {
|
if ( result != noErr ) {
|
||||||
MIDIClientDispose( data->client );
|
MIDIClientDispose( data->client );
|
||||||
errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port.";
|
errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port.";
|
||||||
@@ -700,9 +998,12 @@ void MidiInCore :: openVirtualPort( const std::string &portName )
|
|||||||
|
|
||||||
// Create a virtual MIDI input destination.
|
// Create a virtual MIDI input destination.
|
||||||
MIDIEndpointRef endpoint;
|
MIDIEndpointRef endpoint;
|
||||||
|
CFStringRef portNameRef = CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII );
|
||||||
OSStatus result = MIDIDestinationCreate( data->client,
|
OSStatus result = MIDIDestinationCreate( data->client,
|
||||||
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
|
portNameRef,
|
||||||
midiInputCallback, (void *)&inputData_, &endpoint );
|
midiInputCallback, (void *)&inputData_, &endpoint );
|
||||||
|
CFRelease( portNameRef );
|
||||||
|
|
||||||
if ( result != noErr ) {
|
if ( result != noErr ) {
|
||||||
errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination.";
|
errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination.";
|
||||||
error( RtMidiError::DRIVER_ERROR, errorString_ );
|
error( RtMidiError::DRIVER_ERROR, errorString_ );
|
||||||
@@ -730,6 +1031,22 @@ void MidiInCore :: closePort( void )
|
|||||||
connected_ = false;
|
connected_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiInCore :: setClientName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiInCore::setClientName: this function is not implemented for the MACOSX_CORE API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiInCore :: setPortName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiInCore::setPortName: this function is not implemented for the MACOSX_CORE API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int MidiInCore :: getPortCount()
|
unsigned int MidiInCore :: getPortCount()
|
||||||
{
|
{
|
||||||
CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
|
CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
|
||||||
@@ -798,6 +1115,7 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
|
|||||||
// prepend the device name to the entity name
|
// prepend the device name to the entity name
|
||||||
if ( CFStringGetLength( result ) > 0 )
|
if ( CFStringGetLength( result ) > 0 )
|
||||||
CFStringInsert( result, 0, CFSTR(" ") );
|
CFStringInsert( result, 0, CFSTR(" ") );
|
||||||
|
|
||||||
CFStringInsert( result, 0, str );
|
CFStringInsert( result, 0, str );
|
||||||
}
|
}
|
||||||
CFRelease( str );
|
CFRelease( str );
|
||||||
@@ -844,7 +1162,8 @@ static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint )
|
|||||||
if ( str != NULL ) {
|
if ( str != NULL ) {
|
||||||
if ( anyStrings )
|
if ( anyStrings )
|
||||||
CFStringAppend( result, CFSTR(", ") );
|
CFStringAppend( result, CFSTR(", ") );
|
||||||
else anyStrings = true;
|
else
|
||||||
|
anyStrings = true;
|
||||||
CFStringAppend( result, str );
|
CFStringAppend( result, str );
|
||||||
CFRelease( str );
|
CFRelease( str );
|
||||||
}
|
}
|
||||||
@@ -891,15 +1210,16 @@ std::string MidiInCore :: getPortName( unsigned int portNumber )
|
|||||||
// Class Definitions: MidiOutCore
|
// Class Definitions: MidiOutCore
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
|
|
||||||
MidiOutCore :: MidiOutCore( const std::string &clientName ) : MidiOutApi()
|
MidiOutCore :: MidiOutCore( const std::string &clientName )
|
||||||
|
: MidiOutApi()
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiOutCore::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiOutCore :: ~MidiOutCore( void )
|
MidiOutCore :: ~MidiOutCore( void )
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiOutCore::closePort();
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||||
@@ -987,9 +1307,7 @@ void MidiOutCore :: openPort( unsigned int portNumber, const std::string &portNa
|
|||||||
MIDIPortRef port;
|
MIDIPortRef port;
|
||||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||||
CFStringRef portNameRef = CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII );
|
CFStringRef portNameRef = CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII );
|
||||||
OSStatus result = MIDIOutputPortCreate( data->client,
|
OSStatus result = MIDIOutputPortCreate( data->client, portNameRef, &port );
|
||||||
portNameRef,
|
|
||||||
&port );
|
|
||||||
CFRelease( portNameRef );
|
CFRelease( portNameRef );
|
||||||
if ( result != noErr ) {
|
if ( result != noErr ) {
|
||||||
MIDIClientDispose( data->client );
|
MIDIClientDispose( data->client );
|
||||||
@@ -1031,6 +1349,22 @@ void MidiOutCore :: closePort( void )
|
|||||||
connected_ = false;
|
connected_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiOutCore :: setClientName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiOutCore::setClientName: this function is not implemented for the MACOSX_CORE API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiOutCore :: setPortName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiOutCore::setPortName: this function is not implemented for the MACOSX_CORE API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void MidiOutCore :: openVirtualPort( const std::string &portName )
|
void MidiOutCore :: openVirtualPort( const std::string &portName )
|
||||||
{
|
{
|
||||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||||
@@ -1043,9 +1377,10 @@ void MidiOutCore :: openVirtualPort( const std::string &portName )
|
|||||||
|
|
||||||
// Create a virtual MIDI output source.
|
// Create a virtual MIDI output source.
|
||||||
MIDIEndpointRef endpoint;
|
MIDIEndpointRef endpoint;
|
||||||
OSStatus result = MIDISourceCreate( data->client,
|
CFStringRef portNameRef = CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII );
|
||||||
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
|
OSStatus result = MIDISourceCreate( data->client, portNameRef, &endpoint );
|
||||||
&endpoint );
|
CFRelease( portNameRef );
|
||||||
|
|
||||||
if ( result != noErr ) {
|
if ( result != noErr ) {
|
||||||
errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source.";
|
errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source.";
|
||||||
error( RtMidiError::DRIVER_ERROR, errorString_ );
|
error( RtMidiError::DRIVER_ERROR, errorString_ );
|
||||||
@@ -1284,6 +1619,8 @@ static void *alsaMidiHandler( void *ptr )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
doDecode = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
doDecode = true;
|
doDecode = true;
|
||||||
@@ -1320,21 +1657,25 @@ static void *alsaMidiHandler( void *ptr )
|
|||||||
// https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
|
// https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
|
||||||
|
|
||||||
// Perform the carry for the later subtraction by updating y.
|
// Perform the carry for the later subtraction by updating y.
|
||||||
|
// Temp var y is timespec because computation requires signed types,
|
||||||
|
// while snd_seq_real_time_t has unsigned types.
|
||||||
snd_seq_real_time_t &x( ev->time.time );
|
snd_seq_real_time_t &x( ev->time.time );
|
||||||
snd_seq_real_time_t &y(apiData->lastTime);
|
struct timespec y;
|
||||||
|
y.tv_nsec = apiData->lastTime.tv_nsec;
|
||||||
|
y.tv_sec = apiData->lastTime.tv_sec;
|
||||||
if ( x.tv_nsec < y.tv_nsec ) {
|
if ( x.tv_nsec < y.tv_nsec ) {
|
||||||
int nsec = (y.tv_nsec - x.tv_nsec) / 1000000000 + 1;
|
int nsec = (y.tv_nsec - (int)x.tv_nsec) / 1000000000 + 1;
|
||||||
y.tv_nsec -= 1000000000 * nsec;
|
y.tv_nsec -= 1000000000 * nsec;
|
||||||
y.tv_sec += nsec;
|
y.tv_sec += nsec;
|
||||||
}
|
}
|
||||||
if ( x.tv_nsec - y.tv_nsec > 1000000000 ) {
|
if ( x.tv_nsec - y.tv_nsec > 1000000000 ) {
|
||||||
int nsec = (x.tv_nsec - y.tv_nsec) / 1000000000;
|
int nsec = ((int)x.tv_nsec - y.tv_nsec) / 1000000000;
|
||||||
y.tv_nsec += 1000000000 * nsec;
|
y.tv_nsec += 1000000000 * nsec;
|
||||||
y.tv_sec -= nsec;
|
y.tv_sec -= nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the time difference.
|
// Compute the time difference.
|
||||||
time = x.tv_sec - y.tv_sec + (x.tv_nsec - y.tv_nsec)*1e-9;
|
time = (int)x.tv_sec - y.tv_sec + ((int)x.tv_nsec - y.tv_nsec)*1e-9;
|
||||||
|
|
||||||
apiData->lastTime = ev->time.time;
|
apiData->lastTime = ev->time.time;
|
||||||
|
|
||||||
@@ -1372,15 +1713,16 @@ static void *alsaMidiHandler( void *ptr )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInAlsa :: MidiInAlsa( const std::string &clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
|
MidiInAlsa :: MidiInAlsa( const std::string &clientName, unsigned int queueSizeLimit )
|
||||||
|
: MidiInApi( queueSizeLimit )
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiInAlsa::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInAlsa :: ~MidiInAlsa()
|
MidiInAlsa :: ~MidiInAlsa()
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiInAlsa::closePort();
|
||||||
|
|
||||||
// Shutdown the input thread.
|
// Shutdown the input thread.
|
||||||
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||||
@@ -1719,6 +2061,24 @@ void MidiInAlsa :: closePort( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiInAlsa :: setClientName( const std::string &clientName )
|
||||||
|
{
|
||||||
|
|
||||||
|
AlsaMidiData *data = static_cast<AlsaMidiData *> ( apiData_ );
|
||||||
|
snd_seq_set_client_name( data->seq, clientName.c_str() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiInAlsa :: setPortName( const std::string &portName )
|
||||||
|
{
|
||||||
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||||
|
snd_seq_port_info_t *pinfo;
|
||||||
|
snd_seq_port_info_alloca( &pinfo );
|
||||||
|
snd_seq_get_port_info( data->seq, data->vport, pinfo );
|
||||||
|
snd_seq_port_info_set_name( pinfo, portName.c_str() );
|
||||||
|
snd_seq_set_port_info( data->seq, data->vport, pinfo );
|
||||||
|
}
|
||||||
|
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
// API: LINUX ALSA
|
// API: LINUX ALSA
|
||||||
// Class Definitions: MidiOutAlsa
|
// Class Definitions: MidiOutAlsa
|
||||||
@@ -1726,13 +2086,13 @@ void MidiInAlsa :: closePort( void )
|
|||||||
|
|
||||||
MidiOutAlsa :: MidiOutAlsa( const std::string &clientName ) : MidiOutApi()
|
MidiOutAlsa :: MidiOutAlsa( const std::string &clientName ) : MidiOutApi()
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiOutAlsa::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiOutAlsa :: ~MidiOutAlsa()
|
MidiOutAlsa :: ~MidiOutAlsa()
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiOutAlsa::closePort();
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||||
@@ -1898,6 +2258,24 @@ void MidiOutAlsa :: closePort( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiOutAlsa :: setClientName( const std::string &clientName )
|
||||||
|
{
|
||||||
|
|
||||||
|
AlsaMidiData *data = static_cast<AlsaMidiData *> ( apiData_ );
|
||||||
|
snd_seq_set_client_name( data->seq, clientName.c_str() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiOutAlsa :: setPortName( const std::string &portName )
|
||||||
|
{
|
||||||
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||||
|
snd_seq_port_info_t *pinfo;
|
||||||
|
snd_seq_port_info_alloca( &pinfo );
|
||||||
|
snd_seq_get_port_info( data->seq, data->vport, pinfo );
|
||||||
|
snd_seq_port_info_set_name( pinfo, portName.c_str() );
|
||||||
|
snd_seq_set_port_info( data->seq, data->vport, pinfo );
|
||||||
|
}
|
||||||
|
|
||||||
void MidiOutAlsa :: openVirtualPort( const std::string &portName )
|
void MidiOutAlsa :: openVirtualPort( const std::string &portName )
|
||||||
{
|
{
|
||||||
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||||
@@ -2045,7 +2423,6 @@ static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/,
|
|||||||
data->firstMessage = false;
|
data->firstMessage = false;
|
||||||
}
|
}
|
||||||
else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001;
|
else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001;
|
||||||
apiData->lastTime = timestamp;
|
|
||||||
|
|
||||||
if ( inputStatus == MIM_DATA ) { // Channel or system message
|
if ( inputStatus == MIM_DATA ) { // Channel or system message
|
||||||
|
|
||||||
@@ -2106,6 +2483,9 @@ static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/,
|
|||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the time of the last non-filtered message
|
||||||
|
apiData->lastTime = timestamp;
|
||||||
|
|
||||||
if ( data->usingCallback ) {
|
if ( data->usingCallback ) {
|
||||||
RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
|
RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
|
||||||
callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData );
|
callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData );
|
||||||
@@ -2120,15 +2500,16 @@ static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/,
|
|||||||
apiData->message.bytes.clear();
|
apiData->message.bytes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInWinMM :: MidiInWinMM( const std::string &clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
|
MidiInWinMM :: MidiInWinMM( const std::string &clientName, unsigned int queueSizeLimit )
|
||||||
|
: MidiInApi( queueSizeLimit )
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiInWinMM::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInWinMM :: ~MidiInWinMM()
|
MidiInWinMM :: ~MidiInWinMM()
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiInWinMM::closePort();
|
||||||
|
|
||||||
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
||||||
DeleteCriticalSection( &(data->_mutex) );
|
DeleteCriticalSection( &(data->_mutex) );
|
||||||
@@ -2269,6 +2650,22 @@ void MidiInWinMM :: closePort( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiInWinMM :: setClientName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiInWinMM::setClientName: this function is not implemented for the WINDOWS_MM API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiInWinMM :: setPortName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiInWinMM::setPortName: this function is not implemented for the WINDOWS_MM API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int MidiInWinMM :: getPortCount()
|
unsigned int MidiInWinMM :: getPortCount()
|
||||||
{
|
{
|
||||||
return midiInGetNumDevs();
|
return midiInGetNumDevs();
|
||||||
@@ -2293,7 +2690,7 @@ std::string MidiInWinMM :: getPortName( unsigned int portNumber )
|
|||||||
// Next lines added to add the portNumber to the name so that
|
// Next lines added to add the portNumber to the name so that
|
||||||
// the device's names are sure to be listed with individual names
|
// the device's names are sure to be listed with individual names
|
||||||
// even when they have the same brand name
|
// even when they have the same brand name
|
||||||
#ifdef RTMIDI_ENSURE_UNIQUE_PORTNAMES
|
#ifndef RTMIDI_DO_NOT_ENSURE_UNIQUE_PORTNAMES
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << " ";
|
os << " ";
|
||||||
os << portNumber;
|
os << portNumber;
|
||||||
@@ -2310,13 +2707,13 @@ std::string MidiInWinMM :: getPortName( unsigned int portNumber )
|
|||||||
|
|
||||||
MidiOutWinMM :: MidiOutWinMM( const std::string &clientName ) : MidiOutApi()
|
MidiOutWinMM :: MidiOutWinMM( const std::string &clientName ) : MidiOutApi()
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiOutWinMM::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiOutWinMM :: ~MidiOutWinMM()
|
MidiOutWinMM :: ~MidiOutWinMM()
|
||||||
{
|
{
|
||||||
// Close a connection if it exists.
|
// Close a connection if it exists.
|
||||||
closePort();
|
MidiOutWinMM::closePort();
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
||||||
@@ -2363,7 +2760,7 @@ std::string MidiOutWinMM :: getPortName( unsigned int portNumber )
|
|||||||
// the device's names are sure to be listed with individual names
|
// the device's names are sure to be listed with individual names
|
||||||
// even when they have the same brand name
|
// even when they have the same brand name
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
#ifdef RTMIDI_ENSURE_UNIQUE_PORTNAMES
|
#ifndef RTMIDI_DO_NOT_ENSURE_UNIQUE_PORTNAMES
|
||||||
os << " ";
|
os << " ";
|
||||||
os << portNumber;
|
os << portNumber;
|
||||||
stringName += os.str();
|
stringName += os.str();
|
||||||
@@ -2421,6 +2818,22 @@ void MidiOutWinMM :: closePort( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiOutWinMM :: setClientName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiOutWinMM::setClientName: this function is not implemented for the WINDOWS_MM API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiOutWinMM :: setPortName ( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiOutWinMM::setPortName: this function is not implemented for the WINDOWS_MM API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void MidiOutWinMM :: openVirtualPort( const std::string &/*portName*/ )
|
void MidiOutWinMM :: openVirtualPort( const std::string &/*portName*/ )
|
||||||
{
|
{
|
||||||
// This function cannot be implemented for the Windows MM MIDI API.
|
// This function cannot be implemented for the Windows MM MIDI API.
|
||||||
@@ -2556,29 +2969,64 @@ static int jackProcessIn( jack_nframes_t nframes, void *arg )
|
|||||||
|
|
||||||
// Is port created?
|
// Is port created?
|
||||||
if ( jData->port == NULL ) return 0;
|
if ( jData->port == NULL ) return 0;
|
||||||
|
|
||||||
void *buff = jack_port_get_buffer( jData->port, nframes );
|
void *buff = jack_port_get_buffer( jData->port, nframes );
|
||||||
|
bool& continueSysex = rtData->continueSysex;
|
||||||
|
unsigned char& ignoreFlags = rtData->ignoreFlags;
|
||||||
|
|
||||||
// We have midi events in buffer
|
// We have midi events in buffer
|
||||||
int evCount = jack_midi_get_event_count( buff );
|
int evCount = jack_midi_get_event_count( buff );
|
||||||
for (int j = 0; j < evCount; j++) {
|
for (int j = 0; j < evCount; j++) {
|
||||||
MidiInApi::MidiMessage message;
|
MidiInApi::MidiMessage& message = rtData->message;
|
||||||
message.bytes.clear();
|
|
||||||
|
|
||||||
jack_midi_event_get( &event, buff, j );
|
jack_midi_event_get( &event, buff, j );
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < event.size; i++ )
|
|
||||||
message.bytes.push_back( event.buffer[i] );
|
|
||||||
|
|
||||||
// Compute the delta time.
|
// Compute the delta time.
|
||||||
time = jack_get_time();
|
time = jack_get_time();
|
||||||
if ( rtData->firstMessage == true )
|
if ( rtData->firstMessage == true ) {
|
||||||
|
message.timeStamp = 0.0;
|
||||||
rtData->firstMessage = false;
|
rtData->firstMessage = false;
|
||||||
else
|
} else
|
||||||
message.timeStamp = ( time - jData->lastTime ) * 0.000001;
|
message.timeStamp = ( time - jData->lastTime ) * 0.000001;
|
||||||
|
|
||||||
jData->lastTime = time;
|
jData->lastTime = time;
|
||||||
|
|
||||||
if ( !rtData->continueSysex ) {
|
if ( !continueSysex )
|
||||||
|
message.bytes.clear();
|
||||||
|
|
||||||
|
if ( !( ( continueSysex || event.buffer[0] == 0xF0 ) && ( ignoreFlags & 0x01 ) ) ) {
|
||||||
|
// Unless this is a (possibly continued) SysEx message and we're ignoring SysEx,
|
||||||
|
// copy the event buffer into the MIDI message struct.
|
||||||
|
for ( unsigned int i = 0; i < event.size; i++ )
|
||||||
|
message.bytes.push_back( event.buffer[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( event.buffer[0] ) {
|
||||||
|
case 0xF0:
|
||||||
|
// Start of a SysEx message
|
||||||
|
continueSysex = event.buffer[event.size - 1] != 0xF7;
|
||||||
|
if ( ignoreFlags & 0x01 ) continue;
|
||||||
|
break;
|
||||||
|
case 0xF1:
|
||||||
|
case 0xF8:
|
||||||
|
// MIDI Time Code or Timing Clock message
|
||||||
|
if ( ignoreFlags & 0x02 ) continue;
|
||||||
|
break;
|
||||||
|
case 0xFE:
|
||||||
|
// Active Sensing message
|
||||||
|
if ( ignoreFlags & 0x04 ) continue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ( continueSysex ) {
|
||||||
|
// Continuation of a SysEx message
|
||||||
|
continueSysex = event.buffer[event.size - 1] != 0xF7;
|
||||||
|
if ( ignoreFlags & 0x01 ) continue;
|
||||||
|
}
|
||||||
|
// All other MIDI messages
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !continueSysex ) {
|
||||||
|
// If not a continuation of a SysEx message,
|
||||||
|
// invoke the user callback function or queue the message.
|
||||||
if ( rtData->usingCallback ) {
|
if ( rtData->usingCallback ) {
|
||||||
RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback;
|
RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback;
|
||||||
callback( message.timeStamp, &message.bytes, rtData->userData );
|
callback( message.timeStamp, &message.bytes, rtData->userData );
|
||||||
@@ -2594,9 +3042,10 @@ static int jackProcessIn( jack_nframes_t nframes, void *arg )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInJack :: MidiInJack( const std::string &clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
|
MidiInJack :: MidiInJack( const std::string &clientName, unsigned int queueSizeLimit )
|
||||||
|
: MidiInApi( queueSizeLimit )
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiInJack::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiInJack :: initialize( const std::string& clientName )
|
void MidiInJack :: initialize( const std::string& clientName )
|
||||||
@@ -2632,7 +3081,7 @@ void MidiInJack :: connect()
|
|||||||
MidiInJack :: ~MidiInJack()
|
MidiInJack :: ~MidiInJack()
|
||||||
{
|
{
|
||||||
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
||||||
closePort();
|
MidiInJack::closePort();
|
||||||
|
|
||||||
if ( data->client )
|
if ( data->client )
|
||||||
jack_client_close( data->client );
|
jack_client_close( data->client );
|
||||||
@@ -2659,6 +3108,8 @@ void MidiInJack :: openPort( unsigned int portNumber, const std::string &portNam
|
|||||||
// Connecting to the output
|
// Connecting to the output
|
||||||
std::string name = getPortName( portNumber );
|
std::string name = getPortName( portNumber );
|
||||||
jack_connect( data->client, name.c_str(), jack_port_name( data->port ) );
|
jack_connect( data->client, name.c_str(), jack_port_name( data->port ) );
|
||||||
|
|
||||||
|
connected_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiInJack :: openVirtualPort( const std::string &portName )
|
void MidiInJack :: openVirtualPort( const std::string &portName )
|
||||||
@@ -2714,7 +3165,9 @@ std::string MidiInJack :: getPortName( unsigned int portNumber )
|
|||||||
return retStr;
|
return retStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ports[portNumber] == NULL ) {
|
unsigned int i;
|
||||||
|
for ( i=0; i<portNumber && ports[i]; i++ ) {}
|
||||||
|
if ( i < portNumber || !ports[portNumber] ) {
|
||||||
std::ostringstream ost;
|
std::ostringstream ost;
|
||||||
ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
|
ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
|
||||||
errorString_ = ost.str();
|
errorString_ = ost.str();
|
||||||
@@ -2722,7 +3175,7 @@ std::string MidiInJack :: getPortName( unsigned int portNumber )
|
|||||||
}
|
}
|
||||||
else retStr.assign( ports[portNumber] );
|
else retStr.assign( ports[portNumber] );
|
||||||
|
|
||||||
free( ports );
|
jack_free( ports );
|
||||||
return retStr;
|
return retStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2733,6 +3186,26 @@ void MidiInJack :: closePort()
|
|||||||
if ( data->port == NULL ) return;
|
if ( data->port == NULL ) return;
|
||||||
jack_port_unregister( data->client, data->port );
|
jack_port_unregister( data->client, data->port );
|
||||||
data->port = NULL;
|
data->port = NULL;
|
||||||
|
|
||||||
|
connected_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiInJack:: setClientName( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiInJack::setClientName: this function is not implemented for the UNIX_JACK API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiInJack :: setPortName( const std::string &portName )
|
||||||
|
{
|
||||||
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
||||||
|
#ifdef JACK_HAS_PORT_RENAME
|
||||||
|
jack_port_rename( data->client, data->port, portName.c_str() );
|
||||||
|
#else
|
||||||
|
jack_port_set_name( data->port, portName.c_str() );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//*********************************************************************//
|
//*********************************************************************//
|
||||||
@@ -2770,7 +3243,7 @@ static int jackProcessOut( jack_nframes_t nframes, void *arg )
|
|||||||
|
|
||||||
MidiOutJack :: MidiOutJack( const std::string &clientName ) : MidiOutApi()
|
MidiOutJack :: MidiOutJack( const std::string &clientName ) : MidiOutApi()
|
||||||
{
|
{
|
||||||
initialize( clientName );
|
MidiOutJack::initialize( clientName );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiOutJack :: initialize( const std::string& clientName )
|
void MidiOutJack :: initialize( const std::string& clientName )
|
||||||
@@ -2813,7 +3286,7 @@ void MidiOutJack :: connect()
|
|||||||
MidiOutJack :: ~MidiOutJack()
|
MidiOutJack :: ~MidiOutJack()
|
||||||
{
|
{
|
||||||
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
||||||
closePort();
|
MidiOutJack::closePort();
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
jack_ringbuffer_free( data->buffSize );
|
jack_ringbuffer_free( data->buffSize );
|
||||||
@@ -2850,6 +3323,8 @@ void MidiOutJack :: openPort( unsigned int portNumber, const std::string &portNa
|
|||||||
// Connecting to the output
|
// Connecting to the output
|
||||||
std::string name = getPortName( portNumber );
|
std::string name = getPortName( portNumber );
|
||||||
jack_connect( data->client, jack_port_name( data->port ), name.c_str() );
|
jack_connect( data->client, jack_port_name( data->port ), name.c_str() );
|
||||||
|
|
||||||
|
connected_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiOutJack :: openVirtualPort( const std::string &portName )
|
void MidiOutJack :: openVirtualPort( const std::string &portName )
|
||||||
@@ -2926,8 +3401,7 @@ void MidiOutJack :: closePort()
|
|||||||
|
|
||||||
#ifdef HAVE_SEMAPHORE
|
#ifdef HAVE_SEMAPHORE
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
if (clock_gettime(CLOCK_REALTIME, &ts) != -1)
|
if ( clock_gettime( CLOCK_REALTIME, &ts ) != -1 ) {
|
||||||
{
|
|
||||||
ts.tv_sec += 1; // wait max one second
|
ts.tv_sec += 1; // wait max one second
|
||||||
sem_post( &data->sem_needpost );
|
sem_post( &data->sem_needpost );
|
||||||
sem_timedwait( &data->sem_cleanup, &ts );
|
sem_timedwait( &data->sem_cleanup, &ts );
|
||||||
@@ -2936,6 +3410,26 @@ void MidiOutJack :: closePort()
|
|||||||
|
|
||||||
jack_port_unregister( data->client, data->port );
|
jack_port_unregister( data->client, data->port );
|
||||||
data->port = NULL;
|
data->port = NULL;
|
||||||
|
|
||||||
|
connected_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiOutJack:: setClientName( const std::string& )
|
||||||
|
{
|
||||||
|
|
||||||
|
errorString_ = "MidiOutJack::setClientName: this function is not implemented for the UNIX_JACK API!";
|
||||||
|
error( RtMidiError::WARNING, errorString_ );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiOutJack :: setPortName( const std::string &portName )
|
||||||
|
{
|
||||||
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
||||||
|
#ifdef JACK_HAS_PORT_RENAME
|
||||||
|
jack_port_rename( data->client, data->port, portName.c_str() );
|
||||||
|
#else
|
||||||
|
jack_port_set_name( data->port, portName.c_str() );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiOutJack :: sendMessage( const unsigned char *message, size_t size )
|
void MidiOutJack :: sendMessage( const unsigned char *message, size_t size )
|
||||||
@@ -2944,8 +3438,7 @@ void MidiOutJack :: sendMessage( const unsigned char *message, size_t size )
|
|||||||
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
||||||
|
|
||||||
// Write full message to buffer
|
// Write full message to buffer
|
||||||
jack_ringbuffer_write( data->buffMessage, ( const char * ) message,
|
jack_ringbuffer_write( data->buffMessage, ( const char * ) message, nBytes );
|
||||||
nBytes );
|
|
||||||
jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) );
|
jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user