mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-22 01:34:21 +00:00
Midi parsing fix for embedded realtime messages, and CoreMidi fix for sending large packets.
This commit is contained in:
parent
cb77241d20
commit
a5a4e69f37
2 changed files with 69 additions and 24 deletions
|
|
@ -37,13 +37,14 @@ public:
|
|||
//==============================================================================
|
||||
MidiDataConcatenator (const int initialBufferSize)
|
||||
: pendingData ((size_t) initialBufferSize),
|
||||
pendingBytes (0), pendingDataTime (0)
|
||||
pendingBytes (0), runningStatus (0), pendingDataTime (0)
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
pendingBytes = 0;
|
||||
runningStatus = 0;
|
||||
pendingDataTime = 0;
|
||||
}
|
||||
|
||||
|
|
@ -57,18 +58,48 @@ public:
|
|||
if (pendingBytes > 0 || d[0] == 0xf0)
|
||||
{
|
||||
processSysex (d, numBytes, time, input, callback);
|
||||
runningStatus = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int used = 0;
|
||||
const MidiMessage m (d, numBytes, used, 0, time);
|
||||
int len = 0;
|
||||
uint8 data[3];
|
||||
|
||||
if (used <= 0)
|
||||
break; // malformed message..
|
||||
while (numBytes > 0)
|
||||
{
|
||||
// If there's a realtime message embedded in the middle of
|
||||
// the normal message, handle it now..
|
||||
if (*d >= 0xf8 && *d <= 0xfe)
|
||||
{
|
||||
const MidiMessage m (*d++, time);
|
||||
callback.handleIncomingMidiMessage (input, m);
|
||||
--numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len == 0 && *d < 0x80 && runningStatus >= 0x80)
|
||||
data[len++] = runningStatus;
|
||||
|
||||
callback.handleIncomingMidiMessage (input, m);
|
||||
numBytes -= used;
|
||||
d += used;
|
||||
data[len++] = *d++;
|
||||
--numBytes;
|
||||
|
||||
if (len >= MidiMessage::getMessageLengthFromFirstByte (data[0]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
int used = 0;
|
||||
const MidiMessage m (data, len, used, 0, time);
|
||||
|
||||
if (used <= 0)
|
||||
break; // malformed message..
|
||||
|
||||
jassert (used == len);
|
||||
callback.handleIncomingMidiMessage (input, m);
|
||||
runningStatus = data[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +164,7 @@ private:
|
|||
}
|
||||
|
||||
MemoryBlock pendingData;
|
||||
int pendingBytes;
|
||||
int pendingBytes, runningStatus;
|
||||
double pendingDataTime;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator);
|
||||
|
|
|
|||
|
|
@ -359,24 +359,27 @@ MidiOutput::~MidiOutput()
|
|||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
{
|
||||
CoreMidiHelpers::MidiPortAndEndpoint* const mpe = static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal);
|
||||
|
||||
#if JUCE_IOS
|
||||
const MIDITimeStamp timeStamp = mach_absolute_time();
|
||||
#else
|
||||
const MIDITimeStamp timeStamp = AudioGetCurrentHostTime();
|
||||
#endif
|
||||
|
||||
HeapBlock <MIDIPacketList> allocatedPackets;
|
||||
MIDIPacketList stackPacket;
|
||||
MIDIPacketList* packetToSend = &stackPacket;
|
||||
const size_t dataSize = (size_t) message.getRawDataSize();
|
||||
|
||||
if (message.isSysEx())
|
||||
{
|
||||
const int maxPacketSize = 256;
|
||||
int pos = 0, bytesLeft = message.getRawDataSize();
|
||||
int pos = 0, bytesLeft = (int) dataSize;
|
||||
const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize;
|
||||
HeapBlock <MIDIPacketList> packets;
|
||||
packets.malloc ((size_t) (32 * numPackets + message.getRawDataSize()), 1);
|
||||
packets->numPackets = (UInt32) numPackets;
|
||||
allocatedPackets.malloc ((size_t) (32 * numPackets + dataSize), 1);
|
||||
packetToSend = allocatedPackets;
|
||||
packetToSend->numPackets = (UInt32) numPackets;
|
||||
|
||||
MIDIPacket* p = packets->packet;
|
||||
MIDIPacket* p = packetToSend->packet;
|
||||
|
||||
for (int i = 0; i < numPackets; ++i)
|
||||
{
|
||||
|
|
@ -387,19 +390,30 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
|
|||
bytesLeft -= p->length;
|
||||
p = MIDIPacketNext (p);
|
||||
}
|
||||
}
|
||||
else if (dataSize < 65536) // max packet size
|
||||
{
|
||||
const size_t stackCapacity = sizeof (stackPacket.packet->data);
|
||||
|
||||
mpe->send (packets);
|
||||
if (dataSize > stackCapacity)
|
||||
{
|
||||
allocatedPackets.malloc ((sizeof (MIDIPacketList) - stackCapacity) + dataSize, 1);
|
||||
packetToSend = allocatedPackets;
|
||||
}
|
||||
|
||||
packetToSend->numPackets = 1;
|
||||
MIDIPacket& p = *(packetToSend->packet);
|
||||
p.timeStamp = timeStamp;
|
||||
p.length = (UInt16) dataSize;
|
||||
memcpy (p.data, message.getRawData(), dataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
MIDIPacketList packets;
|
||||
packets.numPackets = 1;
|
||||
packets.packet[0].timeStamp = timeStamp;
|
||||
packets.packet[0].length = (UInt16) message.getRawDataSize();
|
||||
*(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
|
||||
|
||||
mpe->send (&packets);
|
||||
jassertfalse; // packet too large to send!
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal)->send (packetToSend);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue