瀏覽代碼

Version 1.0.11

Gary Scavone 11 年之前
父節點
當前提交
94ef7a9c92
共有 7 個文件被更改,包括 79 次插入63 次删除
  1. 61 54
      RtMidi.cpp
  2. 2 2
      RtMidi.h
  3. 1 1
      doc/doxygen/Doxyfile
  4. 1 1
      doc/doxygen/footer.html
  5. 5 2
      doc/doxygen/tutorial.txt
  6. 7 1
      doc/release.txt
  7. 2 2
      readme

+ 61 - 54
RtMidi.cpp

@@ -8,7 +8,7 @@
     RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
     RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
 
 
     RtMidi: realtime MIDI i/o C++ classes
     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
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation files
     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 "RtMidi.h"
 #include <sstream>
 #include <sstream>
@@ -166,6 +166,7 @@ RtMidiOut :: RtMidiOut( const std::string clientName ) : RtMidi()
 // OS-X CoreMIDI header files.
 // OS-X CoreMIDI header files.
 #include <CoreMIDI/CoreMIDI.h>
 #include <CoreMIDI/CoreMIDI.h>
 #include <CoreAudio/HostTime.h>
 #include <CoreAudio/HostTime.h>
+#include <CoreServices/CoreServices.h>
 
 
 // A structure to hold variables related to the CoreMIDI API
 // A structure to hold variables related to the CoreMIDI API
 // implementation.
 // implementation.
@@ -226,7 +227,7 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
       // We have a continuing, segmented sysex message.
       // We have a continuing, segmented sysex message.
       if ( !( data->ignoreFlags & 0x01 ) ) {
       if ( !( data->ignoreFlags & 0x01 ) ) {
         // If we're not ignoring sysex messages, copy the entire packet.
         // 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] );
           message.bytes.push_back( packet->data[j] );
       }
       }
       continueSysex = packet->data[nBytes-1] != 0xF7;
       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.
   // Get the desired input source identifier.
   MIDIEndpointRef endpoint = MIDIGetSource( portNumber );
   MIDIEndpointRef endpoint = MIDIGetSource( portNumber );
-  if ( endpoint == NULL ) {
+  if ( endpoint == 0 ) {
     MIDIPortDispose( port );
     MIDIPortDispose( port );
     MIDIClientDispose( data->client );
     MIDIClientDispose( data->client );
     errorString_ = "RtMidiIn::openPort: error getting MIDI input source reference.";
     errorString_ = "RtMidiIn::openPort: error getting MIDI input source reference.";
@@ -451,7 +452,7 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
 
 
   MIDIEntityRef entity = NULL;
   MIDIEntityRef entity = NULL;
   MIDIEndpointGetEntity( endpoint, &entity );
   MIDIEndpointGetEntity( endpoint, &entity );
-  if ( entity == NULL )
+  if ( entity == 0 )
     // probably virtual
     // probably virtual
     return result;
     return result;
 
 
@@ -465,9 +466,9 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
     }
     }
   }
   }
   // now consider the device's name
   // now consider the device's name
-  MIDIDeviceRef device = NULL;
+  MIDIDeviceRef device = 0;
   MIDIEntityGetDevice( entity, &device );
   MIDIEntityGetDevice( entity, &device );
-  if ( device == NULL )
+  if ( device == 0 )
     return result;
     return result;
 
 
   str = NULL;
   str = NULL;
@@ -665,7 +666,7 @@ void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName
 
 
   // Get the desired output port identifier.
   // Get the desired output port identifier.
   MIDIEndpointRef destination = MIDIGetDestination( portNumber );
   MIDIEndpointRef destination = MIDIGetDestination( portNumber );
-  if ( destination == NULL ) {
+  if ( destination == 0 ) {
     MIDIPortDispose( port );
     MIDIPortDispose( port );
     MIDIClientDispose( data->client );
     MIDIClientDispose( data->client );
     errorString_ = "RtMidiOut::openPort: error getting MIDI output destination reference.";
     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 );
       unsigned int caps = snd_seq_port_info_get_capability( pinfo );
       if ( ( caps & type ) != type ) continue;
       if ( ( caps & type ) != type ) continue;
       if ( count == portNumber ) return 1;
       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 );
   if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport );
 #ifndef AVOID_TIMESTAMPING
 #ifndef AVOID_TIMESTAMPING
   snd_seq_free_queue( data->seq, data->queue_id );
   snd_seq_free_queue( data->seq, data->queue_id );
-  snd_seq_close( data->seq );
 #endif
 #endif
+  snd_seq_close( data->seq );
   delete data;
   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_source(&ev, data->vport);
   snd_seq_ev_set_subs(&ev);
   snd_seq_ev_set_subs(&ev);
   snd_seq_ev_set_direct(&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 );
   result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev );
   if ( result < (int)nBytes ) {
   if ( result < (int)nBytes ) {
     errorString_ = "RtMidiOut::sendMessage: event parsing error!";
     errorString_ = "RtMidiOut::sendMessage: event parsing error!";
@@ -1564,7 +1565,7 @@ extern "C" void *irixMidiHandler( void *ptr )
         if ( continueSysex ) {
         if ( continueSysex ) {
           // We have a continuing, segmented sysex message.  Append
           // We have a continuing, segmented sysex message.  Append
           // the new bytes to our existing message.
           // 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] );
             message.bytes.push_back( event.sysexmsg[i] );
           if ( event.sysexmsg[event.msglen-1] == 0xF7 ) continueSysex = false;
           if ( event.sysexmsg[event.msglen-1] == 0xF7 ) continueSysex = false;
           if ( !continueSysex ) {
           if ( !continueSysex ) {
@@ -1858,11 +1859,11 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
     event.msg[0] = 0xF0;
     event.msg[0] = 0xF0;
     event.msglen = nBytes;
     event.msglen = nBytes;
     buffer = (char *) malloc( 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;
     event.sysexmsg = buffer;
   }
   }
   else {
   else {
-    for ( int i=0; i<nBytes; i++ )
+    for ( int i=0; i<nBytes; ++i )
       event.msg[i] = message->at(i);
       event.msg[i] = message->at(i);
   }
   }
 
 
@@ -1897,6 +1898,9 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
 #include <windows.h>
 #include <windows.h>
 #include <mmsystem.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
 // A structure to hold variables related to the CoreMIDI API
 // implementation.
 // implementation.
 struct WinMidiData {
 struct WinMidiData {
@@ -1904,11 +1908,9 @@ struct WinMidiData {
   HMIDIOUT outHandle;  // Handle to Midi Output Device
   HMIDIOUT outHandle;  // Handle to Midi Output Device
   DWORD lastTime;
   DWORD lastTime;
   RtMidiIn::MidiMessage message;
   RtMidiIn::MidiMessage message;
-  LPMIDIHDR sysexBuffer;
+  LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT];
 };
 };
 
 
-#define  RT_SYSEX_BUFFER_SIZE 1024
-
 //*********************************************************************//
 //*********************************************************************//
 //  API: Windows MM
 //  API: Windows MM
 //  Class Definitions: RtMidiIn
 //  Class Definitions: RtMidiIn
@@ -1920,7 +1922,7 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
                                         DWORD midiMessage,
                                         DWORD midiMessage,
                                         DWORD timestamp )
                                         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 = static_cast<RtMidiIn::RtMidiInData *> (instancePtr);
   RtMidiIn::RtMidiInData *data = (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.
     // Copy bytes to our MIDI message.
     unsigned char *ptr = (unsigned char *) &midiMessage;
     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; 
     MIDIHDR *sysex = ( MIDIHDR *) midiMessage; 
-    if ( !( data->ignoreFlags & 0x01 ) ) {  
+    if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) {  
       // Sysex message and we're not ignoring it
       // 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] );
         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
     // buffer when an application closes and in this case, we should
     // avoid requeueing it, else the computer suddenly reboots after
     // avoid requeueing it, else the computer suddenly reboots after
     // one or two minutes.
     // 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 )
       if ( result != MMSYSERR_NOERROR )
         std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n";
         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 );
     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 );
   result = midiInStart( data->inHandle );
@@ -2099,13 +2104,15 @@ void RtMidiIn :: closePort( void )
     midiInReset( data->inHandle );
     midiInReset( data->inHandle );
     midiInStop( 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 );
     midiInClose( data->inHandle );
@@ -2145,7 +2152,7 @@ std::string RtMidiIn :: getPortName( unsigned int portNumber )
   // UNICODE (thanks to Eduardo Coutinho!).
   // UNICODE (thanks to Eduardo Coutinho!).
   //std::string stringName = std::string( deviceCaps.szPname );
   //std::string stringName = std::string( deviceCaps.szPname );
   char nameString[MAXPNAMELEN];
   char nameString[MAXPNAMELEN];
-  for( int i=0; i<MAXPNAMELEN; i++ )
+  for( int i=0; i<MAXPNAMELEN; ++i )
     nameString[i] = (char)( deviceCaps.szPname[i] );
     nameString[i] = (char)( deviceCaps.szPname[i] );
 
 
   std::string stringName( nameString );
   std::string stringName( nameString );
@@ -2179,7 +2186,7 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
   // UNICODE (thanks to Eduardo Coutinho!).
   // UNICODE (thanks to Eduardo Coutinho!).
   //std::string stringName = std::string( deviceCaps.szPname );
   //std::string stringName = std::string( deviceCaps.szPname );
   char nameString[MAXPNAMELEN];
   char nameString[MAXPNAMELEN];
-  for( int i=0; i<MAXPNAMELEN; i++ )
+  for( int i=0; i<MAXPNAMELEN; ++i )
     nameString[i] = (char)( deviceCaps.szPname[i] );
     nameString[i] = (char)( deviceCaps.szPname[i] );
 
 
   std::string stringName( nameString );
   std::string stringName( nameString );
@@ -2284,7 +2291,7 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
     }
     }
 
 
     // Copy data to buffer.
     // 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.
     // Create and prepare MIDIHDR structure.
     MIDIHDR sysex;
     MIDIHDR sysex;
@@ -2323,9 +2330,9 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
     // Pack MIDI bytes into double word.
     // Pack MIDI bytes into double word.
     DWORD packet;
     DWORD packet;
     unsigned char *ptr = (unsigned char *) &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 = message->at(i);
-      ptr++;
+      ++ptr;
     }
     }
 
 
     // Send the message immediately.
     // Send the message immediately.

+ 2 - 2
RtMidi.h

@@ -8,7 +8,7 @@
     RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
     RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
 
 
     RtMidi: realtime MIDI i/o C++ classes
     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
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation files
     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
 #ifndef RTMIDI_H
 #define RTMIDI_H
 #define RTMIDI_H

+ 1 - 1
doc/doxygen/Doxyfile

@@ -31,7 +31,7 @@ PROJECT_NAME           = RtMidi
 # This could be handy for archiving the generated documentation or 
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 # 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) 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
 # base path where the generated documentation will be put. 

+ 1 - 1
doc/doxygen/footer.html

@@ -1,7 +1,7 @@
 <HR>
 <HR>
 
 
 <table><tr><td><img src="../images/mcgill.gif" width=165></td>
 <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>
   Maintained by Gary P. Scavone, gary at music.mcgill.ca</td></tr>
 </table>
 </table>
 
 

+ 5 - 2
doc/doxygen/tutorial.txt

@@ -17,7 +17,7 @@ MIDI input and output functionality are separated into two classes, RtMidiIn and
 
 
 \section download Download
 \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
 \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>Christoph Eckert (ALSA sysex fixes)</LI>
 <LI>Immanuel Litzroth (OS-X sysex fix)</LI>
 <LI>Immanuel Litzroth (OS-X sysex fix)</LI>
 <LI>Axel Schmidt (client naming)</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>
 </UL>
 
 
 \section license License
 \section license License
 
 
     RtMidi: realtime MIDI i/o C++ classes<BR>
     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
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation files
     obtaining a copy of this software and associated documentation files

+ 7 - 1
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.
 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)
 v1.0.10: (3 June 2009)
 - fix adding timestamp to OS-X sendMessage() function (thanks to John Dey)
 - fix adding timestamp to OS-X sendMessage() function (thanks to John Dey)

+ 2 - 2
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.
 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:
 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.
 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
     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
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation files
     obtaining a copy of this software and associated documentation files