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:
parent
e4ad19d40e
commit
874b44e6f3
34
src/MIDI.hpp
34
src/MIDI.hpp
|
|
@ -711,8 +711,8 @@ inline bool MidiInterface<Transport, Settings, Platform>::read(Channel inChannel
|
|||
return false;
|
||||
|
||||
handleNullVelocityNoteOnAsNoteOff();
|
||||
|
||||
const bool channelMatch = inputFilter(inChannel);
|
||||
|
||||
if (channelMatch)
|
||||
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
|
||||
if (mPendingMessageIndex >= (mPendingMessageExpectedLength - 1))
|
||||
{
|
||||
// "FML" case: fall down here with an overflown SysEx..
|
||||
// This means we received the last possible data byte that can fit
|
||||
// the buffer. If this happens, try increasing MidiMessage::sSysExMaxSize.
|
||||
if (mPendingMessage[0] == SystemExclusive)
|
||||
// SysEx larger than the allocated buffer size,
|
||||
// Split SysEx like so:
|
||||
// first: 0xF0 .... 0xF0
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue