further refinement of the parser

need to further check edge cases:
- RealTime msg in the middle of a regular msg
- RealTime msg in the middle of a SysEx
This commit is contained in:
lathoub 2021-08-04 05:06:05 +02:00
parent 8904a44963
commit 20354c247c
2 changed files with 53 additions and 66 deletions

View File

@ -231,8 +231,8 @@ public:
byte lastStatus;
byte headerByte = buffer[lPtr++];
auto signatureIs1 = CHECK_BIT(headerByte, 7 - 1); // must be 1
auto reservedIs0 = !CHECK_BIT(headerByte, 6 - 1); // must be 0
// auto signatureIs1 = CHECK_BIT(headerByte, 7 - 1); // must be 1
// auto reservedIs0 = !CHECK_BIT(headerByte, 6 - 1); // must be 0
auto timestampHigh = 0x3f & headerByte;
byte timestampByte = buffer[lPtr++];
@ -240,7 +240,7 @@ public:
bool sysExContinuation = false;
if (CHECK_BIT(timestampByte, 7 - 1)) // if bit 7 is 1, it's a timestampByte
if (timestampByte >= 80) // if bit 7 is 1, it's a timestampByte
{
timestamp = setMidiTimestamp(headerByte, timestampByte);
}
@ -250,7 +250,7 @@ public:
lPtr--;
}
//While statement contains incrementing pointers and breaks when buffer size exceeded.
// While statement contains incrementing pointers and breaks when buffer size exceeded.
while (true)
{
lastStatus = buffer[lPtr];
@ -313,40 +313,24 @@ public:
break;
case MIDI_NAMESPACE::MidiType::SystemExclusive:
// do we have a complete sysex?
if ((rPtr + 1 < length) && (buffer[rPtr + 1] == MIDI_NAMESPACE::MidiType::SystemExclusiveEnd))
rPtr--; // before end is the timestampLow
mBleClass.add(buffer[lPtr]);
for (byte i = lPtr; i < rPtr; i++)
mBleClass.add(buffer[i + 1]);
rPtr++;
if (rPtr >= length)
return; // end of packet
timestampByte = buffer[rPtr++];
if (CHECK_BIT(timestampByte, 7 - 1))
{
timestamp = setMidiTimestamp(headerByte, timestampByte);
}
rPtr++;
break;
default:
break;
}
}
rPtr++;
if (rPtr >= length)
if (++rPtr >= length)
return; // end of packet
timestampByte = buffer[rPtr++];
if (CHECK_BIT(timestampByte, 7 - 1))
if (timestampByte >= 80) // is bit 7 set?
{
timestamp = setMidiTimestamp(headerByte, timestampByte);
// what do to with the timestamp?
}
// Point to next status

View File

@ -31,18 +31,16 @@ void receive(byte* buffer, size_t length)
byte lastStatus;
byte headerByte = buffer[lPtr++];
auto signatureIs1 = CHECK_BIT(headerByte, 7 - 1);
auto reservedIs0 = !CHECK_BIT(headerByte, 6 - 1);
// auto signatureIs1 = CHECK_BIT(headerByte, 7 - 1);
// auto reservedIs0 = !CHECK_BIT(headerByte, 6 - 1);
auto timestampHigh = 0x3f & headerByte;
byte timestampByte = buffer[lPtr++];
signatureIs1 = CHECK_BIT(timestampByte, 7 - 1);
uint16_t timestamp = 0;
bool sysExContinuation = false;
if (signatureIs1) {
if (timestampByte >= 80) {
auto timestampLow = 0x7f & timestampByte;
timestamp = timestampLow + (timestampHigh << 7);
}
@ -103,25 +101,15 @@ void receive(byte* buffer, size_t length)
}
break;
case 0xF0:
// do we have a complete sysex?
if ((rPtr + 1 < length) && (buffer[rPtr + 1] == 0xF7))
{
std::cout << "end: 0x" << std::hex << (int)buffer[rPtr + 1] << std::endl;
rPtr--;
}
transmitMIDIonDIN(buffer[lPtr], 0, 0);
for (auto i = lPtr; i < rPtr; i++)
transmitMIDIonDIN(buffer[i + 1], 0, 0);
rPtr++;
if (rPtr >= length)
/*
if (++rPtr >= length)
return; // end of packet
timestampByte = buffer[rPtr++];
signatureIs1 = CHECK_BIT(timestampByte, 7 - 1);
if (signatureIs1)
if (timestampByte >= 80)
{
auto timestampLow = 0x7f & timestampByte;
timestamp = timestampLow + (timestampHigh << 7);
@ -130,7 +118,7 @@ void receive(byte* buffer, size_t length)
}
std::cout << "end of SysEx: 0x" << std::hex << (int)buffer[rPtr] << std::endl;
*/
break;
default:
@ -138,16 +126,11 @@ void receive(byte* buffer, size_t length)
}
}
rPtr++;
if (rPtr >= length)
if (++rPtr >= length)
return; // end of packet
timestampByte = buffer[rPtr++];
// std::cout << "dddd: 0x" << std::hex << (int)timestampByte << std::endl;
signatureIs1 = CHECK_BIT(timestampByte, 7 - 1);
if (signatureIs1)
if (timestampByte >= 80) // is bit 7 set?
{
auto timestampLow = 0x7f & timestampByte;
timestamp = timestampLow + (timestampHigh << 7);
@ -165,26 +148,29 @@ void receive(byte* buffer, size_t length)
int main()
{
byte packet1[] = {0x80, 0xF7, 0x80, 0x34, 0x2B, 0xF7, 0x81, 0x34, 0x2B, 0xF8, 0xF0, 0x00, 0x11};
receive(packet1, sizeof(packet1));
std::cout << std::endl << "SysEx " << std::endl;
byte packet2[] = { 0x91, 0x22, 0x33, 0x44, 0x55, 0xF7, 0xF7, 0x80, 0x34, 0x2B, 0xF7, 0x80, 0x34, 0x34 };
receive(packet2, sizeof(packet2));
byte sysExPart[] = { 0xB0, 0xF4, // header + timestamp
0xF0, // start SysEx
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // sysex data
0xF4, // timestampLow
0xF7 }; // end of SysEx
receive(sysExPart, sizeof(sysExPart));
std::cout << std::endl << "SysEx part 1" << std::endl;
byte sysExPart1[] = { 0xB0, 0xF4,
0xF0,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
byte sysExPart1[] = { 0xB0, 0xF4, // header + timestamp
0xF0, // start SysEx
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; // sysex data
receive(sysExPart1, sizeof(sysExPart1));
std::cout << std::endl << "SysEx part 2" << std::endl;
byte sysExPart2[] = { 0xB0,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0xF4,
0xF7 };
byte sysExPart2[] = { 0xB0, // 1 byte header
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // sysex data (cont)
0xF4, // timestampLow
0xF7 }; // end of SysEx
receive(sysExPart2, sizeof(sysExPart2));
@ -203,6 +189,23 @@ int main()
0x91, 0x3E, 0x3E };
receive(blePacketWithTwoMIDIMessage, sizeof(blePacketWithTwoMIDIMessage));
std::cout << std::endl << "ble Packet with 3 MIDI messages" << std::endl;
byte blePacketWithThreeMIDIMessage[] = { 0xA8, 0xC0,
0x90, 0x3E, 0x3E,
0xC1,
0xF0,
0x01, 0x02,
0xC2,
0xF7,
0xC3,
0x91, 0x3E, 0x3E };
receive(blePacketWithThreeMIDIMessage, sizeof(blePacketWithThreeMIDIMessage));
// std::cout << std::endl << "2 MIDI messages with running status" << std::endl;
// TODO