mirror of
https://github.com/thestk/stk
synced 2026-01-14 21:41:53 +00:00
Version 4.3.0
This commit is contained in:
committed by
Stephen Sinclair
parent
2cbce2d8bd
commit
27d9b79dc7
@@ -35,7 +35,7 @@
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
// RtMidi: Version 1.0.4, 14 October 2005
|
||||
// RtMidi: Version 1.0.5, in development
|
||||
|
||||
#include "RtMidi.h"
|
||||
#include <sstream>
|
||||
@@ -383,13 +383,15 @@ void RtMidiIn :: openPort( unsigned int portNumber )
|
||||
connected_ = true;
|
||||
}
|
||||
|
||||
void RtMidiIn :: openVirtualPort()
|
||||
void RtMidiIn :: openVirtualPort( const std::string portName )
|
||||
{
|
||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||
|
||||
// Create a virtual MIDI input destination.
|
||||
MIDIEndpointRef endpoint;
|
||||
OSStatus result = MIDIDestinationCreate( data->client, CFSTR("RtMidi Input"), midiInputCallback, (void *)&inputData_, &endpoint );
|
||||
OSStatus result = MIDIDestinationCreate( data->client,
|
||||
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
|
||||
midiInputCallback, (void *)&inputData_, &endpoint );
|
||||
if ( result != noErr ) {
|
||||
errorString_ = "RtMidiIn::openVirtualPort: error creating virtual OS-X MIDI destination.";
|
||||
error( RtError::DRIVER_ERROR );
|
||||
@@ -548,7 +550,7 @@ void RtMidiOut :: closePort( void )
|
||||
}
|
||||
}
|
||||
|
||||
void RtMidiOut :: openVirtualPort()
|
||||
void RtMidiOut :: openVirtualPort( std::string portName )
|
||||
{
|
||||
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
|
||||
|
||||
@@ -560,7 +562,9 @@ void RtMidiOut :: openVirtualPort()
|
||||
|
||||
// Create a virtual MIDI output source.
|
||||
MIDIEndpointRef endpoint;
|
||||
OSStatus result = MIDISourceCreate( data->client, CFSTR("RtMidi Output"), &endpoint );
|
||||
OSStatus result = MIDISourceCreate( data->client,
|
||||
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
|
||||
&endpoint );
|
||||
if ( result != noErr ) {
|
||||
errorString_ = "RtMidiOut::initialize: error creating OS-X virtual MIDI source.";
|
||||
error( RtError::DRIVER_ERROR );
|
||||
@@ -957,7 +961,7 @@ void RtMidiIn :: openPort( unsigned int portNumber )
|
||||
connected_ = true;
|
||||
}
|
||||
|
||||
void RtMidiIn :: openVirtualPort()
|
||||
void RtMidiIn :: openVirtualPort( std::string portName )
|
||||
{
|
||||
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||
if ( data->vport < 0 ) {
|
||||
@@ -973,7 +977,7 @@ void RtMidiIn :: openVirtualPort()
|
||||
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 ) {
|
||||
@@ -1195,11 +1199,11 @@ void RtMidiOut :: closePort( void )
|
||||
}
|
||||
}
|
||||
|
||||
void RtMidiOut :: openVirtualPort()
|
||||
void RtMidiOut :: openVirtualPort( std::string portName )
|
||||
{
|
||||
AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
|
||||
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 );
|
||||
|
||||
@@ -1484,7 +1488,7 @@ void RtMidiIn :: openPort( unsigned int portNumber )
|
||||
connected_ = true;
|
||||
}
|
||||
|
||||
void RtMidiIn :: openVirtualPort()
|
||||
void RtMidiIn :: openVirtualPort( std::string portName )
|
||||
{
|
||||
// This function cannot be implemented for the Irix MIDI API.
|
||||
errorString_ = "RtMidiIn::openVirtualPort: cannot be implemented in Irix MIDI API!";
|
||||
@@ -1617,7 +1621,7 @@ void RtMidiOut :: closePort( void )
|
||||
}
|
||||
}
|
||||
|
||||
void RtMidiOut :: openVirtualPort()
|
||||
void RtMidiOut :: openVirtualPort( std::string portName )
|
||||
{
|
||||
// This function cannot be implemented for the Irix MIDI API.
|
||||
errorString_ = "RtMidiOut::openVirtualPort: cannot be implemented in Irix MIDI API!";
|
||||
@@ -1676,6 +1680,8 @@ void RtMidiOut :: sendMessage( std::vector<unsigned char> *message )
|
||||
// API information deciphered from:
|
||||
// - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp
|
||||
|
||||
// Thanks to Jean-Baptiste Berruchon for the sysex code.
|
||||
|
||||
#if defined(__WINDOWS_MM__)
|
||||
|
||||
// The Windows MM API is based on the use of a callback function for
|
||||
@@ -1693,8 +1699,11 @@ struct WinMidiData {
|
||||
HMIDIOUT outHandle; // Handle to Midi Output Device
|
||||
DWORD lastTime;
|
||||
RtMidiIn::MidiMessage message;
|
||||
LPMIDIHDR sysexBuffer;
|
||||
};
|
||||
|
||||
#define RT_SYSEX_BUFFER_SIZE 1024
|
||||
|
||||
//*********************************************************************//
|
||||
// API: Windows MM
|
||||
// Class Definitions: RtMidiIn
|
||||
@@ -1748,11 +1757,21 @@ 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 { // Sysex message
|
||||
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] );
|
||||
if ( apiData->message.bytes.back() != 0xF7 ) return;
|
||||
|
||||
// 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).
|
||||
if ( apiData->sysexBuffer->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->usingCallback ) {
|
||||
@@ -1822,6 +1841,27 @@ void RtMidiIn :: openPort( unsigned int portNumber )
|
||||
error( RtError::DRIVER_ERROR );
|
||||
}
|
||||
|
||||
// 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->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 );
|
||||
}
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
result = midiInStart( data->inHandle );
|
||||
if ( result != MMSYSERR_NOERROR ) {
|
||||
midiInClose( data->inHandle );
|
||||
@@ -1832,7 +1872,7 @@ void RtMidiIn :: openPort( unsigned int portNumber )
|
||||
connected_ = true;
|
||||
}
|
||||
|
||||
void RtMidiIn :: openVirtualPort()
|
||||
void RtMidiIn :: openVirtualPort( std::string portName )
|
||||
{
|
||||
// This function cannot be implemented for the Windows MM MIDI API.
|
||||
errorString_ = "RtMidiIn::openVirtualPort: cannot be implemented in Windows MM MIDI API!";
|
||||
@@ -1845,6 +1885,16 @@ void RtMidiIn :: closePort( void )
|
||||
WinMidiData *data = static_cast<WinMidiData *> (apiData_);
|
||||
midiInReset( 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 );
|
||||
}
|
||||
|
||||
midiInClose( data->inHandle );
|
||||
connected_ = false;
|
||||
}
|
||||
@@ -1878,7 +1928,14 @@ std::string RtMidiIn :: getPortName( unsigned int portNumber )
|
||||
MIDIINCAPS deviceCaps;
|
||||
MMRESULT result = midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS));
|
||||
|
||||
std::string stringName = std::string( deviceCaps.szPname );
|
||||
// For some reason, we need to copy character by character with
|
||||
// UNICODE (thanks to Eduardo Coutinho!).
|
||||
//std::string stringName = std::string( deviceCaps.szPname );
|
||||
char nameString[MAXPNAMELEN];
|
||||
for( int i=0; i<MAXPNAMELEN; i++ )
|
||||
nameString[i] = (char)( deviceCaps.szPname[i] );
|
||||
|
||||
std::string stringName( nameString );
|
||||
return stringName;
|
||||
}
|
||||
|
||||
@@ -1905,7 +1962,14 @@ std::string RtMidiOut :: getPortName( unsigned int portNumber )
|
||||
MIDIOUTCAPS deviceCaps;
|
||||
MMRESULT result = midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS));
|
||||
|
||||
std::string stringName = std::string( deviceCaps.szPname );
|
||||
// For some reason, we need to copy character by character with
|
||||
// UNICODE (thanks to Eduardo Coutinho!).
|
||||
//std::string stringName = std::string( deviceCaps.szPname );
|
||||
char nameString[MAXPNAMELEN];
|
||||
for( int i=0; i<MAXPNAMELEN; i++ )
|
||||
nameString[i] = (char)( deviceCaps.szPname[i] );
|
||||
|
||||
std::string stringName( nameString );
|
||||
return stringName;
|
||||
}
|
||||
|
||||
@@ -1969,7 +2033,7 @@ void RtMidiOut :: closePort( void )
|
||||
}
|
||||
}
|
||||
|
||||
void RtMidiOut :: openVirtualPort()
|
||||
void RtMidiOut :: openVirtualPort( std::string portName )
|
||||
{
|
||||
// This function cannot be implemented for the Windows MM MIDI API.
|
||||
errorString_ = "RtMidiOut::openVirtualPort: cannot be implemented in Windows MM MIDI API!";
|
||||
|
||||
Reference in New Issue
Block a user