Hi all,
I wrote a sketch in which I'm receiving raw Midi data as HEX bytes via UDP. The following code snipped is reading the UDP message and printing it to the serial monitor:
void UDPreceive() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.print(packetSize);
Serial.print(" From ");
IPAddress remote = Udp.remoteIP();
for (int i = 0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.print(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer, packetSize);
//print the incoming packet as HEX bytes
Serial.print(" Contents: ");
for (int i = 0; i < packetSize; i++) {
Serial.print(packetBuffer[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
This is already working so far. However, sometimes I receive several Midi messages in one UDP packet. For most of the messages this is not a problem as most of the Midi messages are 3 bytes long (one status byte, two data bytes) and I can easily split them. The only exception are System Exclusive (SysEx) messages. They start with the byte 0xF0 followed by an unknown amount of data bytes and ending with a 0xF7. If the UDP packet only contains a SysEx message that's also not a problem at all. But sometimes I receive - let's say - a SysEx message followed by a control change message in one UPD packet and I haven't found a way to split the messages while reading the UDP packet. Sure I could put the whole packet in a temporary array and split them afterwards but I was hoping to find a more elegant way to do so.
My starting point was this code snipped:
void processUDP() {
packetSize = UDP.parsePacket();
while (UDP.available() > 0) {
UDP.read(&messageType, 1);
switch ( (messageType & 0xF0) ) {
case 0x80: //Note Off Message
UDP.read(data, 2);
HandleNoteOff(messageType & 0x0F, data[0], data[1]);
break;
case 0x90: //Note On Message
UDP.read(data, 2);
HandleNoteOn(messageType & 0x0F, data[0], data[1]);
break;
case 0xA0: //Polyphonic Key Press
UDP.read(data, 2);
break;
case 0xB0: //Control Change
UDP.read(data, 2);
HandleControlChange(messageType & 0x0F, data[0], data[1]);
break;
case 0xC0: //Program Change
UDP.read(data, 1);
break;
case 0xD0: //Channel Pressure (after-touch)
UDP.read(data, 1);
break;
case 0xE0: //Pitch Wheel
UDP.read(data, 2);
break;
case 0xF0: //System
switch (messageType) {
case 0xF0: //Sysex, what to do??
break;
case 0xF1: //MIDI Time Code Quarter Frame.
UDP.read(data, 1);
break;
case 0xF2: //Song Position Pointer.
UDP.read(data, 2);
break;
case 0xF3: //Song Select
UDP.read(data, 1);
break;
case 0xF8: //Timing Clock
//Do something here if you want....
break;
default:
break;
}
break;
default:
UDP.read(data, 2);
}
}
}
Does anyone have a hint on this? Is there a way to stop Udp.read() when 0xF7 is reached in the packet buffer and continue in another variable?
cheers,
stefan