|
|
|
@@ -36,7 +36,7 @@ |
|
|
|
*/ |
|
|
|
/**********************************************************************/ |
|
|
|
|
|
|
|
// RtMidi: Version 2.0.0 |
|
|
|
// RtMidi: Version 2.0.1 |
|
|
|
|
|
|
|
#include "RtMidi.h" |
|
|
|
#include <sstream> |
|
|
|
@@ -571,7 +571,7 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string portName |
|
|
|
|
|
|
|
MIDIPortRef port; |
|
|
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_); |
|
|
|
OSStatus result = MIDIInputPortCreate( data->client, |
|
|
|
OSStatus result = MIDIInputPortCreate( data->client, |
|
|
|
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), |
|
|
|
midiInputCallback, (void *)&inputData_, &port ); |
|
|
|
if ( result != noErr ) { |
|
|
|
@@ -756,7 +756,7 @@ static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) |
|
|
|
if ( anyStrings ) |
|
|
|
return result; |
|
|
|
|
|
|
|
// Here, either the endpoint had no connections, or we failed to obtain names |
|
|
|
// Here, either the endpoint had no connections, or we failed to obtain names |
|
|
|
return EndpointName( endpoint, false ); |
|
|
|
} |
|
|
|
|
|
|
|
@@ -848,7 +848,7 @@ std::string MidiOutCore :: getPortName( unsigned int portNumber ) |
|
|
|
nameRef = ConnectedEndpointName(portRef); |
|
|
|
CFStringGetCString( nameRef, name, sizeof(name), 0); |
|
|
|
CFRelease( nameRef ); |
|
|
|
|
|
|
|
|
|
|
|
return stringName = name; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -875,7 +875,7 @@ void MidiOutCore :: openPort( unsigned int portNumber, const std::string portNam |
|
|
|
|
|
|
|
MIDIPortRef port; |
|
|
|
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_); |
|
|
|
OSStatus result = MIDIOutputPortCreate( data->client, |
|
|
|
OSStatus result = MIDIOutputPortCreate( data->client, |
|
|
|
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), |
|
|
|
&port ); |
|
|
|
if ( result != noErr ) { |
|
|
|
@@ -947,7 +947,7 @@ void MidiOutCore :: sendMessage( std::vector<unsigned char> *message ) |
|
|
|
// messages. Otherwise, we use a single CoreMidi MIDIPacket. |
|
|
|
unsigned int nBytes = message->size(); |
|
|
|
if ( nBytes == 0 ) { |
|
|
|
errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; |
|
|
|
errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; |
|
|
|
RtMidi::error( RtError::WARNING, errorString_ ); |
|
|
|
return; |
|
|
|
} |
|
|
|
@@ -995,7 +995,7 @@ void MidiOutCore :: sendMessage( std::vector<unsigned char> *message ) |
|
|
|
MIDIPacket *packet = MIDIPacketListInit( &packetList ); |
|
|
|
packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); |
|
|
|
if ( !packet ) { |
|
|
|
errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; |
|
|
|
errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; |
|
|
|
RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1185,13 +1185,13 @@ extern "C" void *alsaMidiHandler( void *ptr ) |
|
|
|
doDecode = false; |
|
|
|
switch ( ev->type ) { |
|
|
|
|
|
|
|
case SND_SEQ_EVENT_PORT_SUBSCRIBED: |
|
|
|
case SND_SEQ_EVENT_PORT_SUBSCRIBED: |
|
|
|
#if defined(__RTMIDI_DEBUG__) |
|
|
|
std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n"; |
|
|
|
#endif |
|
|
|
break; |
|
|
|
|
|
|
|
case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: |
|
|
|
case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: |
|
|
|
#if defined(__RTMIDI_DEBUG__) |
|
|
|
std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n"; |
|
|
|
std::cout << "sender = " << (int) ev->data.connect.sender.client << ":" |
|
|
|
@@ -1214,7 +1214,7 @@ extern "C" void *alsaMidiHandler( void *ptr ) |
|
|
|
if ( !( data->ignoreFlags & 0x04 ) ) doDecode = true; |
|
|
|
break; |
|
|
|
|
|
|
|
case SND_SEQ_EVENT_SYSEX: |
|
|
|
case SND_SEQ_EVENT_SYSEX: |
|
|
|
if ( (data->ignoreFlags & 0x01) ) break; |
|
|
|
if ( ev->data.ext.len > apiData->bufferSize ) { |
|
|
|
apiData->bufferSize = ev->data.ext.len; |
|
|
|
@@ -1481,12 +1481,12 @@ void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName |
|
|
|
snd_seq_port_info_set_midi_channels(pinfo, 16); |
|
|
|
#ifndef AVOID_TIMESTAMPING |
|
|
|
snd_seq_port_info_set_timestamping(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_real(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_real(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); |
|
|
|
#endif |
|
|
|
snd_seq_port_info_set_name(pinfo, portName.c_str() ); |
|
|
|
data->vport = snd_seq_create_port(data->seq, pinfo); |
|
|
|
|
|
|
|
|
|
|
|
if ( data->vport < 0 ) { |
|
|
|
errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; |
|
|
|
RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); |
|
|
|
@@ -1546,15 +1546,15 @@ void MidiInAlsa :: openVirtualPort( std::string portName ) |
|
|
|
snd_seq_port_info_t *pinfo; |
|
|
|
snd_seq_port_info_alloca( &pinfo ); |
|
|
|
snd_seq_port_info_set_capability( pinfo, |
|
|
|
SND_SEQ_PORT_CAP_WRITE | |
|
|
|
SND_SEQ_PORT_CAP_SUBS_WRITE ); |
|
|
|
SND_SEQ_PORT_CAP_WRITE | |
|
|
|
SND_SEQ_PORT_CAP_SUBS_WRITE ); |
|
|
|
snd_seq_port_info_set_type( pinfo, |
|
|
|
SND_SEQ_PORT_TYPE_MIDI_GENERIC | |
|
|
|
SND_SEQ_PORT_TYPE_APPLICATION ); |
|
|
|
SND_SEQ_PORT_TYPE_MIDI_GENERIC | |
|
|
|
SND_SEQ_PORT_TYPE_APPLICATION ); |
|
|
|
snd_seq_port_info_set_midi_channels(pinfo, 16); |
|
|
|
#ifndef AVOID_TIMESTAMPING |
|
|
|
snd_seq_port_info_set_timestamping(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_real(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_real(pinfo, 1); |
|
|
|
snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); |
|
|
|
#endif |
|
|
|
snd_seq_port_info_set_name(pinfo, portName.c_str()); |
|
|
|
@@ -1657,7 +1657,7 @@ void MidiOutAlsa :: initialize( const std::string& clientName ) |
|
|
|
s_seq = NULL; |
|
|
|
errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object."; |
|
|
|
RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Save our api-specific connection information. |
|
|
|
AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; |
|
|
|
@@ -1685,8 +1685,8 @@ void MidiOutAlsa :: initialize( const std::string& clientName ) |
|
|
|
|
|
|
|
unsigned int MidiOutAlsa :: getPortCount() |
|
|
|
{ |
|
|
|
snd_seq_port_info_t *pinfo; |
|
|
|
snd_seq_port_info_alloca( &pinfo ); |
|
|
|
snd_seq_port_info_t *pinfo; |
|
|
|
snd_seq_port_info_alloca( &pinfo ); |
|
|
|
|
|
|
|
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_); |
|
|
|
return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 ); |
|
|
|
@@ -1733,8 +1733,8 @@ void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portNam |
|
|
|
RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); |
|
|
|
} |
|
|
|
|
|
|
|
snd_seq_port_info_t *pinfo; |
|
|
|
snd_seq_port_info_alloca( &pinfo ); |
|
|
|
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 ) { |
|
|
|
@@ -1887,7 +1887,7 @@ struct WinMidiData { |
|
|
|
//*********************************************************************// |
|
|
|
|
|
|
|
static void CALLBACK midiInputCallback( HMIDIIN hmin, |
|
|
|
UINT inputStatus, |
|
|
|
UINT inputStatus, |
|
|
|
DWORD_PTR instancePtr, |
|
|
|
DWORD_PTR midiMessage, |
|
|
|
DWORD timestamp ) |
|
|
|
@@ -1937,8 +1937,8 @@ static void CALLBACK midiInputCallback( HMIDIIN hmin, |
|
|
|
for ( int i=0; i<nBytes; ++i ) apiData->message.bytes.push_back( *ptr++ ); |
|
|
|
} |
|
|
|
else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) |
|
|
|
MIDIHDR *sysex = ( MIDIHDR *) midiMessage; |
|
|
|
if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { |
|
|
|
MIDIHDR *sysex = ( MIDIHDR *) midiMessage; |
|
|
|
if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { |
|
|
|
// 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] ); |
|
|
|
@@ -1952,7 +1952,7 @@ static void CALLBACK midiInputCallback( HMIDIIN 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[sysex->dwUser]->dwBytesRecorded > 0 ) { |
|
|
|
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 ) |
|
|
|
@@ -2140,7 +2140,7 @@ std::string MidiInWinMM :: getPortName( unsigned int portNumber ) |
|
|
|
stringName = std::string( deviceCaps.szPname ); |
|
|
|
#endif |
|
|
|
|
|
|
|
// Next lines added to add the portNumber to the name so that |
|
|
|
// Next lines added to add the portNumber to the name so that |
|
|
|
// the device's names are sure to be listed with individual names |
|
|
|
// even when they have the same brand name |
|
|
|
std::ostringstream os; |
|
|
|
@@ -2298,7 +2298,7 @@ void MidiOutWinMM :: sendMessage( std::vector<unsigned char> *message ) |
|
|
|
sysex.lpData = (LPSTR) buffer; |
|
|
|
sysex.dwBufferLength = nBytes; |
|
|
|
sysex.dwFlags = 0; |
|
|
|
result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); |
|
|
|
result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); |
|
|
|
if ( result != MMSYSERR_NOERROR ) { |
|
|
|
free( buffer ); |
|
|
|
errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; |
|
|
|
@@ -2366,8 +2366,8 @@ void MidiOutWinMM :: sendMessage( std::vector<unsigned char> *message ) |
|
|
|
#include <setupapi.h> |
|
|
|
#include <mmsystem.h> |
|
|
|
|
|
|
|
#include "include/ks.h" |
|
|
|
#include "include/ksmedia.h" |
|
|
|
#include "ks.h" |
|
|
|
#include "ksmedia.h" |
|
|
|
|
|
|
|
#define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } |
|
|
|
|
|
|
|
@@ -3614,6 +3614,8 @@ void MidiOutJack :: initialize( const std::string& clientName ) |
|
|
|
{ |
|
|
|
JackMidiData *data = new JackMidiData; |
|
|
|
|
|
|
|
data->port = NULL; |
|
|
|
|
|
|
|
// Initialize JACK client |
|
|
|
if (( data->client = jack_client_open( clientName.c_str(), JackNullOption, NULL )) == 0) { |
|
|
|
errorString_ = "MidiOutJack::initialize: JACK server not running?"; |
|
|
|
@@ -3626,8 +3628,6 @@ void MidiOutJack :: initialize( const std::string& clientName ) |
|
|
|
data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); |
|
|
|
jack_activate( data->client ); |
|
|
|
|
|
|
|
data->port = NULL; |
|
|
|
|
|
|
|
apiData_ = (void *) data; |
|
|
|
} |
|
|
|
|