просто начал использовать RtMIDI в Xcode для прототипа некоторых MIDI-материалов. Он отлично работает, но попал в камнем преткновения.
Используя пример midiout.cpp без изменения чего-либо:
Просмотрев код библиотеки, все MIDI-события, кроме syssex, отправляются (в OSX) с помощью вызова os MIDIReceived. События Sysex отправляются с использованием MIDISendSysex. Это так и должно быть.
Теперь никаких ошибок не возникает, все выполняется, как и должно быть, вызов MIDISendSysex не терпит неудачу - просто, чтобы никакие события сисекса не попадали в пункт назначения. Они просто исчезают в черной дыре!
Кто-нибудь еще сталкивается с этим или имеет какую-либо помощь, предложения, обходные пути?
Благодаря,
(Xcode 4.6.2, OSX 10.9.1, используя MIDIMonitor и MIDIPipe для отслеживания трафика на MIDI-портах, оба показывают одинаковые результаты событий sysex, не прибывающих на виртуальные порты из midiout.cpp)
Хорошо, здесь маршрутизация sendMessage, выполняющая фактическую отправку:
void MidiOutCore :: sendMessage( std::vector *message )
{
// ------------------------------------------------------------------------
// We use the MIDISendSysex() function to asynchronously send sysex
// messages. Otherwise, we use a single CoreMidi MIDIPacket.
// ------------------------------------------------------------------------
// error handling code removed for brevity
MIDITimeStamp timeStamp = AudioGetCurrentHostTime();
CoreMidiData *data = static_cast (apiData_);
OSStatus result;
// ------------------------------------------------------------------------
// IF EVENT IS SYSEX
// ------------------------------------------------------------------------
if ( message->at(0) == 0xF0 ) { // sysex start byte
while ( sysexBuffer != 0 ) usleep( 1000 ); // sleep 1 ms
sysexBuffer = new char[nBytes];
// Copy data to buffer.
for ( unsigned int i=0; iat(i);
// build sysex request
data->sysexreq.destination = data->destinationId; // destinaiondId is valid endpointref
data->sysexreq.data = (Byte *)sysexBuffer;
data->sysexreq.bytesToSend = nBytes;
data->sysexreq.complete = 0;
data->sysexreq.completionProc = sysexCompletionProc;
data->sysexreq.completionRefCon = &(data->sysexreq);
// send the data
// this works when we are connected to a 'real' MIDI port/device, but fails on a virtual port
// destinationId is an endpointref and valid and id is good
// tried to use data->endpoint (also an endpointref with id) but doesn't send either
result = MIDISendSysex( &(data->sysexreq) );
return;
}
// ------------------------------------------------------------------------
// IF EVENT IS NOT SYSEX
// ------------------------------------------------------------------------
MIDIPacketList packetList;
MIDIPacket *packet = MIDIPacketListInit( &packetList );
packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) );
// Send to any destinations that may have connected to us.
// this sends to virtual MIDI ports
if ( data->endpoint ) {
result = MIDIReceived( data->endpoint, &packetList );
if ( result != noErr ) {
errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations.";
RtMidi::error( RtError::WARNING, errorString_ );
}
}
// And send to an explicit destination port if we're connected.
// this sends to regular real MIDI devices we are connected to, not virtual ports
if ( connected_ ) {
result = MIDISend( data->port, data->destinationId, &packetList );
if ( result != noErr ) {
errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port.";
RtMidi::error( RtError::WARNING, errorString_ );
}
}
}
Последующая заметка - это была ошибка в RTMidi, которая должна быть исправлена в следующей версии. Это связано с тем, что в CoreMIDI вызов MIDISendSysex() не отправляется на виртуальные порты, он будет работать только на реальных портах.
Я обновил локальную копию RTMIDI для обработки событий sysex, используя MIDIReceived(), как рекомендовано в этом потоке в списке рассылки CoreAdio: http://lists.apple.com/archives/coreaudio-api/2006/Jan/msg00236.html
Теперь он отправляет sysex в виртуальные порты и ведет себя так, как ожидалось.