summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2013-10-11 14:49:11 +0200
committerStephen Sinclair <sinclair@music.mcgill.ca>2013-10-11 14:49:11 +0200
commit94ef7a9c9202314c5fe9de2dc24b16ded6b7d98c (patch)
tree2cd7541d54992c8cc486e001d7784d6f461b6e59
parentfca075f4b54cb4600d06783a225a94e3dd45d640 (diff)
Version 1.0.11
-rw-r--r--RtMidi.cpp115
-rw-r--r--RtMidi.h4
-rw-r--r--doc/doxygen/Doxyfile2
-rw-r--r--doc/doxygen/footer.html2
-rw-r--r--doc/doxygen/tutorial.txt7
-rw-r--r--doc/release.txt8
-rw-r--r--readme4
7 files changed, 79 insertions, 63 deletions
diff --git a/RtMidi.cpp b/RtMidi.cpp
index 4b73921..de8b6ae 100644
--- a/RtMidi.cpp
+++ b/RtMidi.cpp
@@ -8,7 +8,7 @@
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
- Copyright (c) 2003-2009 Gary P. Scavone
+ Copyright (c) 2003-2010 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@@ -35,7 +35,7 @@
*/
/**********************************************************************/
-// RtMidi: Version 1.0.10
+// RtMidi: Version 1.0.11
#include "RtMidi.h"
#include <sstream>
@@ -166,6 +166,7 @@ RtMidiOut :: RtMidiOut( const std::string clientName ) : RtMidi()
// OS-X CoreMIDI header files.
#include <CoreMIDI/CoreMIDI.h>
#include <CoreAudio/HostTime.h>
+#include <CoreServices/CoreServices.h>
// A structure to hold variables related to the CoreMIDI API
// implementation.
@@ -226,7 +227,7 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
// We have a continuing, segmented sysex message.
if ( !( data->ignoreFlags & 0x01 ) ) {
// If we're not ignoring sysex messages, copy the entire packet.
- for ( unsigned int j=0; j<nBytes; j++ )
+ for ( unsigned int j=0; j<nBytes; ++j )
message.bytes.push_back( packet->data[j] );
}
continueSysex = packet->data[nBytes-1] != 0xF7;
@@ -368,7 +369,7 @@ void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName )
// Get the desired input source identifier.
MIDIEndpointRef endpoint = MIDIGetSource( portNumber );
- if ( endpoint == NULL ) {
+ if ( endpoint == 0 ) {
MIDIPortDispose( port );
MIDIClientDispose( data->client );
errorString_ = "RtMidiIn::openPort: error getting MIDI input source reference.";
@@ -451,7 +452,7 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
MIDIEntityRef entity = NULL;
MIDIEndpointGetEntity( endpoint, &entity );
- if ( entity == NULL )
+ if ( entity == 0 )
// probably virtual
return result;
@@ -465,9 +466,9 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
}
}
// now consider the device's name
- MIDIDeviceRef device = NULL;
+ MIDIDeviceRef device = 0;
MIDIEntityGetDevice( entity, &device );
- if ( device == NULL )
+ if ( device == 0 )
return result;
str = NULL;
@@ -665,7 +666,7 @@ void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName
// Get the desired output port identifier.
MIDIEndpointRef destination = MIDIGetDestination( portNumber );
- if ( destination == NULL ) {
+ if ( destination == 0 ) {
MIDIPortDispose( port );
MIDIClientDispose( data->client );
errorString_ = "RtMidiOut::openPort: error getting MIDI output destination reference.";
@@ -1042,7 +1043,7 @@ unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int
unsigned int caps = snd_seq_port_info_get_capability( pinfo );
if ( ( caps & type ) != type ) continue;
if ( count == portNumber ) return 1;
- count++;
+ ++count;
}
}
@@ -1225,8 +1226,8 @@ RtMidiIn :: ~RtMidiIn()
if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport );
#ifndef AVOID_TIMESTAMPING
snd_seq_free_queue( data->seq, data->queue_id );
- snd_seq_close( data->seq );
#endif
+ snd_seq_close( data->seq );
delete data;
}
@@ -1458,7 +1459,7 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
snd_seq_ev_set_source(&ev, data->vport);
snd_seq_ev_set_subs(&ev);
snd_seq_ev_set_direct(&ev);
- for ( unsigned int i=0; i<nBytes; i++ ) data->buffer[i] = message->at(i);
+ for ( unsigned int i=0; i<nBytes; ++i ) data->buffer[i] = message->at(i);
result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev );
if ( result < (int)nBytes ) {
errorString_ = "RtMidiOut::sendMessage: event parsing error!";
@@ -1564,7 +1565,7 @@ extern "C" void *irixMidiHandler( void *ptr )
if ( continueSysex ) {
// We have a continuing, segmented sysex message. Append
// the new bytes to our existing message.
- for ( int i=0; i<event.msglen; i++ )
+ for ( int i=0; i<event.msglen; ++i )
message.bytes.push_back( event.sysexmsg[i] );
if ( event.sysexmsg[event.msglen-1] == 0xF7 ) continueSysex = false;
if ( !continueSysex ) {
@@ -1858,11 +1859,11 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
event.msg[0] = 0xF0;
event.msglen = nBytes;
buffer = (char *) malloc( nBytes );
- for ( int i=0; i<nBytes; i++ ) buffer[i] = message->at(i);
+ for ( int i=0; i<nBytes; ++i ) buffer[i] = message->at(i);
event.sysexmsg = buffer;
}
else {
- for ( int i=0; i<nBytes; i++ )
+ for ( int i=0; i<nBytes; ++i )
event.msg[i] = message->at(i);
}
@@ -1897,6 +1898,9 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
#include <windows.h>
#include <mmsystem.h>
+#define RT_SYSEX_BUFFER_SIZE 1024
+#define RT_SYSEX_BUFFER_COUNT 4
+
// A structure to hold variables related to the CoreMIDI API
// implementation.
struct WinMidiData {
@@ -1904,11 +1908,9 @@ struct WinMidiData {
HMIDIOUT outHandle; // Handle to Midi Output Device
DWORD lastTime;
RtMidiIn::MidiMessage message;
- LPMIDIHDR sysexBuffer;
+ LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT];
};
-#define RT_SYSEX_BUFFER_SIZE 1024
-
//*********************************************************************//
// API: Windows MM
// Class Definitions: RtMidiIn
@@ -1920,7 +1922,7 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
DWORD midiMessage,
DWORD timestamp )
{
- if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA ) return;
+ if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR ) return;
//RtMidiIn::RtMidiInData *data = static_cast<RtMidiIn::RtMidiInData *> (instancePtr);
RtMidiIn::RtMidiInData *data = (RtMidiIn::RtMidiInData *)instancePtr;
@@ -1960,13 +1962,13 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
// Copy bytes to our MIDI message.
unsigned char *ptr = (unsigned char *) &midiMessage;
- for ( int i=0; i<nBytes; i++ ) apiData->message.bytes.push_back( *ptr++ );
+ for ( int i=0; i<nBytes; ++i ) apiData->message.bytes.push_back( *ptr++ );
}
- else { // Sysex message ( MIM_LONGDATA )
+ else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR )
MIDIHDR *sysex = ( MIDIHDR *) midiMessage;
- if ( !( data->ignoreFlags & 0x01 ) ) {
+ if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) {
// Sysex message and we're not ignoring it
- for ( int i=0; i<(int)sysex->dwBytesRecorded; i++ )
+ for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i )
apiData->message.bytes.push_back( sysex->lpData[i] );
}
@@ -1978,9 +1980,9 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
// buffer when an application closes and in this case, we should
// avoid requeueing it, else the computer suddenly reboots after
// one or two minutes.
- if ( apiData->sysexBuffer->dwBytesRecorded > 0 ) {
- //if ( sysex->dwBytesRecorded > 0 ) {
- MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer, sizeof(MIDIHDR) );
+ if ( apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0 ) {
+ //if ( sysex->dwBytesRecorded > 0 ) {
+ MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR) );
if ( result != MMSYSERR_NOERROR )
std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n";
@@ -2054,25 +2056,28 @@ void RtMidiIn :: openPort( unsigned int portNumber, const std::string /*portName
error( RtError::DRIVER_ERROR );
}
- // Allocate and init the sysex buffer.
- data->sysexBuffer = (MIDIHDR*) new char[ sizeof(MIDIHDR) ];
- data->sysexBuffer->lpData = new char[ RT_SYSEX_BUFFER_SIZE ];
- data->sysexBuffer->dwBufferLength = RT_SYSEX_BUFFER_SIZE;
- data->sysexBuffer->dwFlags = 0;
+ // Allocate and init the sysex buffers.
+ for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) {
+ data->sysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ];
+ data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ];
+ data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE;
+ data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator
+ data->sysexBuffer[i]->dwFlags = 0;
- result = midiInPrepareHeader( data->inHandle, data->sysexBuffer, sizeof(MIDIHDR) );
- if ( result != MMSYSERR_NOERROR ) {
- midiInClose( data->inHandle );
- errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (PrepareHeader).";
- error( RtError::DRIVER_ERROR );
- }
+ result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
+ if ( result != MMSYSERR_NOERROR ) {
+ midiInClose( data->inHandle );
+ errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (PrepareHeader).";
+ error( RtError::DRIVER_ERROR );
+ }
- // Register the buffer.
- result = midiInAddBuffer( data->inHandle, data->sysexBuffer, sizeof(MIDIHDR) );
- if ( result != MMSYSERR_NOERROR ) {
- midiInClose( data->inHandle );
- errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (AddBuffer).";
- error( RtError::DRIVER_ERROR );
+ // Register the buffer.
+ result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
+ if ( result != MMSYSERR_NOERROR ) {
+ midiInClose( data->inHandle );
+ errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (AddBuffer).";
+ error( RtError::DRIVER_ERROR );
+ }
}
result = midiInStart( data->inHandle );
@@ -2099,13 +2104,15 @@ void RtMidiIn :: closePort( void )
midiInReset( data->inHandle );
midiInStop( data->inHandle );
- int result = midiInUnprepareHeader(data->inHandle, data->sysexBuffer, sizeof(MIDIHDR));
- delete [] data->sysexBuffer->lpData;
- delete [] data->sysexBuffer;
- if ( result != MMSYSERR_NOERROR ) {
- midiInClose( data->inHandle );
- errorString_ = "RtMidiIn::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader).";
- error( RtError::DRIVER_ERROR );
+ for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) {
+ int result = midiInUnprepareHeader(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR));
+ delete [] data->sysexBuffer[i]->lpData;
+ delete [] data->sysexBuffer[i];
+ if ( result != MMSYSERR_NOERROR ) {
+ midiInClose( data->inHandle );
+ errorString_ = "RtMidiIn::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader).";
+ error( RtError::DRIVER_ERROR );
+ }
}
midiInClose( data->inHandle );
@@ -2145,7 +2152,7 @@ std::string RtMidiIn :: getPortName( unsigned int portNumber )
// UNICODE (thanks to Eduardo Coutinho!).
//std::string stringName = std::string( deviceCaps.szPname );
char nameString[MAXPNAMELEN];
- for( int i=0; i<MAXPNAMELEN; i++ )
+ for( int i=0; i<MAXPNAMELEN; ++i )
nameString[i] = (char)( deviceCaps.szPname[i] );
std::string stringName( nameString );
@@ -2179,7 +2186,7 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
// UNICODE (thanks to Eduardo Coutinho!).
//std::string stringName = std::string( deviceCaps.szPname );
char nameString[MAXPNAMELEN];
- for( int i=0; i<MAXPNAMELEN; i++ )
+ for( int i=0; i<MAXPNAMELEN; ++i )
nameString[i] = (char)( deviceCaps.szPname[i] );
std::string stringName( nameString );
@@ -2284,7 +2291,7 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
}
// Copy data to buffer.
- for ( unsigned int i=0; i<nBytes; i++ ) buffer[i] = message->at(i);
+ for ( unsigned int i=0; i<nBytes; ++i ) buffer[i] = message->at(i);
// Create and prepare MIDIHDR structure.
MIDIHDR sysex;
@@ -2323,9 +2330,9 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
// Pack MIDI bytes into double word.
DWORD packet;
unsigned char *ptr = (unsigned char *) &packet;
- for ( unsigned int i=0; i<nBytes; i++ ) {
+ for ( unsigned int i=0; i<nBytes; ++i ) {
*ptr = message->at(i);
- ptr++;
+ ++ptr;
}
// Send the message immediately.
diff --git a/RtMidi.h b/RtMidi.h
index eab4626..1e3b731 100644
--- a/RtMidi.h
+++ b/RtMidi.h
@@ -8,7 +8,7 @@
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
- Copyright (c) 2003-2009 Gary P. Scavone
+ Copyright (c) 2003-2010 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@@ -35,7 +35,7 @@
*/
/**********************************************************************/
-// RtMidi: Version 1.0.10
+// RtMidi: Version 1.0.11
#ifndef RTMIDI_H
#define RTMIDI_H
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 0624153..103f24e 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = RtMidi
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 1.0.10
+PROJECT_NUMBER = 1.0.11
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
diff --git a/doc/doxygen/footer.html b/doc/doxygen/footer.html
index 47f4340..dc3d30f 100644
--- a/doc/doxygen/footer.html
+++ b/doc/doxygen/footer.html
@@ -1,7 +1,7 @@
<HR>
<table><tr><td><img src="../images/mcgill.gif" width=165></td>
- <td>&copy;2003-2009 Gary P. Scavone, McGill University. All Rights Reserved.<br>
+ <td>&copy;2003-2010 Gary P. Scavone, McGill University. All Rights Reserved.<br>
Maintained by Gary P. Scavone, gary at music.mcgill.ca</td></tr>
</table>
diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt
index 1104e1a..4984589 100644
--- a/doc/doxygen/tutorial.txt
+++ b/doc/doxygen/tutorial.txt
@@ -17,7 +17,7 @@ MIDI input and output functionality are separated into two classes, RtMidiIn and
\section download Download
-Latest Release (3 June 2009): <A href="http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.10.tar.gz">Version 1.0.10</A>
+Latest Release (29 January 2010): <A href="http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.11.tar.gz">Version 1.0.11</A>
\section start Getting Started
@@ -416,12 +416,15 @@ Many thanks to the following people for providing bug fixes and improvements:
<LI>Christoph Eckert (ALSA sysex fixes)</LI>
<LI>Immanuel Litzroth (OS-X sysex fix)</LI>
<LI>Axel Schmidt (client naming)</LI>
+<LI>Bastiaan Verreijt (Windows sysex multi-buffer code)</LI>
+<LI>Jon McCormack (Snow Leopard updates)</LI>
+<LI>Paul Dean (increment optimization)</LI>
</UL>
\section license License
RtMidi: realtime MIDI i/o C++ classes<BR>
- Copyright (c) 2003-2009 Gary P. Scavone
+ Copyright (c) 2003-2010 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
diff --git a/doc/release.txt b/doc/release.txt
index 145a263..abfe577 100644
--- a/doc/release.txt
+++ b/doc/release.txt
@@ -1,6 +1,12 @@
RtMidi - a set of C++ classes that provides a common API for realtime MIDI input/output across Linux (ALSA), SGI, Macintosh OS X (CoreMidi), and Windows (Multimedia) operating systems.
-By Gary P. Scavone, 2003-2009.
+By Gary P. Scavone, 2003-2010.
+
+v1.0.11: (29 January 2010)
+- added CoreServices/CoreServices.h include for OS-X 10.6 and gcc4.2 compile (thanks to Jon McCormack)
+- various increment optimizations (thanks to Paul Dean)
+- fixed incorrectly located snd_seq_close() function in ALSA API (thanks to Pedro Lopez-Cabanillas)
+- updates to Windows sysex code to better deal with possible delivery problems (thanks to Bastiaan Verreijt)
v1.0.10: (3 June 2009)
- fix adding timestamp to OS-X sendMessage() function (thanks to John Dey)
diff --git a/readme b/readme
index 929c83c..cf26d46 100644
--- a/readme
+++ b/readme
@@ -1,6 +1,6 @@
RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA), SGI, Macintosh OS X (CoreMidi), and Windows (Multimedia) operating systems.
-By Gary P. Scavone, 2003-2009.
+By Gary P. Scavone, 2003-2010.
This distribution of RtMidi contains the following:
@@ -30,7 +30,7 @@ LEGAL AND ETHICAL:
The RtMidi license is similar to the the MIT License, with the added "feature" that modifications be sent to the developer.
RtMidi: realtime MIDI i/o C++ classes
- Copyright (c) 2003-2009 Gary P. Scavone
+ Copyright (c) 2003-2010 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files