summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2014-03-14 12:44:06 -0400
committerGary Scavone <gary@music.mcgill.ca>2014-03-14 12:44:06 -0400
commitd2530d10261f65c0e79541fc642092c178eec17c (patch)
tree76664eb294feaca429aa508ba38c63b217716040
parentcfb945a9c2aa53b631a0790f9554704e9e520aa6 (diff)
Updated OS-X sysex sending mechanism according to patch submitted by ptarabbia
-rw-r--r--RtMidi.cpp62
-rw-r--r--doc/release.txt1
-rw-r--r--tests/sysextest.cpp2
3 files changed, 32 insertions, 33 deletions
diff --git a/RtMidi.cpp b/RtMidi.cpp
index 18da68f..e6f507b 100644
--- a/RtMidi.cpp
+++ b/RtMidi.cpp
@@ -993,13 +993,9 @@ void MidiOutCore :: openVirtualPort( std::string portName )
data->endpoint = endpoint;
}
-static char *sysexBuffer = 0;
-
-static void sysexCompletionProc( MIDISysexSendRequest * /*sreq*/ )
+static void sysexCompletionProc( MIDISysexSendRequest *sreq )
{
- //std::cout << "Completed SysEx send\n";
- delete sysexBuffer;
- sysexBuffer = 0;
+ free( sreq );
}
void MidiOutCore :: sendMessage( std::vector<unsigned char> *message )
@@ -1021,32 +1017,34 @@ void MidiOutCore :: sendMessage( std::vector<unsigned char> *message )
if ( message->at(0) == 0xF0 ) {
- while ( sysexBuffer != 0 ) usleep( 1000 ); // sleep 1 ms
-
- sysexBuffer = new char[nBytes];
- if ( sysexBuffer == NULL ) {
- errorString_ = "MidiOutCore::sendMessage: error allocating sysex message memory!";
- error( RtMidiError::MEMORY_ERROR, errorString_ );
- return;
- }
-
- // Copy data to buffer.
- for ( unsigned int i=0; i<nBytes; ++i ) sysexBuffer[i] = message->at(i);
-
- data->sysexreq.destination = data->destinationId;
- data->sysexreq.data = (Byte *)sysexBuffer;
- data->sysexreq.bytesToSend = nBytes;
- data->sysexreq.complete = 0;
- data->sysexreq.completionProc = sysexCompletionProc;
- data->sysexreq.completionRefCon = &(data->sysexreq);
-
- result = MIDISendSysex( &(data->sysexreq) );
- if ( result != noErr ) {
- errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations.";
- error( RtMidiError::WARNING, errorString_ );
- return;
- }
- return;
+ // Apple's fantastic API requires us to free the allocated data in
+ // the completion callback but trashes the pointer and size before
+ // we get a chance to free it!! This is a somewhat ugly hack
+ // submitted by ptarabbia that puts the sysex buffer data right at
+ // the end of the MIDISysexSendRequest structure. This solution
+ // does not require that we wait for a previous sysex buffer to be
+ // sent before sending a new one, which was the old way we did it.
+ MIDISysexSendRequest *newRequest = (MIDISysexSendRequest *) malloc(sizeof(struct MIDISysexSendRequest) + nBytes);
+ char * sysexBuffer = ((char *) newRequest) + sizeof(struct MIDISysexSendRequest);
+
+ // Copy data to buffer.
+ for ( unsigned int i=0; i<nBytes; ++i ) sysexBuffer[i] = message->at(i);
+
+ newRequest->destination = data->destinationId;
+ newRequest->data = (Byte *)sysexBuffer;
+ newRequest->bytesToSend = nBytes;
+ newRequest->complete = 0;
+ newRequest->completionProc = sysexCompletionProc;
+ newRequest->completionRefCon = newRequest;
+
+ result = MIDISendSysex(newRequest);
+ if ( result != noErr ) {
+ free( newRequest );
+ errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations.";
+ error( RtMidiError::WARNING, errorString_ );
+ return;
+ }
+ return;
}
else if ( nBytes > 3 ) {
errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?";
diff --git a/doc/release.txt b/doc/release.txt
index 7eefe46..3d8b59a 100644
--- a/doc/release.txt
+++ b/doc/release.txt
@@ -13,6 +13,7 @@ v2.1.0: (?? 2014)
- added custom error hook that allows the client to capture an RtMidi error outside of the RtMidi code
- fix for portnames in Windows when UNICODE is defined
- added RtMidi::isPortOpen function
+- updated OS-X sysex sending mechanism (ptarabbia)
v2.0.1: (26 July 2012)
- small fixes for problems reported by Chris Arndt (scoping, preprocessor, and include)
diff --git a/tests/sysextest.cpp b/tests/sysextest.cpp
index 68b9a0d..39228ea 100644
--- a/tests/sysextest.cpp
+++ b/tests/sysextest.cpp
@@ -80,7 +80,7 @@ int main( int argc, char *argv[] )
midiout->sendMessage( &message );
SLEEP( 500 ); // pause a little
- // Create a long sysex messages of numbered bytes and send it out.
+ // Create a long sysex message of numbered bytes and send it out.
for ( int n=0; n<2; n++ ) {
message.clear();
message.push_back( 240 );