summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2013-12-29 22:05:48 -0800
committerGary Scavone <gary@music.mcgill.ca>2013-12-29 22:05:48 -0800
commita0d187b872eefe9efe1fa55dc1e804ddb78ecc76 (patch)
tree85331e01d14fc7dfa31fd181dd8e875b55465d2b
parented94023c333c63a8b5713da1c5746ebbbe5b665b (diff)
Some error printing changes, removed ALSA global sequencer objects because they were not thread safe, various other updates suggested by Martin Koegler
-rw-r--r--Makefile.in2
-rw-r--r--RtMidi.cpp214
-rw-r--r--RtMidi.h20
-rw-r--r--tests/cmidiin.cpp2
-rw-r--r--tests/cmidiin.dsp4
-rw-r--r--tests/midiout.cpp4
-rw-r--r--tests/midiout.dsp4
-rw-r--r--tests/midiprobe.cpp2
-rw-r--r--tests/midiprobe.dsp4
-rw-r--r--tests/qmidiin.cpp4
-rw-r--r--tests/qmidiin.dsp4
-rw-r--r--tests/sysextest.cpp4
-rw-r--r--tests/sysextest.dsp4
13 files changed, 136 insertions, 136 deletions
diff --git a/Makefile.in b/Makefile.in
index 55857f0..9fac5f6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -66,7 +66,7 @@ distclean:
$(RM) -f $(LIBRARIES) @sharedname@ $(SHARED)*
$(RM) -f $(OBJECTS)
$(RM) -f *~
- $(RM) -rf config.log config.status autom4te.cache Makefile rtmidi-config
+ $(RM) -rf config.log config.status autom4te.cache Makefile rtmidi-config $(LIBNAME).pc
cd tests && $(MAKE) distclean
strip :
diff --git a/RtMidi.cpp b/RtMidi.cpp
index a9999c2..c31754a 100644
--- a/RtMidi.cpp
+++ b/RtMidi.cpp
@@ -36,8 +36,6 @@
*/
/**********************************************************************/
-// RtMidi: Version 2.1.0
-
#include "RtMidi.h"
#include <sstream>
@@ -45,6 +43,11 @@
// RtMidi Definitions
//*********************************************************************//
+std::string RtMidi :: getVersion( void ) throw()
+{
+ return std::string( RTMIDI_VERSION );
+}
+
void RtMidi :: getCompiledApi( std::vector<RtMidi::Api> &apis ) throw()
{
apis.clear();
@@ -71,7 +74,7 @@ void RtMidi :: getCompiledApi( std::vector<RtMidi::Api> &apis ) throw()
#endif
}
-void RtMidi :: error( RtMidiError::Type type, std::string errorString )
+void RtMidi :: error( RtMidiError::Type type, std::string &errorString )
{
if (type == RtMidiError::WARNING) {
std::cerr << '\n' << errorString << "\n\n";
@@ -134,7 +137,8 @@ RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string clientName, unsigned in
// No compiled support for specified API value. Issue a debug
// warning and continue as if no API was specified.
- RtMidi::error( RtMidiError::WARNING, "RtMidiIn: no compiled support for specified API argument!" );
+ std::string errormsg = "RtMidiIn: no compiled support for specified API argument!";
+ RtMidi::error( RtMidiError::WARNING, errormsg );
}
// Iterate through the compiled APIs and return as soon as we find
@@ -152,12 +156,14 @@ RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string clientName, unsigned in
// definition __RTMIDI_DUMMY__ is automatically defined if no
// API-specific definitions are passed to the compiler. But just in
// case something weird happens, we'll print out an error message.
- RtMidi::error( RtMidiError::WARNING, "RtMidiIn: no compiled API support found ... critical error!!" );
+ std::string errormsg = "RtMidiIn: no compiled API support found ... critical error!!";
+ RtMidi::error( RtMidiError::UNSPECIFIED, errormsg );
}
RtMidiIn :: ~RtMidiIn() throw()
{
- delete rtapi_;
+ if ( rtapi_ )
+ delete rtapi_;
}
@@ -208,7 +214,8 @@ RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string clientName )
// No compiled support for specified API value. Issue a debug
// warning and continue as if no API was specified.
- RtMidi::error( RtMidiError::WARNING, "RtMidiOut: no compiled support for specified API argument!" );
+ std::string errormsg = "RtMidiOut: no compiled support for specified API argument!";
+ RtMidi::error( RtMidiError::WARNING, errormsg );
}
// Iterate through the compiled APIs and return as soon as we find
@@ -226,12 +233,14 @@ RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string clientName )
// definition __RTMIDI_DUMMY__ is automatically defined if no
// API-specific definitions are passed to the compiler. But just in
// case something weird happens, we'll print out an error message.
- RtMidi::error( RtMidiError::WARNING, "RtMidiOut: no compiled API support found ... critical error!!" );
+ std::string errormsg = "RtMidiOut: no compiled API support found ... critical error!!";
+ RtMidi::error( RtMidiError::UNSPECIFIED, errormsg );
}
RtMidiOut :: ~RtMidiOut() throw()
{
- delete rtapi_;
+ if ( rtapi_ )
+ delete rtapi_;
}
//*********************************************************************//
@@ -363,7 +372,7 @@ struct CoreMidiData {
// Class Definitions: MidiInCore
//*********************************************************************//
-void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef )
+static void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef )
{
MidiInApi::RtMidiInData *data = static_cast<MidiInApi::RtMidiInData *> (procRef);
CoreMidiData *apiData = static_cast<CoreMidiData *> (data->apiData);
@@ -563,8 +572,8 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string portName
RtMidi::error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
}
- std::ostringstream ost;
if ( portNumber >= nSrc ) {
+ std::ostringstream ost;
ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -653,7 +662,7 @@ CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
CFRelease( str );
}
- MIDIEntityRef entity = NULL;
+ MIDIEntityRef entity = 0;
MIDIEndpointGetEntity( endpoint, &entity );
if ( entity == 0 )
// probably virtual
@@ -766,16 +775,15 @@ std::string MidiInCore :: getPortName( unsigned int portNumber )
{
CFStringRef nameRef;
MIDIEndpointRef portRef;
- std::ostringstream ost;
char name[128];
std::string stringName;
CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
if ( portNumber >= MIDIGetNumberOfSources() ) {
+ std::ostringstream ost;
ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::WARNING, errorString_ );
- //RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
return stringName;
}
@@ -836,17 +844,16 @@ std::string MidiOutCore :: getPortName( unsigned int portNumber )
{
CFStringRef nameRef;
MIDIEndpointRef portRef;
- std::ostringstream ost;
char name[128];
std::string stringName;
CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
if ( portNumber >= MIDIGetNumberOfDestinations() ) {
+ std::ostringstream ost;
ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::WARNING, errorString_ );
return stringName;
- //RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
}
portRef = MIDIGetDestination( portNumber );
@@ -872,8 +879,8 @@ void MidiOutCore :: openPort( unsigned int portNumber, const std::string portNam
RtMidi::error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
}
- std::ostringstream ost;
if ( portNumber >= nDest ) {
+ std::ostringstream ost;
ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -938,9 +945,9 @@ void MidiOutCore :: openVirtualPort( std::string portName )
data->endpoint = endpoint;
}
-char *sysexBuffer = 0;
+static char *sysexBuffer = 0;
-void sysexCompletionProc( MIDISysexSendRequest * sreq )
+static void sysexCompletionProc( MIDISysexSendRequest * sreq )
{
//std::cout << "Completed SysEx send\n";
delete sysexBuffer;
@@ -1053,17 +1060,6 @@ void MidiOutCore :: sendMessage( std::vector<unsigned char> *message )
// ALSA header file.
#include <alsa/asoundlib.h>
-// Global sequencer instance created when first In/Out object is
-// created, then destroyed when last In/Out is deleted.
-static snd_seq_t *s_seq = NULL;
-
-// Variable to keep track of how many ports are open.
-static unsigned int s_numPorts = 0;
-
-// The client name to use when creating the sequencer, which is
-// currently set on the first call to createSequencer.
-static std::string s_clientName = "RtMidi Client";
-
// A structure to hold variables related to the ALSA API
// implementation.
struct AlsaMidiData {
@@ -1083,44 +1079,12 @@ struct AlsaMidiData {
#define PORT_TYPE( pinfo, bits ) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
-snd_seq_t* createSequencer( const std::string& clientName )
-{
- // Set up the ALSA sequencer client.
- if ( s_seq == NULL ) {
- int result = snd_seq_open(&s_seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
- if ( result < 0 ) {
- s_seq = NULL;
- }
- else {
- // Set client name, use current name if given string is empty.
- if ( clientName != "" ) {
- s_clientName = clientName;
- }
- snd_seq_set_client_name( s_seq, s_clientName.c_str() );
- }
- }
-
- // Increment port count.
- s_numPorts++;
-
- return s_seq;
-}
-
-void freeSequencer ( void )
-{
- s_numPorts--;
- if ( s_numPorts == 0 && s_seq != NULL ) {
- snd_seq_close( s_seq );
- s_seq = NULL;
- }
-}
-
//*********************************************************************//
// API: LINUX ALSA
// Class Definitions: MidiInAlsa
//*********************************************************************//
-extern "C" void *alsaMidiHandler( void *ptr )
+static void *alsaMidiHandler( void *ptr )
{
MidiInApi::RtMidiInData *data = static_cast<MidiInApi::RtMidiInData *> (ptr);
AlsaMidiData *apiData = static_cast<AlsaMidiData *> (data->apiData);
@@ -1334,19 +1298,23 @@ MidiInAlsa :: ~MidiInAlsa()
#ifndef AVOID_TIMESTAMPING
snd_seq_free_queue( data->seq, data->queue_id );
#endif
- freeSequencer();
+ snd_seq_close( data->seq );
delete data;
}
void MidiInAlsa :: initialize( const std::string& clientName )
{
- snd_seq_t* seq = createSequencer( clientName );
- if ( seq == NULL ) {
- s_seq = NULL;
+ // Set up the ALSA sequencer client.
+ snd_seq_t *seq;
+ int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
+ if ( result < 0 ) {
errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object.";
RtMidi::error( RtMidiError::DRIVER_ERROR, errorString_ );
}
+ // Set client name.
+ snd_seq_set_client_name( seq, clientName.c_str() );
+
// Save our api-specific connection information.
AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
data->seq = seq;
@@ -1367,7 +1335,7 @@ void MidiInAlsa :: initialize( const std::string& clientName )
// Create the input queue
#ifndef AVOID_TIMESTAMPING
- data->queue_id = snd_seq_alloc_named_queue(s_seq, "RtMidi Queue");
+ data->queue_id = snd_seq_alloc_named_queue(seq, "RtMidi Queue");
// Set arbitrary tempo (mm=100) and resolution (240)
snd_seq_queue_tempo_t *qtempo;
snd_seq_queue_tempo_alloca(&qtempo);
@@ -1443,7 +1411,6 @@ std::string MidiInAlsa :: getPortName( unsigned int portNumber )
errorString_ = "MidiInAlsa::getPortName: error looking for port name!";
RtMidi::error( RtMidiError::WARNING, errorString_ );
return stringName;
- //RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
}
void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName )
@@ -1462,9 +1429,9 @@ void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName
snd_seq_port_info_t *pinfo;
snd_seq_port_info_alloca( &pinfo );
- std::ostringstream ost;
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) {
+ std::ostringstream ost;
ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -1652,19 +1619,23 @@ MidiOutAlsa :: ~MidiOutAlsa()
if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport );
if ( data->coder ) snd_midi_event_free( data->coder );
if ( data->buffer ) free( data->buffer );
- freeSequencer();
+ snd_seq_close( data->seq );
delete data;
}
void MidiOutAlsa :: initialize( const std::string& clientName )
{
- snd_seq_t* seq = createSequencer( clientName );
- if ( seq == NULL ) {
- s_seq = NULL;
+ // Set up the ALSA sequencer client.
+ snd_seq_t *seq;
+ int result1 = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK );
+ if ( result1 < 0 ) {
errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object.";
RtMidi::error( RtMidiError::DRIVER_ERROR, errorString_ );
}
+ // Set client name.
+ snd_seq_set_client_name( seq, clientName.c_str() );
+
// Save our api-specific connection information.
AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
data->seq = seq;
@@ -1712,6 +1683,8 @@ std::string MidiOutAlsa :: getPortName( unsigned int portNumber )
snd_seq_get_any_client_info( data->seq, cnum, cinfo );
std::ostringstream os;
os << snd_seq_client_info_get_name(cinfo);
+ os << " "; // These lines added to make sure devices are listed
+ os << snd_seq_port_info_get_client( pinfo ); // with full portnames added to ensure individual device names
os << ":";
os << snd_seq_port_info_get_port(pinfo);
stringName = os.str();
@@ -1741,9 +1714,9 @@ void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portNam
snd_seq_port_info_t *pinfo;
snd_seq_port_info_alloca( &pinfo );
- std::ostringstream ost;
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) {
+ std::ostringstream ost;
ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -2035,8 +2008,8 @@ void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portN
RtMidi::error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
}
- std::ostringstream ost;
if ( portNumber >= nDevices ) {
+ std::ostringstream ost;
ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -2130,7 +2103,6 @@ std::string MidiInWinMM :: getPortName( unsigned int portNumber )
std::ostringstream ost;
ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
- //RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
RtMidi::error( RtMidiError::WARNING, errorString_ );
return stringName;
}
@@ -2205,7 +2177,6 @@ std::string MidiOutWinMM :: getPortName( unsigned int portNumber )
std::ostringstream ost;
ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
- //RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
RtMidi::error( RtMidiError::WARNING, errorString_ );
return stringName;
}
@@ -2238,8 +2209,8 @@ void MidiOutWinMM :: openPort( unsigned int portNumber, const std::string /*port
RtMidi::error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
}
- std::ostringstream ost;
if ( portNumber >= nDevices ) {
+ std::ostringstream ost;
ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::INVALID_PARAMETER, errorString_ );
@@ -3054,7 +3025,7 @@ struct WindowsKsData
// Class Definitions: MidiInWinKS
// *********************************************************************//
-DWORD WINAPI midiKsInputThread(VOID* pUser)
+static DWORD WINAPI midiKsInputThread(VOID* pUser)
{
MidiInApi::RtMidiInData* data = static_cast<MidiInApi::RtMidiInData*>(pUser);
WindowsKsData* apiData = static_cast<WindowsKsData*>(data->apiData);
@@ -3410,7 +3381,7 @@ struct JackMidiData {
// Class Definitions: MidiInJack
//*********************************************************************//
-int jackProcessIn( jack_nframes_t nframes, void *arg )
+static int jackProcessIn( jack_nframes_t nframes, void *arg )
{
JackMidiData *jData = (JackMidiData *) arg;
MidiInApi :: RtMidiInData *rtData = jData->rtMidiIn;
@@ -3423,13 +3394,13 @@ int jackProcessIn( jack_nframes_t nframes, void *arg )
// We have midi events in buffer
int evCount = jack_midi_get_event_count( buff );
- if ( evCount > 0 ) {
+ for (int j = 0; j < evCount; j++) {
MidiInApi::MidiMessage message;
message.bytes.clear();
- jack_midi_event_get( &event, buff, 0 );
+ jack_midi_event_get( &event, buff, j );
- for (unsigned int i = 0; i < event.size; i++ )
+ for ( unsigned int i = 0; i < event.size; i++ )
message.bytes.push_back( event.buffer[i] );
// Compute the delta time.
@@ -3473,16 +3444,27 @@ void MidiInJack :: initialize( const std::string& clientName )
JackMidiData *data = new JackMidiData;
apiData_ = (void *) data;
+ data->rtMidiIn = &inputData_;
+ data->port = NULL;
+ data->client = NULL;
+ this->clientName = clientName;
+
+ connect();
+}
+
+void MidiInJack :: connect()
+{
+ JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ if ( data->client )
+ return;
+
// Initialize JACK client
- if (( data->client = jack_client_open( clientName.c_str(), JackNullOption, NULL )) == 0) {
+ if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) {
errorString_ = "MidiInJack::initialize: JACK server not running?";
- RtMidi::error( RtMidiError::DRIVER_ERROR, errorString_ );
+ RtMidi::error( RtError::WARNING, errorString_ );
return;
}
- data->rtMidiIn = &inputData_;
- data->port = NULL;
-
jack_set_process_callback( data->client, jackProcessIn, data );
jack_activate( data->client );
}
@@ -3492,13 +3474,17 @@ MidiInJack :: ~MidiInJack()
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
closePort();
- jack_client_close( data->client );
+ if ( data->client )
+ jack_client_close( data->client );
+ delete data;
}
void MidiInJack :: openPort( unsigned int portNumber, const std::string portName )
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
+
// Creating new port
if ( data->port == NULL)
data->port = jack_port_register( data->client, portName.c_str(),
@@ -3518,6 +3504,7 @@ void MidiInJack :: openVirtualPort( const std::string portName )
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
if ( data->port == NULL )
data->port = jack_port_register( data->client, portName.c_str(),
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 );
@@ -3532,6 +3519,9 @@ unsigned int MidiInJack :: getPortCount()
{
int count = 0;
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
+ if ( !data->client )
+ return 0;
// List of available ports
const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput );
@@ -3548,9 +3538,10 @@ unsigned int MidiInJack :: getPortCount()
std::string MidiInJack :: getPortName( unsigned int portNumber )
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
- std::ostringstream ost;
std::string retStr("");
+ connect();
+
// List of available ports
const char **ports = jack_get_ports( data->client, NULL,
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput );
@@ -3563,6 +3554,7 @@ std::string MidiInJack :: getPortName( unsigned int portNumber )
}
if ( ports[portNumber] == NULL ) {
+ std::ostringstream ost;
ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::WARNING, errorString_ );
@@ -3589,7 +3581,7 @@ void MidiInJack :: closePort()
//*********************************************************************//
// Jack process callback
-int jackProcessOut( jack_nframes_t nframes, void *arg )
+static int jackProcessOut( jack_nframes_t nframes, void *arg )
{
JackMidiData *data = (JackMidiData *) arg;
jack_midi_data_t *midiData;
@@ -3619,13 +3611,25 @@ MidiOutJack :: MidiOutJack( const std::string clientName ) : MidiOutApi()
void MidiOutJack :: initialize( const std::string& clientName )
{
JackMidiData *data = new JackMidiData;
+ apiData_ = (void *) data;
data->port = NULL;
+ data->client = NULL;
+ this->clientName = clientName;
+
+ connect();
+}
+
+void MidiOutJack :: connect()
+{
+ JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ if ( data->client )
+ return;
// Initialize JACK client
- if (( data->client = jack_client_open( clientName.c_str(), JackNullOption, NULL )) == 0) {
+ if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) {
errorString_ = "MidiOutJack::initialize: JACK server not running?";
- RtMidi::error( RtMidiError::DRIVER_ERROR, errorString_ );
+ RtMidi::error( RtMidiError::WARNING, errorString_ );
return;
}
@@ -3633,8 +3637,6 @@ void MidiOutJack :: initialize( const std::string& clientName )
data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE );
data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE );
jack_activate( data->client );
-
- apiData_ = (void *) data;
}
MidiOutJack :: ~MidiOutJack()
@@ -3642,10 +3644,12 @@ MidiOutJack :: ~MidiOutJack()
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
closePort();
- // Cleanup
- jack_client_close( data->client );
- jack_ringbuffer_free( data->buffSize );
- jack_ringbuffer_free( data->buffMessage );
+ if ( data->client ) {
+ // Cleanup
+ jack_client_close( data->client );
+ jack_ringbuffer_free( data->buffSize );
+ jack_ringbuffer_free( data->buffMessage );
+ }
delete data;
}
@@ -3654,6 +3658,8 @@ void MidiOutJack :: openPort( unsigned int portNumber, const std::string portNam
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
+
// Creating new port
if ( data->port == NULL )
data->port = jack_port_register( data->client, portName.c_str(),
@@ -3673,6 +3679,7 @@ void MidiOutJack :: openVirtualPort( const std::string portName )
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
if ( data->port == NULL )
data->port = jack_port_register( data->client, portName.c_str(),
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 );
@@ -3687,6 +3694,9 @@ unsigned int MidiOutJack :: getPortCount()
{
int count = 0;
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+ connect();
+ if ( !data->client )
+ return 0;
// List of available ports
const char **ports = jack_get_ports( data->client, NULL,
@@ -3704,9 +3714,10 @@ unsigned int MidiOutJack :: getPortCount()
std::string MidiOutJack :: getPortName( unsigned int portNumber )
{
JackMidiData *data = static_cast<JackMidiData *> (apiData_);
- std::ostringstream ost;
std::string retStr("");
+ connect();
+
// List of available ports
const char **ports = jack_get_ports( data->client, NULL,
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput );
@@ -3719,6 +3730,7 @@ std::string MidiOutJack :: getPortName( unsigned int portNumber )
}
if ( ports[portNumber] == NULL) {
+ std::ostringstream ost;
ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
RtMidi::error( RtMidiError::WARNING, errorString_ );
diff --git a/RtMidi.h b/RtMidi.h
index cb039c8..26f5936 100644
--- a/RtMidi.h
+++ b/RtMidi.h
@@ -40,11 +40,11 @@
\file RtMidi.h
*/
-// RtMidi: Version 2.1.0
-
#ifndef RTMIDI_H
#define RTMIDI_H
+#define RTMIDI_VERSION "2.1.0pre"
+
#include <exception>
#include <iostream>
#include <string>
@@ -55,9 +55,8 @@
\brief Exception handling class for RtMidi.
The RtMidiError class is quite simple but it does allow errors to be
- "caught" by RtMidiError::Type. See the RtAudio and RtMidi
- documentation to know which methods can throw an RtMidiError.
-
+ "caught" by RtMidiError::Type. See the RtMidi documentation to know
+ which methods can throw an RtMidiError.
*/
/************************************************************************/
@@ -117,6 +116,9 @@ class RtMidi
RTMIDI_DUMMY /*!< A compilable but non-functional API. */
};
+ //! A static function to determine the current RtMidi version.
+ static std::string getVersion( void ) throw();
+
//! A static function to determine the available compiled MIDI APIs.
/*!
The values returned in the std::vector can be compared against
@@ -141,7 +143,7 @@ class RtMidi
virtual void closePort( void ) = 0;
//! A basic error reporting function for RtMidi classes.
- static void error( RtMidiError::Type type, std::string errorString );
+ static void error( RtMidiError::Type type, std::string &errorString );
protected:
@@ -520,6 +522,9 @@ class MidiInCore: public MidiInApi
std::string getPortName( unsigned int portNumber );
protected:
+ std::string clientName;
+
+ void connect( void );
void initialize( const std::string& clientName );
};
@@ -537,6 +542,9 @@ class MidiOutCore: public MidiOutApi
void sendMessage( std::vector<unsigned char> *message );
protected:
+ std::string clientName;
+
+ void connect( void );
void initialize( const std::string& clientName );
};
diff --git a/tests/cmidiin.cpp b/tests/cmidiin.cpp
index ad6cbd5..5aa4053 100644
--- a/tests/cmidiin.cpp
+++ b/tests/cmidiin.cpp
@@ -60,7 +60,7 @@ int main( int argc, char *argv[] )
char input;
std::cin.get(input);
- } catch ( RtError &error ) {
+ } catch ( RtMidiError &error ) {
error.printMessage();
}
diff --git a/tests/cmidiin.dsp b/tests/cmidiin.dsp
index cacda20..55fcbe6 100644
--- a/tests/cmidiin.dsp
+++ b/tests/cmidiin.dsp
@@ -99,10 +99,6 @@ SOURCE=..\RtMidi.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\RtError.h
-# End Source File
-# Begin Source File
-
SOURCE=..\RtMidi.h
# End Source File
# End Group
diff --git a/tests/midiout.cpp b/tests/midiout.cpp
index 4da65c1..0a9b9fd 100644
--- a/tests/midiout.cpp
+++ b/tests/midiout.cpp
@@ -33,7 +33,7 @@ int main( int argc, char *argv[] )
try {
midiout = new RtMidiOut();
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
exit( EXIT_FAILURE );
}
@@ -42,7 +42,7 @@ int main( int argc, char *argv[] )
try {
if ( chooseMidiPort( midiout ) == false ) goto cleanup;
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
goto cleanup;
}
diff --git a/tests/midiout.dsp b/tests/midiout.dsp
index 3f9480f..48e5811 100644
--- a/tests/midiout.dsp
+++ b/tests/midiout.dsp
@@ -99,10 +99,6 @@ SOURCE=..\RtMidi.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\RtError.h
-# End Source File
-# Begin Source File
-
SOURCE=..\RtMidi.h
# End Source File
# End Group
diff --git a/tests/midiprobe.cpp b/tests/midiprobe.cpp
index 7a7452e..6576e15 100644
--- a/tests/midiprobe.cpp
+++ b/tests/midiprobe.cpp
@@ -61,7 +61,7 @@ int main()
}
std::cout << std::endl;
- } catch ( RtError &error ) {
+ } catch ( RtMidiError &error ) {
error.printMessage();
}
diff --git a/tests/midiprobe.dsp b/tests/midiprobe.dsp
index 0f79fce..6a5eeaa 100644
--- a/tests/midiprobe.dsp
+++ b/tests/midiprobe.dsp
@@ -99,10 +99,6 @@ SOURCE=..\RtMidi.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\RtError.h
-# End Source File
-# Begin Source File
-
SOURCE=..\RtMidi.h
# End Source File
# End Group
diff --git a/tests/qmidiin.cpp b/tests/qmidiin.cpp
index de8337e..2adc03d 100644
--- a/tests/qmidiin.cpp
+++ b/tests/qmidiin.cpp
@@ -46,7 +46,7 @@ int main( int argc, char *argv[] )
try {
midiin = new RtMidiIn();
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
exit( EXIT_FAILURE );
}
@@ -64,7 +64,7 @@ int main( int argc, char *argv[] )
try {
midiin->openPort( port );
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
goto cleanup;
}
diff --git a/tests/qmidiin.dsp b/tests/qmidiin.dsp
index 9b66f7e..77f4818 100644
--- a/tests/qmidiin.dsp
+++ b/tests/qmidiin.dsp
@@ -99,10 +99,6 @@ SOURCE=..\RtMidi.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\RtError.h
-# End Source File
-# Begin Source File
-
SOURCE=..\RtMidi.h
# End Source File
# End Group
diff --git a/tests/sysextest.cpp b/tests/sysextest.cpp
index a11ec16..68b9a0d 100644
--- a/tests/sysextest.cpp
+++ b/tests/sysextest.cpp
@@ -56,7 +56,7 @@ int main( int argc, char *argv[] )
midiout = new RtMidiOut();
midiin = new RtMidiIn();
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
goto cleanup;
}
@@ -69,7 +69,7 @@ int main( int argc, char *argv[] )
if ( chooseMidiPort( midiin ) == false ) goto cleanup;
if ( chooseMidiPort( midiout ) == false ) goto cleanup;
}
- catch ( RtError &error ) {
+ catch ( RtMidiError &error ) {
error.printMessage();
goto cleanup;
}
diff --git a/tests/sysextest.dsp b/tests/sysextest.dsp
index 84ce289..0af5bf3 100644
--- a/tests/sysextest.dsp
+++ b/tests/sysextest.dsp
@@ -99,10 +99,6 @@ SOURCE=.\sysextest.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\RtError.h
-# End Source File
-# Begin Source File
-
SOURCE=..\RtMidi.h
# End Source File
# End Group