Update to RtMidi 1.0.8

git-svn-id: https://svn.code.sf.net/p/pianobooster/code/trunk@36 ba081f5d-443b-49a7-ac4b-446c3f91f371
This commit is contained in:
louisjb 2009-03-09 23:14:58 +00:00
parent a3ceb6ca71
commit 8f20ee0dae
2 changed files with 178 additions and 104 deletions

View File

@ -8,7 +8,7 @@
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
Copyright (c) 2003-2007 Gary P. Scavone
Copyright (c) 2003-2009 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.7
// RtMidi: Version 1.0.8
#include "RtMidi.h"
#include <sstream>
@ -69,9 +69,9 @@ void RtMidi :: error( RtError::Type type )
// Common RtMidiIn Definitions
//*********************************************************************//
RtMidiIn :: RtMidiIn() : RtMidi()
RtMidiIn :: RtMidiIn( const std::string clientName ) : RtMidi()
{
this->initialize();
this->initialize( clientName );
}
void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData )
@ -144,9 +144,9 @@ double RtMidiIn :: getMessage( std::vector<unsigned char> *message )
// Common RtMidiOut Definitions
//*********************************************************************//
RtMidiOut :: RtMidiOut() : RtMidi()
RtMidiOut :: RtMidiOut( const std::string clientName ) : RtMidi()
{
this->initialize();
this->initialize( clientName );
}
@ -187,20 +187,24 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
RtMidiIn::RtMidiInData *data = static_cast<RtMidiIn::RtMidiInData *> (procRef);
CoreMidiData *apiData = static_cast<CoreMidiData *> (data->apiData);
bool continueSysex = false;
unsigned char status;
unsigned short nBytes, iByte, size;
unsigned long long time;
RtMidiIn::MidiMessage message;
bool& continueSysex = data->continueSysex;
RtMidiIn::MidiMessage& message = data->message;
const MIDIPacket *packet = &list->packet[0];
for ( unsigned int i=0; i<list->numPackets; ++i ) {
// My interpretation of the CoreMIDI documentation: all message
// types, except sysex, are complete within a packet and there may
// be several of them in a single packet. Sysex messages can be
// broken across multiple packets but are bundled alone within a
// packet. I'm assuming that sysex messages, if segmented, must
// be complete within the same MIDIPacketList.
// broken across multiple packets and PacketLists but are bundled
// alone within each packet (these packets do not contain other
// message types). If sysex messages are split across multiple
// MIDIPacketLists, they must be handled by multiple calls to this
// function.
nBytes = packet->length;
if ( nBytes == 0 ) continue;
@ -220,12 +224,13 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
iByte = 0;
if ( continueSysex ) {
// 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.
for ( unsigned int j=0; j<nBytes; j++ )
message.bytes.push_back( packet->data[j] );
}
if ( packet->data[nBytes] == 0xF7 ) continueSysex = false;
continueSysex = packet->data[nBytes-1] != 0xF7;
if ( !continueSysex ) {
// If not a continuing sysex message, invoke the user callback function or queue the message.
if ( data->usingCallback && message.bytes.size() > 0 ) {
@ -259,7 +264,7 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
iByte = nBytes;
}
else size = nBytes - iByte;
if ( packet->data[nBytes] == 0xF7 ) continueSysex = false;
continueSysex = packet->data[nBytes-1] != 0xF7;
}
else if ( status < 0xF3 ) {
if ( status == 0xF1 && (data->ignoreFlags & 0x02) ) {
@ -311,11 +316,11 @@ void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef
}
}
void RtMidiIn :: initialize( void )
void RtMidiIn :: initialize( const std::string& clientName )
{
// Set up our client.
MIDIClientRef client;
OSStatus result = MIDIClientCreate( CFSTR("RtMidi Input Client"), NULL, NULL, &client );
OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
if ( result != noErr ) {
errorString_ = "RtMidiIn::initialize: error creating OS-X MIDI client object.";
error( RtError::DRIVER_ERROR );
@ -329,7 +334,7 @@ void RtMidiIn :: initialize( void )
inputData_.apiData = (void *) data;
}
void RtMidiIn :: openPort( unsigned int portNumber )
void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName )
{
if ( connected_ ) {
errorString_ = "RtMidiIn::openPort: a valid connection already exists!";
@ -352,7 +357,9 @@ void RtMidiIn :: openPort( unsigned int portNumber )
MIDIPortRef port;
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
OSStatus result = MIDIInputPortCreate( data->client, CFSTR("RtMidi MIDI Input Port"), midiInputCallback, (void *)&inputData_, &port );
OSStatus result = MIDIInputPortCreate( data->client,
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
midiInputCallback, (void *)&inputData_, &port );
if ( result != noErr ) {
MIDIClientDispose( data->client );
errorString_ = "RtMidiIn::openPort: error creating OS-X MIDI input port.";
@ -479,11 +486,11 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
return stringName;
}
void RtMidiOut :: initialize( void )
void RtMidiOut :: initialize( const std::string& clientName )
{
// Set up our client.
MIDIClientRef client;
OSStatus result = MIDIClientCreate( CFSTR("RtMidi Output Client"), NULL, NULL, &client );
OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
if ( result != noErr ) {
errorString_ = "RtMidiOut::initialize: error creating OS-X MIDI client object.";
error( RtError::DRIVER_ERROR );
@ -496,7 +503,7 @@ void RtMidiOut :: initialize( void )
apiData_ = (void *) data;
}
void RtMidiOut :: openPort( unsigned int portNumber )
void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName )
{
if ( connected_ ) {
errorString_ = "RtMidiOut::openPort: a valid connection already exists!";
@ -519,7 +526,9 @@ void RtMidiOut :: openPort( unsigned int portNumber )
MIDIPortRef port;
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
OSStatus result = MIDIOutputPortCreate( data->client, CFSTR("RtMidi Virtual MIDI Output Port"), &port );
OSStatus result = MIDIOutputPortCreate( data->client,
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
&port );
if ( result != noErr ) {
MIDIClientDispose( data->client );
errorString_ = "RtMidiOut::openPort: error creating OS-X MIDI output port.";
@ -588,33 +597,59 @@ RtMidiOut :: ~RtMidiOut()
void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
{
// The CoreMidi documentation indicates a maximum PackList size of
// 64K, so we may need to break long sysex messages into pieces and
// send via separate lists.
unsigned int nBytes = message->size();
// Pad the buffer for extra (unknown) structure data.
Byte buffer[nBytes+32];
MIDIPacketList *pktlist = (MIDIPacketList *) buffer;
MIDIPacket *curPacket = MIDIPacketListInit( pktlist );
MIDITimeStamp timeStamp = 0;
curPacket = MIDIPacketListAdd( pktlist, sizeof(buffer), curPacket, timeStamp, nBytes, &message->at(0) );
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
// Send to any destinations that may have connected to us.
OSStatus result;
if ( data->endpoint ) {
result = MIDIReceived( data->endpoint, pktlist );
if ( result != noErr ) {
errorString_ = "RtMidiOut::sendMessage: error sending MIDI to virtual destinations.";
error( RtError::WARNING );
}
if ( nBytes == 0 ) {
errorString_ = "RtMidiOut::sendMessage: no data in message argument!";
error( RtError::WARNING );
return;
}
// And send to an explicit destination port if we're connected.
if ( connected_ ) {
result = MIDISend( data->port, data->destinationId, pktlist );
if ( result != noErr ) {
errorString_ = "RtMidiOut::sendMessage: error sending MIDI message to port.";
error( RtError::WARNING );
if ( nBytes > 3 && ( message->at(0) != 0xF0 ) ) {
errorString_ = "RtMidiOut::sendMessage: message format problem ... not sysex but > 3 bytes?";
error( RtError::WARNING );
return;
}
unsigned int packetBytes, bytesLeft = nBytes;
unsigned int messageIndex = 0;
MIDITimeStamp timeStamp = 0;
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
while ( bytesLeft > 0 ) {
packetBytes = ( bytesLeft > 32736 ) ? 32736 : bytesLeft;
Byte buffer[packetBytes + 32]; // extra memory for other structure variables
MIDIPacketList *packetList = (MIDIPacketList *) buffer;
MIDIPacket *curPacket = MIDIPacketListInit( packetList );
curPacket = MIDIPacketListAdd( packetList, packetBytes+32, curPacket, timeStamp, packetBytes, (const Byte *) &message->at( messageIndex ) );
if ( !curPacket ) {
errorString_ = "RtMidiOut::sendMessage: could not allocate packet list";
error( RtError::DRIVER_ERROR );
}
messageIndex += packetBytes;
bytesLeft -= packetBytes;
// Send to any destinations that may have connected to us.
OSStatus result;
if ( data->endpoint ) {
result = MIDIReceived( data->endpoint, packetList );
if ( result != noErr ) {
errorString_ = "RtMidiOut::sendMessage: error sending MIDI to virtual destinations.";
error( RtError::WARNING );
}
}
// And send to an explicit destination port if we're connected.
if ( connected_ ) {
result = MIDISend( data->port, data->destinationId, packetList );
if ( result != noErr ) {
errorString_ = "RtMidiOut::sendMessage: error sending MIDI message to port.";
error( RtError::WARNING );
}
}
}
}
@ -713,7 +748,9 @@ extern "C" void *alsaMidiHandler( void *ptr )
// This is a bit weird, but we now have to decode an ALSA MIDI
// event (back) into MIDI bytes. We'll ignore non-MIDI types.
message.bytes.clear();
if ( !continueSysex )
message.bytes.clear();
switch ( ev->type ) {
case SND_SEQ_EVENT_PORT_SUBSCRIBED:
@ -723,8 +760,15 @@ extern "C" void *alsaMidiHandler( void *ptr )
break;
case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
#if defined(__RTMIDI_DEBUG__)
std::cerr << "RtMidiIn::alsaMidiHandler: port connection has closed!\n";
data->doInput = false;
// FIXME: this is called for all unsubscribe events, even ones
//not related to this particular connection. As it stands, I
//see no data provided in the "source" and "dest" fields so
//there is nothing we can do about this at this time.
// std::cout << "sender = " << ev->source.client << ", dest = " << ev->dest.port << std::endl;
#endif
//data->doInput = false;
break;
case SND_SEQ_EVENT_QFRAME: // MIDI time code
@ -768,7 +812,7 @@ extern "C" void *alsaMidiHandler( void *ptr )
else
message.bytes.insert( message.bytes.end(), buffer, &buffer[nBytes] );
continueSysex = ( ev->type == SND_SEQ_EVENT_SYSEX && message.bytes.back() != 0xF7 );
continueSysex = ( ( ev->type == SND_SEQ_EVENT_SYSEX ) && ( message.bytes.back() != 0xF7 ) );
if ( continueSysex )
break;
@ -794,7 +838,7 @@ extern "C" void *alsaMidiHandler( void *ptr )
snd_seq_free_event(ev);
if ( message.bytes.size() == 0 ) continue;
if ( data->usingCallback ) {
if ( data->usingCallback && !continueSysex ) {
RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
callback( message.timeStamp, &message.bytes, data->userData );
}
@ -813,10 +857,10 @@ extern "C" void *alsaMidiHandler( void *ptr )
return 0;
}
void RtMidiIn :: initialize( void )
void RtMidiIn :: initialize( const std::string& clientName )
{
// Set up the ALSA sequencer client.
snd_seq_t *seq;
snd_seq_t *seq;
int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
if ( result < 0 ) {
errorString_ = "RtMidiIn::initialize: error creating ALSA sequencer input client object.";
@ -824,7 +868,7 @@ void RtMidiIn :: initialize( void )
}
// Set client name.
snd_seq_set_client_name(seq, "RtMidi Input Client");
snd_seq_set_client_name( seq, clientName.c_str() );
// Save our api-specific connection information.
AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
@ -860,7 +904,10 @@ unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int
snd_seq_port_info_set_client( pinfo, client );
snd_seq_port_info_set_port( pinfo, -1 );
while ( snd_seq_query_next_port( seq, pinfo ) >= 0 ) {
if ( !PORT_TYPE( pinfo, type ) ) continue;
unsigned int atyp = snd_seq_port_info_get_type( pinfo );
if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue;
unsigned int caps = snd_seq_port_info_get_capability( pinfo );
if ( ( caps & type ) != type ) continue;
if ( count == portNumber ) return 1;
count++;
}
@ -871,7 +918,7 @@ unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int
return 0;
}
void RtMidiIn :: openPort( unsigned int portNumber )
void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName )
{
if ( connected_ ) {
errorString_ = "RtMidiIn::openPort: a valid connection already exists!";
@ -913,7 +960,7 @@ void RtMidiIn :: openPort( unsigned int portNumber )
snd_seq_port_info_set_timestamping(pinfo, 1);
snd_seq_port_info_set_timestamp_real(pinfo, 1);
snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id);
snd_seq_port_info_set_name(pinfo, "RtMidi Input");
snd_seq_port_info_set_name(pinfo, portName.c_str() );
data->vport = snd_seq_create_port(data->seq, pinfo);
if ( data->vport < 0 ) {
@ -1049,12 +1096,20 @@ unsigned int RtMidiIn :: getPortCount()
std::string RtMidiIn :: getPortName( unsigned int portNumber )
{
snd_seq_port_info_t *pinfo;
snd_seq_port_info_alloca( &pinfo );
snd_seq_client_info_t *cinfo;
snd_seq_port_info_t *pinfo;
snd_seq_client_info_alloca( &cinfo );
snd_seq_port_info_alloca( &pinfo );
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) ) {
std::string stringName = std::string( snd_seq_port_info_get_name( pinfo ) );
int cnum = snd_seq_port_info_get_client( pinfo );
snd_seq_get_any_client_info( data->seq, cnum, cinfo );
std::ostringstream os;
os << snd_seq_client_info_get_name( cinfo );
os << ":";
os << snd_seq_port_info_get_port( pinfo );
std::string stringName = os.str();
return stringName;
}
@ -1080,12 +1135,20 @@ unsigned int RtMidiOut :: getPortCount()
std::string RtMidiOut :: getPortName( unsigned int portNumber )
{
snd_seq_port_info_t *pinfo;
snd_seq_port_info_alloca( &pinfo );
snd_seq_client_info_t *cinfo;
snd_seq_port_info_t *pinfo;
snd_seq_client_info_alloca( &cinfo );
snd_seq_port_info_alloca( &pinfo );
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) ) {
std::string stringName = std::string( snd_seq_port_info_get_name( pinfo ) );
int cnum = snd_seq_port_info_get_client(pinfo);
snd_seq_get_any_client_info( data->seq, cnum, cinfo );
std::ostringstream os;
os << snd_seq_client_info_get_name(cinfo);
os << ":";
os << snd_seq_port_info_get_port(pinfo);
std::string stringName = os.str();
return stringName;
}
@ -1095,18 +1158,18 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
return 0;
}
void RtMidiOut :: initialize( void )
void RtMidiOut :: initialize( const std::string& clientName )
{
// Set up the ALSA sequencer client.
snd_seq_t *seq;
int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0);
snd_seq_t *seq;
int result = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK );
if ( result < 0 ) {
errorString_ = "RtMidiOut::initialize: error creating ALSA sequencer client object.";
error( RtError::DRIVER_ERROR );
}
// Set client name.
snd_seq_set_client_name(seq, "RtMidi Output Client");
snd_seq_set_client_name( seq, clientName.c_str() );
// Save our api-specific connection information.
AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
@ -1131,7 +1194,7 @@ void RtMidiOut :: initialize( void )
apiData_ = (void *) data;
}
void RtMidiOut :: openPort( unsigned int portNumber )
void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName )
{
if ( connected_ ) {
errorString_ = "RtMidiOut::openPort: a valid connection already exists!";
@ -1161,7 +1224,7 @@ void RtMidiOut :: openPort( unsigned int portNumber )
sender.client = snd_seq_client_id( data->seq );
if ( data->vport < 0 ) {
data->vport = snd_seq_create_simple_port( data->seq, "RtMidi Output",
data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(),
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_MIDI_GENERIC );
if ( data->vport < 0 ) {
@ -1423,7 +1486,7 @@ extern "C" void *irixMidiHandler( void *ptr )
return 0;
}
void RtMidiIn :: initialize( void )
void RtMidiIn :: initialize( const std::string& /*clientName*/ )
{
// Initialize the Irix MIDI system. At the moment, we will not
// worry about a return value of zero (ports) because there is a
@ -1436,7 +1499,7 @@ void RtMidiIn :: initialize( void )
inputData_.apiData = (void *) data;
}
void RtMidiIn :: openPort( unsigned int portNumber )
void RtMidiIn :: openPort( unsigned int portNumber, const std::string /*portName*/ )
{
if ( connected_ ) {
errorString_ = "RtMidiIn::openPort: a valid connection already exists!";
@ -1564,7 +1627,7 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
return stringName;
}
void RtMidiOut :: initialize( void )
void RtMidiOut :: initialize( const std::string& /*clientName*/ )
{
// Initialize the Irix MIDI system. At the moment, we will not
// worry about a return value of zero (ports) because there is a
@ -1576,7 +1639,7 @@ void RtMidiOut :: initialize( void )
apiData_ = (void *) data;
}
void RtMidiOut :: openPort( unsigned int portNumber )
void RtMidiOut :: openPort( unsigned int portNumber, const std::string /*portName*/ )
{
if ( connected_ ) {
errorString_ = "RtMidiOut::openPort: a valid connection already exists!";
@ -1754,21 +1817,31 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
unsigned char *ptr = (unsigned char *) &midiMessage;
for ( int i=0; i<nBytes; i++ ) apiData->message.bytes.push_back( *ptr++ );
}
else if ( !(data->ignoreFlags & 0x01) ) {
// Sysex message and we're not ignoring it
MIDIHDR *sysex = ( MIDIHDR *) midiMessage;
for ( int i=0; i<(int)sysex->dwBytesRecorded; i++ )
apiData->message.bytes.push_back( sysex->lpData[i] );
else { // Sysex message ( MIM_LONGDATA )
MIDIHDR *sysex = ( MIDIHDR *) midiMessage;
if ( !( data->ignoreFlags & 0x01 ) ) {
// Sysex message and we're not ignoring it
for ( int i=0; i<(int)sysex->dwBytesRecorded; i++ )
apiData->message.bytes.push_back( sysex->lpData[i] );
}
// When the callback has to be unaffected (application closes),
// it seems WinMM calls it with an empty sysex to de-queue the buffer
// If the buffer is requeued afer that message, the PC suddenly reboots
// after one or two minutes (JB).
// The WinMM API requires that the sysex buffer be requeued after
// input of each sysex message. Even if we are ignoring sysex
// messages, we still need to requeue the buffer in case the user
// decides to not ignore sysex messages in the future. However,
// it seems that WinMM calls this function with an empty sysex
// 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 ( result != MMSYSERR_NOERROR )
std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n";
if ( data->ignoreFlags & 0x01 ) return;
}
else return;
}
if ( data->usingCallback ) {
@ -1783,13 +1856,11 @@ static void CALLBACK midiInputCallback( HMIDIOUT hmin,
std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
}
// Clear the vector for the next input message. Note that doing
// this here allows our code to work for sysex messages which are
// segmented across multiple buffers.
// Clear the vector for the next input message.
apiData->message.bytes.clear();
}
void RtMidiIn :: initialize( void )
void RtMidiIn :: initialize( const std::string& /*clientName*/ )
{
// We'll issue a warning here if no devices are available but not
// throw an error since the user can plugin something later.
@ -1806,7 +1877,7 @@ void RtMidiIn :: initialize( void )
data->message.bytes.clear(); // needs to be empty for first input message
}
void RtMidiIn :: openPort( unsigned int portNumber )
void RtMidiIn :: openPort( unsigned int portNumber, const std::string /*portName*/ )
{
if ( connected_ ) {
errorString_ = "RtMidiIn::openPort: a valid connection already exists!";
@ -1840,8 +1911,8 @@ void RtMidiIn :: openPort( unsigned int portNumber )
// Allocate and init the sysex buffer.
data->sysexBuffer = (MIDIHDR*) new char[ sizeof(MIDIHDR) ];
data->sysexBuffer->lpData = new char[1024];
data->sysexBuffer->dwBufferLength = 1024;
data->sysexBuffer->lpData = new char[ RT_SYSEX_BUFFER_SIZE ];
data->sysexBuffer->dwBufferLength = RT_SYSEX_BUFFER_SIZE;
data->sysexBuffer->dwFlags = 0;
result = midiInPrepareHeader( data->inHandle, data->sysexBuffer, sizeof(MIDIHDR) );
@ -1970,7 +2041,7 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
return stringName;
}
void RtMidiOut :: initialize( void )
void RtMidiOut :: initialize( const std::string& /*clientName*/ )
{
// We'll issue a warning here if no devices are available but not
// throw an error since the user can plug something in later.
@ -1985,7 +2056,7 @@ void RtMidiOut :: initialize( void )
apiData_ = (void *) data;
}
void RtMidiOut :: openPort( unsigned int portNumber )
void RtMidiOut :: openPort( unsigned int portNumber, const std::string /*portName*/ )
{
if ( connected_ ) {
errorString_ = "RtMidiOut::openPort: a valid connection already exists!";

View File

@ -8,7 +8,7 @@
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
Copyright (c) 2003-2007 Gary P. Scavone
Copyright (c) 2003-2009 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.7
// RtMidi: Version 1.0.8
#ifndef RTMIDI_H
#define RTMIDI_H
@ -48,7 +48,7 @@ class RtMidi
public:
//! Pure virtual openPort() function.
virtual void openPort( unsigned int portNumber = 0 ) = 0;
virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
//! Pure virtual openVirtualPort() function.
virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
@ -91,7 +91,7 @@ class RtMidi
to open a virtual input port to which other MIDI software clients
can connect.
by Gary P. Scavone, 2003-2004.
by Gary P. Scavone, 2003-2008.
*/
/**********************************************************************/
@ -105,11 +105,11 @@ class RtMidiIn : public RtMidi
//! User callback function type definition.
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
//! Default constructor.
//! Default constructor that allows an optional client name.
/*!
An exception will be thrown if a MIDI system initialization error occurs.
*/
RtMidiIn();
RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client") );
//! If a MIDI connection is still open, it will be closed by the destructor.
~RtMidiIn();
@ -119,7 +119,7 @@ class RtMidiIn : public RtMidi
An optional port number greater than 0 can be specified.
Otherwise, the default or first port found is opened.
*/
void openPort( unsigned int portNumber = 0 );
void openPort( unsigned int portNumber = 0, const std::string Portname = std::string( "RtMidi Input" ) );
//! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only).
/*!
@ -200,6 +200,7 @@ class RtMidiIn : public RtMidi
// the MIDI input handling function or thread.
struct RtMidiInData {
std::queue<MidiMessage> queue;
MidiMessage message;
unsigned int queueLimit;
unsigned char ignoreFlags;
bool doInput;
@ -208,16 +209,18 @@ class RtMidiIn : public RtMidi
bool usingCallback;
void *userCallback;
void *userData;
bool continueSysex;
// Default constructor.
RtMidiInData()
: queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
apiData(0), usingCallback(false), userCallback(0), userData(0) {}
apiData(0), usingCallback(false), userCallback(0), userData(0),
continueSysex(false) {}
};
private:
void initialize( void );
void initialize( const std::string& clientName );
RtMidiInData inputData_;
};
@ -232,7 +235,7 @@ class RtMidiIn : public RtMidi
the connection. Create multiple instances of this class to
connect to more than one MIDI device at the same time.
by Gary P. Scavone, 2003-2004.
by Gary P. Scavone, 2003-2008.
*/
/**********************************************************************/
@ -240,11 +243,11 @@ class RtMidiOut : public RtMidi
{
public:
//! Default constructor.
//! Default constructor that allows an optional client name.
/*!
An exception will be thrown if a MIDI system initialization error occurs.
*/
RtMidiOut();
RtMidiOut( const std::string clientName = std::string( "RtMidi Output Client" ) );
//! The destructor closes any open MIDI connections.
~RtMidiOut();
@ -256,7 +259,7 @@ class RtMidiOut : public RtMidi
exception is thrown if an error occurs while attempting to make
the port connection.
*/
void openPort( unsigned int portNumber = 0 );
void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
//! Close an open MIDI connection (if one exists).
void closePort();
@ -290,7 +293,7 @@ class RtMidiOut : public RtMidi
private:
void initialize( void );
void initialize( const std::string& clientName );
};
#endif