Skip to content

Commit 92a8931

Browse files
committed
Update MIDI.hpp
Fixed formatting
1 parent 00c2dc0 commit 92a8931

File tree

1 file changed

+182
-181
lines changed

1 file changed

+182
-181
lines changed

src/MIDI.hpp

Lines changed: 182 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -828,198 +828,199 @@ inline bool MidiInterface<Transport, Settings, Platform>::read(Channel inChannel
828828

829829
// Private method: MIDI parser
830830
template<class Transport, class Settings, class Platform>
831-
bool MidiInterface<Transport, Settings, Platform>::parse() {
832-
833-
if (mTransport.available() == 0)
834-
return false;
835-
836-
mLastError &= ~(1UL << ErrorParse); // Clear ErrorParse bit
837-
/*Possible Errors:
838-
> SysEx Stop byte received with no pending SysEx Start.
839-
> Unsupported Status byte.
840-
> Data received without a valid Status byte or Running Status.
841-
> Warning SysEx split warning.
842-
.... could potentially add an error for when SysEx is aborted due to receiving a new non-realtime status byte.
843-
*/
844-
845-
const byte extracted = mTransport.read();
846-
847-
if (extracted >= 0x80) {
848-
// Lets try get a valid Status byte. Non-realtime status overides any current Status
849-
const MidiType pendingType = getTypeFromStatusByte(extracted);
850-
switch (pendingType) {
851-
// Realtime
852-
case Start:
853-
case Continue:
854-
case Stop:
855-
case Clock:
856-
case Tick:
857-
case ActiveSensing:
858-
case SystemReset:
859-
case TuneRequest:
860-
// Handle message now
861-
mMessage.type = pendingType;
862-
mMessage.channel = 0;
863-
mMessage.data1 = 0;
864-
mMessage.data2 = 0;
865-
mMessage.length = 1;
866-
mMessage.valid = true;
867-
return true;
868-
break;
869-
// 2 byte messages
870-
case ProgramChange:
871-
case AfterTouchChannel:
872-
case TimeCodeQuarterFrame:
873-
case SongSelect:
874-
mPendingMessage[0] = extracted;
875-
mPendingMessageExpectedLength = 2;
876-
break;
877-
// 3 byte messages
878-
case NoteOn:
879-
case NoteOff:
880-
case ControlChange:
881-
case PitchBend:
882-
case AfterTouchPoly:
883-
case SongPosition:
884-
mPendingMessage[0] = extracted;
885-
mPendingMessageExpectedLength = 3;
886-
break;
887-
// SysEx
888-
case SystemExclusiveStart:
889-
mPendingMessage[0] = SystemExclusive;
890-
mPendingMessageExpectedLength = MidiMessage::sSysExMaxSize;
891-
mMessage.sysexArray[0] = SystemExclusiveStart;
892-
mLastError &= ~(1UL << WarningSplitSysEx); // Reset Warning Split SysEx bit
893-
break;
894-
case SystemExclusiveEnd:
895-
if (mPendingMessage[0] == SystemExclusive) {
896-
mMessage.sysexArray[mPendingMessageIndex++] = SystemExclusiveEnd; // Post Inc pending index here for correct lenght data
897-
mMessage.type = SystemExclusive;
898-
mMessage.data1 = mPendingMessageIndex & 0xff; // LSB
899-
mMessage.data2 = byte(mPendingMessageIndex >> 8); // MSB
900-
mMessage.channel = 0;
901-
mMessage.length = mPendingMessageIndex;
902-
if (mMessage.sysexArray[0] == SystemExclusiveEnd) {
903-
// This is the last chunk of a split SysEx message, and is NOT a valid SysEx message (it starts with 0xF7)
904-
mMessage.valid = false; // SysEx message is split so this not technically valid
905-
launchCallback(); // Lets notify callback to deal with this
906-
resetInput(); // Restart message
907-
return false;
908-
} else {
909-
// We are in a valid SysEx message that hasn't overrun (starts with 0xF0) so lets complete it
910-
mMessage.valid = true;
911-
resetInput(); // Restart message
912-
return true;
913-
}
914-
} else { // Looks like a SysEx End without a Sysex Start
915-
mLastError |= 1UL << ErrorParse; // Error: SysEx Stop byte received with no pending SysEx Start.
916-
if (mErrorCallback)
917-
mErrorCallback(mLastError);
918-
resetInput(); // Restart message
919-
return false;
920-
}
921-
break;
922-
// Unsupported
923-
default:
924-
mPendingMessage[0] = InvalidType;
925-
mLastError |= 1UL << ErrorParse; // Error: Unsupported Status byte.
926-
if (mErrorCallback)
927-
mErrorCallback(mLastError);
928-
resetInput(); // Restart message
929-
return false;
930-
break;
931-
}
932-
mPendingMessageIndex = 1; // If we are here, we have a valid Status! Lets try get some Data for it....
933-
mRunningStatus_RX = InvalidType; // Lets also reset Running Status until we have a complete message
934-
return (Settings::Use1ByteParsing) ? false : parse();
935-
936-
} else {
937-
// Lets get some data... First off.. check for Status Byte, or use Running Status
938-
if (mPendingMessageIndex == 0) {
939-
if (mRunningStatus_RX) {
940-
// Yay! We have Running Status
941-
mPendingMessage[0] = mRunningStatus_RX;
942-
mPendingMessageIndex = 1;
943-
} else {
944-
// ooops.... No Status Byte... No Running Status... lets ignore this data
945-
mLastError |= 1UL << ErrorParse; // Error: Data received without a valid Status byte or Running Status.
946-
if (mErrorCallback)
947-
mErrorCallback(mLastError);
831+
bool MidiInterface<Transport, Settings, Platform>::parse()
832+
{
833+
834+
if (mTransport.available() == 0)
948835
return false;
949-
}
950-
}
951836

952-
// Status or Running Status is good so add extracted data byte to pending message
953-
if (mPendingMessage[0] == SystemExclusive)
954-
mMessage.sysexArray[mPendingMessageIndex] = extracted;
955-
else
956-
mPendingMessage[mPendingMessageIndex] = extracted;
957-
958-
// Now we are going to check if we have reached the end of the message
959-
if (mPendingMessageIndex >= (mPendingMessageExpectedLength - 1)) {
960-
// SysEx larger than the allocated buffer size,
961-
// Split SysEx like so:
962-
// first: 0xF0 .... 0xF0
963-
// middle: 0xF7 .... 0xF0
964-
// last: 0xF7 .... 0xF7
965-
// ***** If the buffer has overrun, this SysEx message can now no longer be considered a valid Midi message and must be dealt with via callbacks only! ****
966-
if (mPendingMessage[0] == SystemExclusive) {
967-
// Warn at start of SysEx split
968-
if (mMessage.sysexArray[0] == SystemExclusiveStart) {
969-
mLastError |= 1UL << WarningSplitSysEx; // We have this error already defined so may as well use it
970-
if (mErrorCallback)
971-
mErrorCallback(mLastError);
837+
mLastError &= ~(1UL << ErrorParse); // Clear ErrorParse bit
838+
/*Possible Errors:
839+
> SysEx Stop byte received with no pending SysEx Start.
840+
> Unsupported Status byte.
841+
> Data received without a valid Status byte or Running Status.
842+
> Warning SysEx split warning.
843+
.... could potentially add an error for when SysEx is aborted due to receiving a new non-realtime status byte.
844+
*/
845+
846+
const byte extracted = mTransport.read();
847+
848+
if (extracted >= 0x80) {
849+
// Lets try get a valid Status byte. Non-realtime status overrides any current Status
850+
const MidiType pendingType = getTypeFromStatusByte(extracted);
851+
switch (pendingType) {
852+
// Realtime
853+
case Start:
854+
case Continue:
855+
case Stop:
856+
case Clock:
857+
case Tick:
858+
case ActiveSensing:
859+
case SystemReset:
860+
case TuneRequest:
861+
// Handle message now
862+
mMessage.type = pendingType;
863+
mMessage.channel = 0;
864+
mMessage.data1 = 0;
865+
mMessage.data2 = 0;
866+
mMessage.length = 1;
867+
mMessage.valid = true;
868+
return true;
869+
break;
870+
// 2 byte messages
871+
case ProgramChange:
872+
case AfterTouchChannel:
873+
case TimeCodeQuarterFrame:
874+
case SongSelect:
875+
mPendingMessage[0] = extracted;
876+
mPendingMessageExpectedLength = 2;
877+
break;
878+
// 3 byte messages
879+
case NoteOn:
880+
case NoteOff:
881+
case ControlChange:
882+
case PitchBend:
883+
case AfterTouchPoly:
884+
case SongPosition:
885+
mPendingMessage[0] = extracted;
886+
mPendingMessageExpectedLength = 3;
887+
break;
888+
// SysEx
889+
case SystemExclusiveStart:
890+
mPendingMessage[0] = SystemExclusive;
891+
mPendingMessageExpectedLength = MidiMessage::sSysExMaxSize;
892+
mMessage.sysexArray[0] = SystemExclusiveStart;
893+
mLastError &= ~(1UL << WarningSplitSysEx); // Reset Warning Split SysEx bit
894+
break;
895+
case SystemExclusiveEnd:
896+
if (mPendingMessage[0] == SystemExclusive) {
897+
mMessage.sysexArray[mPendingMessageIndex++] = SystemExclusiveEnd; // Post Inc pending index here for correct length data
898+
mMessage.type = SystemExclusive;
899+
mMessage.data1 = mPendingMessageIndex & 0xff; // LSB
900+
mMessage.data2 = byte(mPendingMessageIndex >> 8); // MSB
901+
mMessage.channel = 0;
902+
mMessage.length = mPendingMessageIndex;
903+
if (mMessage.sysexArray[0] == SystemExclusiveEnd) {
904+
// This is the last chunk of a split SysEx message, and is NOT a valid SysEx message (it starts with 0xF7)
905+
mMessage.valid = false; // SysEx message is split so this is not technically valid
906+
launchCallback(); // Lets notify callback to deal with this
907+
resetInput(); // Restart message
908+
return false;
909+
} else {
910+
// We are in a valid SysEx message that hasn't overrun (starts with 0xF0) so lets complete it
911+
mMessage.valid = true;
912+
resetInput(); // Restart message
913+
return true;
914+
}
915+
} else { // Looks like a SysEx End without a Sysex Start
916+
mLastError |= 1UL << ErrorParse; // Error: SysEx Stop byte received with no pending SysEx Start.
917+
if (mErrorCallback)
918+
mErrorCallback(mLastError);
919+
resetInput(); // Restart message
920+
return false;
921+
}
922+
break;
923+
// Unsupported
924+
default:
925+
mPendingMessage[0] = InvalidType;
926+
mLastError |= 1UL << ErrorParse; // Error: Unsupported Status byte.
927+
if (mErrorCallback)
928+
mErrorCallback(mLastError);
929+
resetInput(); // Restart message
930+
return false;
931+
break;
972932
}
973-
auto lastByte = mMessage.sysexArray[Settings::SysExMaxSize - 1];
974-
mMessage.sysexArray[Settings::SysExMaxSize - 1] = SystemExclusiveStart;
975-
mMessage.type = SystemExclusive;
976-
977-
// Get length
978-
mMessage.data1 = Settings::SysExMaxSize & 0xff; // LSB
979-
mMessage.data2 = byte(Settings::SysExMaxSize >> 8); // MSB
980-
mMessage.channel = 0;
981-
mMessage.length = Settings::SysExMaxSize;
982-
mMessage.valid = false; // SysEx message is split so this is not technically valid
983-
984-
// Notify callback to deal with the SysEx data chunk
985-
launchCallback();
933+
mPendingMessageIndex = 1; // If we are here, we have a valid Status! Lets try get some Data for it....
934+
mRunningStatus_RX = InvalidType; // Lets also reset Running Status until we have a complete message
935+
return (Settings::Use1ByteParsing) ? false : parse();
986936

987-
// Prep next SysEx data chunk to start with 0xF7
988-
mMessage.sysexArray[0] = SystemExclusiveEnd;
989-
mMessage.sysexArray[1] = lastByte;
990-
mPendingMessageIndex = 2;
991-
// SysEx buffer has overrun so parse() will no longer return true, and will need to be dealt with via callbacks only
992-
return false;
993-
}
937+
} else {
938+
// Lets get some data... First off.. check for Status Byte, or use Running Status
939+
if (mPendingMessageIndex == 0) {
940+
if (mRunningStatus_RX) {
941+
// Yay! We have Running Status
942+
mPendingMessage[0] = mRunningStatus_RX;
943+
mPendingMessageIndex = 1;
944+
} else {
945+
// ooops.... No Status Byte... No Running Status... lets ignore this data
946+
mLastError |= 1UL << ErrorParse; // Error: Data received without a valid Status byte or Running Status.
947+
if (mErrorCallback)
948+
mErrorCallback(mLastError);
949+
return false;
950+
}
951+
}
994952

995-
// Pending message is complete so lets save it
996-
mMessage.type = getTypeFromStatusByte(mPendingMessage[0]);
953+
// Status or Running Status is good so add extracted data byte to pending message
954+
if (mPendingMessage[0] == SystemExclusive)
955+
mMessage.sysexArray[mPendingMessageIndex] = extracted;
956+
else
957+
mPendingMessage[mPendingMessageIndex] = extracted;
958+
959+
// Now we are going to check if we have reached the end of the message
960+
if (mPendingMessageIndex >= (mPendingMessageExpectedLength - 1)) {
961+
// SysEx larger than the allocated buffer size,
962+
// Split SysEx like so:
963+
// first: 0xF0 .... 0xF0
964+
// middle: 0xF7 .... 0xF0
965+
// last: 0xF7 .... 0xF7
966+
// ***** If the buffer has overrun, this SysEx message can now no longer be considered a valid Midi message and must be dealt with via callbacks only! ****
967+
if (mPendingMessage[0] == SystemExclusive) {
968+
// Warn at start of SysEx split
969+
if (mMessage.sysexArray[0] == SystemExclusiveStart) {
970+
mLastError |= 1UL << WarningSplitSysEx; // We have this error already defined so may as well use it
971+
if (mErrorCallback)
972+
mErrorCallback(mLastError);
973+
}
974+
auto lastByte = mMessage.sysexArray[Settings::SysExMaxSize - 1];
975+
mMessage.sysexArray[Settings::SysExMaxSize - 1] = SystemExclusiveStart;
976+
mMessage.type = SystemExclusive;
977+
978+
// Get length
979+
mMessage.data1 = Settings::SysExMaxSize & 0xff; // LSB
980+
mMessage.data2 = byte(Settings::SysExMaxSize >> 8); // MSB
981+
mMessage.channel = 0;
982+
mMessage.length = Settings::SysExMaxSize;
983+
mMessage.valid = false; // SysEx message is split so this is not technically valid
984+
985+
// Notify callback to deal with the SysEx data chunk
986+
launchCallback();
987+
988+
// Prep next SysEx data chunk to start with 0xF7
989+
mMessage.sysexArray[0] = SystemExclusiveEnd;
990+
mMessage.sysexArray[1] = lastByte;
991+
mPendingMessageIndex = 2;
992+
// SysEx buffer has overrun so parse() will no longer return true, and will need to be dealt with via callbacks only
993+
return false;
994+
}
997995

998-
if (isChannelMessage(mMessage.type)) {
999-
mMessage.channel = getChannelFromStatusByte(mPendingMessage[0]);
1000-
// Message will be completed soon so lets update RunningStatus now as this is obviously a valid Channel Message.
1001-
mRunningStatus_RX = mPendingMessage[0];
1002-
} else
1003-
mMessage.channel = 0;
996+
// Pending message is complete so lets save it
997+
mMessage.type = getTypeFromStatusByte(mPendingMessage[0]);
1004998

1005-
mMessage.data1 = mPendingMessage[1];
1006-
// Save data2 only if applicable
1007-
mMessage.data2 = mPendingMessageExpectedLength == 3 ? mPendingMessage[2] : 0;
1008-
mMessage.length = mPendingMessageExpectedLength;
1009-
mMessage.valid = true;
999+
if (isChannelMessage(mMessage.type)) {
1000+
mMessage.channel = getChannelFromStatusByte(mPendingMessage[0]);
1001+
// Message will be completed soon so lets update RunningStatus now as this is obviously a valid Channel Message.
1002+
mRunningStatus_RX = mPendingMessage[0];
1003+
} else
1004+
mMessage.channel = 0;
10101005

1011-
// Reset index for next message
1012-
mPendingMessageIndex = 0;
1013-
//mPendingMessageExpectedLength = 0; // <-- No need to reset this as its valid still for Running Status, or will be updated on next Status byte received.
1006+
mMessage.data1 = mPendingMessage[1];
1007+
// Save data2 only if applicable
1008+
mMessage.data2 = mPendingMessageExpectedLength == 3 ? mPendingMessage[2] : 0;
1009+
mMessage.length = mPendingMessageExpectedLength;
1010+
mMessage.valid = true;
10141011

1015-
return true;
1016-
} else {
1017-
// We need more data...
1018-
mPendingMessageIndex++;
1012+
// Reset index for next message
1013+
mPendingMessageIndex = 0;
1014+
//mPendingMessageExpectedLength = 0; // <-- No need to reset this as its valid still for Running Status, or will be updated on next Status byte received.
10191015

1020-
return (Settings::Use1ByteParsing) ? false : parse();
1016+
return true;
1017+
} else {
1018+
// We need more data...
1019+
mPendingMessageIndex++;
1020+
1021+
return (Settings::Use1ByteParsing) ? false : parse();
1022+
}
10211023
}
1022-
}
10231024
}
10241025

10251026
// Private method, see midi_Settings.h for documentation

0 commit comments

Comments
 (0)