Fix #58.
This commit is contained in:
parent
208a79e5f0
commit
5f7fa5d083
19
src/MIDI.hpp
19
src/MIDI.hpp
|
|
@ -677,6 +677,19 @@ bool MidiInterface<SerialPort, Settings>::parse()
|
||||||
|
|
||||||
const byte extracted = mSerial.read();
|
const byte extracted = mSerial.read();
|
||||||
|
|
||||||
|
// Ignore Undefined
|
||||||
|
if (extracted == 0xf9 || extracted == 0xfd)
|
||||||
|
{
|
||||||
|
if (Settings::Use1ByteParsing)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return parse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mPendingMessageIndex == 0)
|
if (mPendingMessageIndex == 0)
|
||||||
{
|
{
|
||||||
// Start a new pending message
|
// Start a new pending message
|
||||||
|
|
@ -717,10 +730,7 @@ bool MidiInterface<SerialPort, Settings>::parse()
|
||||||
mMessage.data2 = 0;
|
mMessage.data2 = 0;
|
||||||
mMessage.valid = true;
|
mMessage.valid = true;
|
||||||
|
|
||||||
// \fix Running Status broken when receiving Clock messages.
|
|
||||||
// Do not reset all input attributes, Running Status must remain unchanged.
|
// Do not reset all input attributes, Running Status must remain unchanged.
|
||||||
//resetInput();
|
|
||||||
|
|
||||||
// We still need to reset these
|
// We still need to reset these
|
||||||
mPendingMessageIndex = 0;
|
mPendingMessageIndex = 0;
|
||||||
mPendingMessageExpectedLenght = 0;
|
mPendingMessageExpectedLenght = 0;
|
||||||
|
|
@ -828,8 +838,6 @@ bool MidiInterface<SerialPort, Settings>::parse()
|
||||||
mMessage.valid = true;
|
mMessage.valid = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// End of Exclusive
|
// End of Exclusive
|
||||||
case 0xf7:
|
case 0xf7:
|
||||||
if (mMessage.sysexArray[0] == SystemExclusive)
|
if (mMessage.sysexArray[0] == SystemExclusive)
|
||||||
|
|
@ -854,7 +862,6 @@ bool MidiInterface<SerialPort, Settings>::parse()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -735,4 +735,194 @@ TEST(MidiInput, realTime)
|
||||||
EXPECT_EQ(midi.getData2(), 0);
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --
|
||||||
|
|
||||||
|
TEST(MidiInput, interleavedRealTime)
|
||||||
|
{
|
||||||
|
SerialMock serial;
|
||||||
|
MidiInterface midi(serial);
|
||||||
|
|
||||||
|
// Interleaved Clocks between NoteOn / Off messages (with running status)
|
||||||
|
{
|
||||||
|
static const unsigned rxSize = 13;
|
||||||
|
static const byte rxData[rxSize] = {
|
||||||
|
0x9b, 12, 0xf8, 34,
|
||||||
|
12, 0,
|
||||||
|
42, 0xf8, 127,
|
||||||
|
0xf8,
|
||||||
|
42, 0xf8, 0
|
||||||
|
};
|
||||||
|
midi.begin(12);
|
||||||
|
serial.mRxBuffer.write(rxData, rxSize);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::Clock);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 0);
|
||||||
|
EXPECT_EQ(midi.getData1(), 0);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::NoteOn);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 12);
|
||||||
|
EXPECT_EQ(midi.getData2(), 34);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::NoteOff);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 12);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::Clock);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 0);
|
||||||
|
EXPECT_EQ(midi.getData1(), 0);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::NoteOn);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 42);
|
||||||
|
EXPECT_EQ(midi.getData2(), 127);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::Clock);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 0);
|
||||||
|
EXPECT_EQ(midi.getData1(), 0);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::Clock);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 0);
|
||||||
|
EXPECT_EQ(midi.getData1(), 0);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::NoteOff);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 42);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
}
|
||||||
|
// Interleaved ActiveSensing between SysEx
|
||||||
|
{
|
||||||
|
static const unsigned rxSize = 6;
|
||||||
|
static const byte rxData[rxSize] = {
|
||||||
|
0xf0, 12, 34, 0xfe, 56, 0xf7
|
||||||
|
};
|
||||||
|
midi.begin(12);
|
||||||
|
serial.mRxBuffer.write(rxData, rxSize);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ActiveSensing);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 0);
|
||||||
|
EXPECT_EQ(midi.getData1(), 0);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getSysExArrayLength(), rxSize - 1);
|
||||||
|
const std::vector<byte> sysExData(midi.getSysExArray(),
|
||||||
|
midi.getSysExArray() + rxSize - 1);
|
||||||
|
EXPECT_THAT(sysExData, ElementsAreArray({
|
||||||
|
0xf0, 12, 34, 56, 0xf7
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidiInput, strayEox)
|
||||||
|
{
|
||||||
|
// A stray End of Exclusive will reset the parser, but should it ?
|
||||||
|
SerialMock serial;
|
||||||
|
MidiInterface midi(serial);
|
||||||
|
static const unsigned rxSize = 4;
|
||||||
|
static const byte rxData[rxSize] = {
|
||||||
|
0x8b, 42, 0xf7, 12
|
||||||
|
};
|
||||||
|
midi.begin(MIDI_CHANNEL_OMNI);
|
||||||
|
serial.mRxBuffer.write(rxData, rxSize);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidiInput, strayUndefinedOneByteParsing)
|
||||||
|
{
|
||||||
|
SerialMock serial;
|
||||||
|
MidiInterface midi(serial);
|
||||||
|
|
||||||
|
static const unsigned rxSize = 13;
|
||||||
|
static const byte rxData[rxSize] = {
|
||||||
|
0xbb, 12, 0xf9, 34,
|
||||||
|
12, 0,
|
||||||
|
42, 0xfd, 127,
|
||||||
|
0xf9,
|
||||||
|
42, 0xfd, 0
|
||||||
|
};
|
||||||
|
midi.begin(12);
|
||||||
|
serial.mRxBuffer.write(rxData, rxSize);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false); // Invalid, should not reset parser
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ControlChange);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 12);
|
||||||
|
EXPECT_EQ(midi.getData2(), 34);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ControlChange);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 12);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ControlChange);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 42);
|
||||||
|
EXPECT_EQ(midi.getData2(), 127);
|
||||||
|
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), false);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ControlChange);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 42);
|
||||||
|
EXPECT_EQ(midi.getData2(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidiInput, strayUndefinedMultiByteParsing)
|
||||||
|
{
|
||||||
|
typedef VariableSettings<false, false> Settings;
|
||||||
|
typedef midi::MidiInterface<SerialMock, Settings> MidiInterface;
|
||||||
|
|
||||||
|
SerialMock serial;
|
||||||
|
MidiInterface midi(serial);
|
||||||
|
|
||||||
|
static const unsigned rxSize = 4;
|
||||||
|
static const byte rxData[rxSize] = {
|
||||||
|
0xbb, 12, 0xf9, 34,
|
||||||
|
};
|
||||||
|
midi.begin(12);
|
||||||
|
serial.mRxBuffer.write(rxData, rxSize);
|
||||||
|
EXPECT_EQ(midi.read(), true);
|
||||||
|
EXPECT_EQ(midi.getType(), midi::ControlChange);
|
||||||
|
EXPECT_EQ(midi.getChannel(), 12);
|
||||||
|
EXPECT_EQ(midi.getData1(), 12);
|
||||||
|
EXPECT_EQ(midi.getData2(), 34);
|
||||||
|
}
|
||||||
|
|
||||||
END_UNNAMED_NAMESPACE
|
END_UNNAMED_NAMESPACE
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue