|
@@ -35,7 +35,7 @@
|
|
|
*/
|
|
|
/**********************************************************************/
|
|
|
|
|
|
-// RtMidi: Version 1.0.14
|
|
|
+// RtMidi: Version 1.0.15
|
|
|
|
|
|
#include "RtMidi.h"
|
|
|
#include <sstream>
|
|
@@ -69,9 +69,14 @@ void RtMidi :: error( RtError::Type type )
|
|
|
// Common RtMidiIn Definitions
|
|
|
//*********************************************************************//
|
|
|
|
|
|
-RtMidiIn :: RtMidiIn( const std::string clientName ) : RtMidi()
|
|
|
+RtMidiIn :: RtMidiIn( const std::string clientName, unsigned int queueSizeLimit ) : RtMidi()
|
|
|
{
|
|
|
this->initialize( clientName );
|
|
|
+
|
|
|
+ // Allocate the MIDI queue.
|
|
|
+ inputData_.queue.ringSize = queueSizeLimit;
|
|
|
+ if ( inputData_.queue.ringSize > 0 )
|
|
|
+ inputData_.queue.ring = new MidiMessage[ inputData_.queue.ringSize ];
|
|
|
}
|
|
|
|
|
|
void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData )
|
|
@@ -106,11 +111,6 @@ void RtMidiIn :: cancelCallback()
|
|
|
inputData_.usingCallback = false;
|
|
|
}
|
|
|
|
|
|
-void RtMidiIn :: setQueueSizeLimit( unsigned int queueSize )
|
|
|
-{
|
|
|
- inputData_.queueLimit = queueSize;
|
|
|
-}
|
|
|
-
|
|
|
void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense )
|
|
|
{
|
|
|
inputData_.ignoreFlags = 0;
|
|
@@ -129,13 +129,16 @@ double RtMidiIn :: getMessage( std::vector<unsigned char> *message )
|
|
|
return 0.0;
|
|
|
}
|
|
|
|
|
|
- if ( inputData_.queue.size() == 0 ) return 0.0;
|
|
|
+ if ( inputData_.queue.size == 0 ) return 0.0;
|
|
|
|
|
|
// Copy queued message to the vector pointer argument and then "pop" it.
|
|
|
- std::vector<unsigned char> *bytes = &(inputData_.queue.front().bytes);
|
|
|
+ std::vector<unsigned char> *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes);
|
|
|
message->assign( bytes->begin(), bytes->end() );
|
|
|
- double deltaTime = inputData_.queue.front().timeStamp;
|
|
|
- inputData_.queue.pop();
|
|
|
+ double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp;
|
|
|
+ inputData_.queue.size--;
|
|
|
+ inputData_.queue.front++;
|
|
|
+ if ( inputData_.queue.front == inputData_.queue.ringSize )
|
|
|
+ inputData_.queue.front = 0;
|
|
|
|
|
|
return deltaTime;
|
|
|
}
|
|
@@ -248,8 +251,12 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -308,8 +315,12 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -434,6 +445,9 @@ RtMidiIn :: ~RtMidiIn()
|
|
|
MIDIClientDispose( data->client );
|
|
|
if ( data->endpoint ) MIDIEndpointDispose( data->endpoint );
|
|
|
delete data;
|
|
|
+
|
|
|
+ // Delete the MIDI queue.
|
|
|
+ if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
|
|
|
}
|
|
|
|
|
|
unsigned int RtMidiIn :: getPortCount()
|
|
@@ -1021,8 +1035,12 @@ extern "C" void *alsaMidiHandler( void *ptr )
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -1274,6 +1292,9 @@ RtMidiIn :: ~RtMidiIn()
|
|
|
#endif
|
|
|
snd_seq_close( data->seq );
|
|
|
delete data;
|
|
|
+
|
|
|
+ // Delete the MIDI queue.
|
|
|
+ if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
|
|
|
}
|
|
|
|
|
|
unsigned int RtMidiIn :: getPortCount()
|
|
@@ -1625,8 +1646,12 @@ extern "C" void *irixMidiHandler( void *ptr )
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -1668,8 +1693,12 @@ extern "C" void *irixMidiHandler( void *ptr )
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -1770,6 +1799,9 @@ RtMidiIn :: ~RtMidiIn()
|
|
|
// Cleanup.
|
|
|
IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);
|
|
|
delete data;
|
|
|
+
|
|
|
+ // Delete the MIDI queue.
|
|
|
+ if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
|
|
|
}
|
|
|
|
|
|
unsigned int RtMidiIn :: getPortCount()
|
|
@@ -2051,8 +2083,12 @@ static void CALLBACK midiInputCallback( HMIDIIN hmin,
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( data->queueLimit > data->queue.size() )
|
|
|
- data->queue.push( apiData->message );
|
|
|
+ if ( data->queue.size < data->queue.ringSize ) {
|
|
|
+ data->queue.ring[data->queue.back++] = apiData->message;
|
|
|
+ if ( data->queue.back == data->queue.ringSize )
|
|
|
+ data->queue.back = 0;
|
|
|
+ data->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -2182,6 +2218,9 @@ RtMidiIn :: ~RtMidiIn()
|
|
|
// Cleanup.
|
|
|
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
|
|
delete data;
|
|
|
+
|
|
|
+ // Delete the MIDI queue.
|
|
|
+ if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
|
|
|
}
|
|
|
|
|
|
unsigned int RtMidiIn :: getPortCount()
|
|
@@ -2205,14 +2244,14 @@ std::string RtMidiIn :: getPortName( unsigned int portNumber )
|
|
|
MIDIINCAPS deviceCaps;
|
|
|
midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS));
|
|
|
|
|
|
- // For some reason, we need to copy character by character with
|
|
|
- // UNICODE (thanks to Eduardo Coutinho!).
|
|
|
- //std::string stringName = std::string( deviceCaps.szPname );
|
|
|
- char nameString[MAXPNAMELEN];
|
|
|
- for( int i=0; i<MAXPNAMELEN; ++i )
|
|
|
- nameString[i] = (char)( deviceCaps.szPname[i] );
|
|
|
+#if defined( UNICODE ) || defined( _UNICODE )
|
|
|
+ int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL);
|
|
|
+ stringName.assign( length, 0 );
|
|
|
+ length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL);
|
|
|
+#else
|
|
|
+ stringName = std::string( deviceCaps.szPname );
|
|
|
+#endif
|
|
|
|
|
|
- stringName = nameString;
|
|
|
return stringName;
|
|
|
}
|
|
|
|
|
@@ -2242,14 +2281,14 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
|
|
|
MIDIOUTCAPS deviceCaps;
|
|
|
midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS));
|
|
|
|
|
|
- // For some reason, we need to copy character by character with
|
|
|
- // UNICODE (thanks to Eduardo Coutinho!).
|
|
|
- //std::string stringName = std::string( deviceCaps.szPname );
|
|
|
- char nameString[MAXPNAMELEN];
|
|
|
- for( int i=0; i<MAXPNAMELEN; ++i )
|
|
|
- nameString[i] = (char)( deviceCaps.szPname[i] );
|
|
|
+#if defined( UNICODE ) || defined( _UNICODE )
|
|
|
+ int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL);
|
|
|
+ stringName.assign( length, 0 );
|
|
|
+ length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL);
|
|
|
+#else
|
|
|
+ stringName = std::string( deviceCaps.szPname );
|
|
|
+#endif
|
|
|
|
|
|
- stringName = nameString;
|
|
|
return stringName;
|
|
|
}
|
|
|
|
|
@@ -2478,8 +2517,12 @@ int jackProcessIn( jack_nframes_t nframes, void *arg )
|
|
|
}
|
|
|
else {
|
|
|
// As long as we haven't reached our queue size limit, push the message.
|
|
|
- if ( rtData->queueLimit > rtData->queue.size() )
|
|
|
- rtData->queue.push( message );
|
|
|
+ if ( rtData->queue.size < rtData->queue.ringSize ) {
|
|
|
+ rtData->queue.ring[rtData->queue.back++] = message;
|
|
|
+ if ( rtData->queue.back == rtData->queue.ringSize )
|
|
|
+ rtData->queue.back = 0;
|
|
|
+ rtData->queue.size++;
|
|
|
+ }
|
|
|
else
|
|
|
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
|
|
|
}
|
|
@@ -2515,6 +2558,9 @@ RtMidiIn :: ~RtMidiIn()
|
|
|
{
|
|
|
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
|
|
|
jack_client_close( data->client );
|
|
|
+
|
|
|
+ // Delete the MIDI queue.
|
|
|
+ if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
|
|
|
}
|
|
|
|
|
|
void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName )
|