Skip to content

Commit 5f7fa5d

Browse files
author
Francois Best
committed
Fix #58.
1 parent 208a79e commit 5f7fa5d

File tree

2 files changed

+203
-6
lines changed

2 files changed

+203
-6
lines changed

src/MIDI.hpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,19 @@ bool MidiInterface<SerialPort, Settings>::parse()
677677

678678
const byte extracted = mSerial.read();
679679

680+
// Ignore Undefined
681+
if (extracted == 0xf9 || extracted == 0xfd)
682+
{
683+
if (Settings::Use1ByteParsing)
684+
{
685+
return false;
686+
}
687+
else
688+
{
689+
return parse();
690+
}
691+
}
692+
680693
if (mPendingMessageIndex == 0)
681694
{
682695
// Start a new pending message
@@ -717,10 +730,7 @@ bool MidiInterface<SerialPort, Settings>::parse()
717730
mMessage.data2 = 0;
718731
mMessage.valid = true;
719732

720-
// \fix Running Status broken when receiving Clock messages.
721733
// Do not reset all input attributes, Running Status must remain unchanged.
722-
//resetInput();
723-
724734
// We still need to reset these
725735
mPendingMessageIndex = 0;
726736
mPendingMessageExpectedLenght = 0;
@@ -828,8 +838,6 @@ bool MidiInterface<SerialPort, Settings>::parse()
828838
mMessage.valid = true;
829839
return true;
830840

831-
break;
832-
833841
// End of Exclusive
834842
case 0xf7:
835843
if (mMessage.sysexArray[0] == SystemExclusive)
@@ -854,7 +862,6 @@ bool MidiInterface<SerialPort, Settings>::parse()
854862
return false;
855863
}
856864

857-
break;
858865
default:
859866
break;
860867
}

test/unit-tests/tests/unit-tests_MidiInput.cpp

+190
Original file line numberDiff line numberDiff line change
@@ -735,4 +735,194 @@ TEST(MidiInput, realTime)
735735
EXPECT_EQ(midi.getData2(), 0);
736736
}
737737

738+
// --
739+
740+
TEST(MidiInput, interleavedRealTime)
741+
{
742+
SerialMock serial;
743+
MidiInterface midi(serial);
744+
745+
// Interleaved Clocks between NoteOn / Off messages (with running status)
746+
{
747+
static const unsigned rxSize = 13;
748+
static const byte rxData[rxSize] = {
749+
0x9b, 12, 0xf8, 34,
750+
12, 0,
751+
42, 0xf8, 127,
752+
0xf8,
753+
42, 0xf8, 0
754+
};
755+
midi.begin(12);
756+
serial.mRxBuffer.write(rxData, rxSize);
757+
EXPECT_EQ(midi.read(), false);
758+
EXPECT_EQ(midi.read(), false);
759+
760+
EXPECT_EQ(midi.read(), true);
761+
EXPECT_EQ(midi.getType(), midi::Clock);
762+
EXPECT_EQ(midi.getChannel(), 0);
763+
EXPECT_EQ(midi.getData1(), 0);
764+
EXPECT_EQ(midi.getData2(), 0);
765+
766+
EXPECT_EQ(midi.read(), true);
767+
EXPECT_EQ(midi.getType(), midi::NoteOn);
768+
EXPECT_EQ(midi.getChannel(), 12);
769+
EXPECT_EQ(midi.getData1(), 12);
770+
EXPECT_EQ(midi.getData2(), 34);
771+
772+
EXPECT_EQ(midi.read(), false);
773+
EXPECT_EQ(midi.read(), true);
774+
EXPECT_EQ(midi.getType(), midi::NoteOff);
775+
EXPECT_EQ(midi.getChannel(), 12);
776+
EXPECT_EQ(midi.getData1(), 12);
777+
EXPECT_EQ(midi.getData2(), 0);
778+
779+
EXPECT_EQ(midi.read(), false);
780+
EXPECT_EQ(midi.read(), true);
781+
EXPECT_EQ(midi.getType(), midi::Clock);
782+
EXPECT_EQ(midi.getChannel(), 0);
783+
EXPECT_EQ(midi.getData1(), 0);
784+
EXPECT_EQ(midi.getData2(), 0);
785+
786+
EXPECT_EQ(midi.read(), true);
787+
EXPECT_EQ(midi.getType(), midi::NoteOn);
788+
EXPECT_EQ(midi.getChannel(), 12);
789+
EXPECT_EQ(midi.getData1(), 42);
790+
EXPECT_EQ(midi.getData2(), 127);
791+
792+
EXPECT_EQ(midi.read(), true);
793+
EXPECT_EQ(midi.getType(), midi::Clock);
794+
EXPECT_EQ(midi.getChannel(), 0);
795+
EXPECT_EQ(midi.getData1(), 0);
796+
EXPECT_EQ(midi.getData2(), 0);
797+
798+
EXPECT_EQ(midi.read(), false);
799+
EXPECT_EQ(midi.read(), true);
800+
EXPECT_EQ(midi.getType(), midi::Clock);
801+
EXPECT_EQ(midi.getChannel(), 0);
802+
EXPECT_EQ(midi.getData1(), 0);
803+
EXPECT_EQ(midi.getData2(), 0);
804+
805+
EXPECT_EQ(midi.read(), true);
806+
EXPECT_EQ(midi.getType(), midi::NoteOff);
807+
EXPECT_EQ(midi.getChannel(), 12);
808+
EXPECT_EQ(midi.getData1(), 42);
809+
EXPECT_EQ(midi.getData2(), 0);
810+
}
811+
// Interleaved ActiveSensing between SysEx
812+
{
813+
static const unsigned rxSize = 6;
814+
static const byte rxData[rxSize] = {
815+
0xf0, 12, 34, 0xfe, 56, 0xf7
816+
};
817+
midi.begin(12);
818+
serial.mRxBuffer.write(rxData, rxSize);
819+
EXPECT_EQ(midi.read(), false);
820+
EXPECT_EQ(midi.read(), false);
821+
EXPECT_EQ(midi.read(), false);
822+
823+
EXPECT_EQ(midi.read(), true);
824+
EXPECT_EQ(midi.getType(), midi::ActiveSensing);
825+
EXPECT_EQ(midi.getChannel(), 0);
826+
EXPECT_EQ(midi.getData1(), 0);
827+
EXPECT_EQ(midi.getData2(), 0);
828+
829+
EXPECT_EQ(midi.read(), false);
830+
EXPECT_EQ(midi.read(), true);
831+
EXPECT_EQ(midi.getSysExArrayLength(), rxSize - 1);
832+
const std::vector<byte> sysExData(midi.getSysExArray(),
833+
midi.getSysExArray() + rxSize - 1);
834+
EXPECT_THAT(sysExData, ElementsAreArray({
835+
0xf0, 12, 34, 56, 0xf7
836+
}));
837+
}
838+
}
839+
840+
TEST(MidiInput, strayEox)
841+
{
842+
// A stray End of Exclusive will reset the parser, but should it ?
843+
SerialMock serial;
844+
MidiInterface midi(serial);
845+
static const unsigned rxSize = 4;
846+
static const byte rxData[rxSize] = {
847+
0x8b, 42, 0xf7, 12
848+
};
849+
midi.begin(MIDI_CHANNEL_OMNI);
850+
serial.mRxBuffer.write(rxData, rxSize);
851+
EXPECT_EQ(midi.read(), false);
852+
EXPECT_EQ(midi.read(), false);
853+
EXPECT_EQ(midi.read(), false);
854+
EXPECT_EQ(midi.read(), false);
855+
}
856+
857+
TEST(MidiInput, strayUndefinedOneByteParsing)
858+
{
859+
SerialMock serial;
860+
MidiInterface midi(serial);
861+
862+
static const unsigned rxSize = 13;
863+
static const byte rxData[rxSize] = {
864+
0xbb, 12, 0xf9, 34,
865+
12, 0,
866+
42, 0xfd, 127,
867+
0xf9,
868+
42, 0xfd, 0
869+
};
870+
midi.begin(12);
871+
serial.mRxBuffer.write(rxData, rxSize);
872+
EXPECT_EQ(midi.read(), false);
873+
EXPECT_EQ(midi.read(), false);
874+
EXPECT_EQ(midi.read(), false); // Invalid, should not reset parser
875+
876+
EXPECT_EQ(midi.read(), true);
877+
EXPECT_EQ(midi.getType(), midi::ControlChange);
878+
EXPECT_EQ(midi.getChannel(), 12);
879+
EXPECT_EQ(midi.getData1(), 12);
880+
EXPECT_EQ(midi.getData2(), 34);
881+
882+
EXPECT_EQ(midi.read(), false);
883+
EXPECT_EQ(midi.read(), true);
884+
EXPECT_EQ(midi.getType(), midi::ControlChange);
885+
EXPECT_EQ(midi.getChannel(), 12);
886+
EXPECT_EQ(midi.getData1(), 12);
887+
EXPECT_EQ(midi.getData2(), 0);
888+
889+
EXPECT_EQ(midi.read(), false);
890+
EXPECT_EQ(midi.read(), false);
891+
EXPECT_EQ(midi.read(), true);
892+
EXPECT_EQ(midi.getType(), midi::ControlChange);
893+
EXPECT_EQ(midi.getChannel(), 12);
894+
EXPECT_EQ(midi.getData1(), 42);
895+
EXPECT_EQ(midi.getData2(), 127);
896+
897+
EXPECT_EQ(midi.read(), false);
898+
EXPECT_EQ(midi.read(), false);
899+
EXPECT_EQ(midi.read(), false);
900+
EXPECT_EQ(midi.read(), true);
901+
EXPECT_EQ(midi.getType(), midi::ControlChange);
902+
EXPECT_EQ(midi.getChannel(), 12);
903+
EXPECT_EQ(midi.getData1(), 42);
904+
EXPECT_EQ(midi.getData2(), 0);
905+
}
906+
907+
TEST(MidiInput, strayUndefinedMultiByteParsing)
908+
{
909+
typedef VariableSettings<false, false> Settings;
910+
typedef midi::MidiInterface<SerialMock, Settings> MidiInterface;
911+
912+
SerialMock serial;
913+
MidiInterface midi(serial);
914+
915+
static const unsigned rxSize = 4;
916+
static const byte rxData[rxSize] = {
917+
0xbb, 12, 0xf9, 34,
918+
};
919+
midi.begin(12);
920+
serial.mRxBuffer.write(rxData, rxSize);
921+
EXPECT_EQ(midi.read(), true);
922+
EXPECT_EQ(midi.getType(), midi::ControlChange);
923+
EXPECT_EQ(midi.getChannel(), 12);
924+
EXPECT_EQ(midi.getData1(), 12);
925+
EXPECT_EQ(midi.getData2(), 34);
926+
}
927+
738928
END_UNNAMED_NAMESPACE

0 commit comments

Comments
 (0)