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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue