Fixed "FML" case: fall down here with an overflown SysEx..

Splitting larger incoming messages into smaller SysEx packets - using an RrtpMidi trick:
            //   first:  0xF0 .... 0xF0
            //   midlle: 0xF7 .... 0xF0
            //   last:   0xF7 .... 0xF7

see: https://tools.ietf.org/html/rfc4695#section-3.2

(Understanding this is not part of the original MIDI spec, but does allow for receiving very very large SysEx messages on a small footprint (does require some 'handy' parsing))

SysExMaxSize in Settings can be reduced significatly (16bytes works fine - pending use case)
This commit is contained in:
lathoub 2020-03-21 19:51:53 +01:00
parent e4ad19d40e
commit 874b44e6f3
1 changed files with 28 additions and 6 deletions

View File

@ -711,8 +711,8 @@ inline bool MidiInterface<Transport, Settings, Platform>::read(Channel inChannel
return false; return false;
handleNullVelocityNoteOnAsNoteOff(); handleNullVelocityNoteOnAsNoteOff();
const bool channelMatch = inputFilter(inChannel); const bool channelMatch = inputFilter(inChannel);
if (channelMatch) if (channelMatch)
launchCallback(); launchCallback();
@ -938,12 +938,34 @@ bool MidiInterface<Transport, Settings, Platform>::parse()
// Now we are going to check if we have reached the end of the message // Now we are going to check if we have reached the end of the message
if (mPendingMessageIndex >= (mPendingMessageExpectedLength - 1)) if (mPendingMessageIndex >= (mPendingMessageExpectedLength - 1))
{ {
// "FML" case: fall down here with an overflown SysEx.. // SysEx larger than the allocated buffer size,
// This means we received the last possible data byte that can fit // Split SysEx like so:
// the buffer. If this happens, try increasing MidiMessage::sSysExMaxSize. // first: 0xF0 .... 0xF0
if (mPendingMessage[0] == SystemExclusive) // midlle: 0xF7 .... 0xF0
// last: 0xF7 .... 0xF7
if ((mPendingMessage[0] == SystemExclusiveStart)
|| (mPendingMessage[0] == SystemExclusiveEnd))
{ {
resetInput(); auto lastByte = mMessage.sysexArray[DefaultSettings::SysExMaxSize - 1];
mMessage.sysexArray[DefaultSettings::SysExMaxSize - 1] = SystemExclusiveStart;
mMessage.type = SystemExclusive;
// Get length
mMessage.data1 = DefaultSettings::SysExMaxSize & 0xff; // LSB
mMessage.data2 = byte(DefaultSettings::SysExMaxSize >> 8); // MSB
mMessage.channel = 0;
mMessage.length = DefaultSettings::SysExMaxSize;
mMessage.valid = true;
// No need to check against the inputChannel,
// SysEx ignores input channel
launchCallback();
mMessage.sysexArray[0] = SystemExclusiveEnd;
mMessage.sysexArray[1] = lastByte;
mPendingMessageIndex = 2;
return false; return false;
} }