Skip to main content

Network MIDI 2.0: Implementation Guide – Using Sequence Numbers for Robustness and Recovery


The Network MIDI 2.0: User Datagram Protocol for Universal MIDI Packets specification by the MIDI Association and AMEI provides a new method for sending MIDI messages over standard IP networks. UDP does not guarantee loss-free transmission, therefore the Network MIDI 2.0 standard provides simple mechanisms to recover from transmission errors.

Please note: Developers should read the Network MIDI 2.0: User Datagram Protocol for Universal MIDI Packets specification before continuing.

UMP Data Command Sequence Number Handling

Sequence Numbers in a UMP Data Command are 16-bit unsigned starting at 0 up to 65535 (hexadecimal 0xFFFF), wrapping back to 0 after 0xFFFF.

It is necessary that every Endpoint maintains two counters for every Session:

LastSentSeqNum: The Sequence Number of the last sent UMP Data Command. When sending a UMP Data Command, the LastSentSeqNum counter is increased before setting the Sequence Number field in the UMP Data Command.

LastReceivedSeqNum: The Sequence Number of the last received UMP Data Command from the remote Endpoint. When receiving a UMP Data Command, its Sequence Number should equal the next value of the LastReceivedSeqNum counter. If the received Sequence Number is after that (“later”), one or more Data Commands are missing.  If the received Sequence Number equals the LastReceivedSeqNum or before, it is a duplicate Data Command or an FEC Data Command and can be safely ignored.

Sequence Number is Before or Later?

When comparing two Sequence Numbers, you cannot just compare if one is greater than the other because they wrap around. For example, the seq num 1 is after 0xFFFF, although the number 0xFFFF is greater than 1.

For comparing Sequence Numbers, we recommend the following approach:

For two given Sequence Numbers Seq1 and Seq2, take the difference. By assuming that they are not spaced further than half the entire Sequence Number range, we can interpret the difference like this:

Seq2 – Seq1interpretation
0Seq1 and Seq2 are equal
1..0x7FFFSeq2 is after Seq1. The difference result tells us how many Sequence Numbers are between Seq1 and Seq2.
0x8000…0xFFFFSeq2 is before Seq1. To find out how many Sequence Numbers are between Seq1 and Seq2, calculate (0xFFFF – (Seq2 – Seq1) + 1). This is effectively a two’s complement.

In C or C++, you can take advantage of two’s complement by casting to a signed 16-bit integer:

/**
 * Calculate the distance between seq1 and seq2.
 * @return 0 when seq1 and seq2 are equal,
 *         a positive number if seq2 is after seq1, or
 *         a negative number if seq2 is before seq1.
 */
int16_t getSeqNumDifference(uint16_t seq1, uint16_t seq2) {
	return (int16_t)(seq2 - seq1);
}

// Example for using this function:

uint16_t seq1 = 0xFFFF;
uint16_t seq2 = 0x0001;
int16_t comparisonResult = getSeqNumDifference(seq1, seq2);
if (comparisonResult == 0) {
  printf("seq1 and seq2 are equal.\n");
} else if (comparisonResult > 0) {
  printf("seq2 is %d packets after seq1\n", comparisonResult);
} else {
  printf("seq2 is %d packets before seq1\n", -comparisonResult);
}

Increasing Robustness of Sending Data: 

Using Forward Error Correction and Sending Empty UMP Data Commands during Idle Periods

Generally speaking, when using MIDI it is usually essential that MIDI messages are not skipped, and that they are processed in the order in which they were sent. This prevents situations where a note is left on without a note off, or System Exclusive message is not received in full.

When a sender is using Forward Error Correction (FEC), it ensures that a receiver is more likely to handle missed MIDI messages, and that the receiver can maintain the correct order. The MIDI Association recommends that all MIDI 2.0 Network Devices should use FEC by default. The only time a Network MIDI 2.0 Device should not use FEC is for special circumstances where both sides understand the risks of missing packets, or where packet loss is not a concern.

The variant of FEC used by Network MIDI 2.0 is a very simple repeat of previous messages. This allows implementing FEC on different hardware and software platforms. As MIDI messages are usually quite small, the Specification makes use of the average UDP packet size to have the space to use these repeated UMP Data Commands.

The specification requires sending empty UMP Data Commands when there is a break in UMP Data Commands. 

For example, imagine the following scenario: you have a Network MIDI 2.0 Controller Keyboard. You are playing across the network to a synth. You play the last note of your piece by sending a Note On Event, and then you release the key to send a Note Off Event. 

Unfortunately, tragedy strikes and the Note Off event is lost on the network. If no other MIDI Messages are sent, then the synth will continue playing the stuck note. FEC will not recover the Note Off Event until a new MIDI Message is sent, and this may not occur for sometime.

To avoid scenarios like these, the specification requires sending empty UMP Data Commands if there are idle periods in sending MIDI messages. By sending a few Empty UMP Data Commands with FEC this will quickly recover from any lost data.

By using FEC and sending empty UMP Data Commands during idle periods, you can minimize the chances of lost packets. In fact, when MIDI Association members tested their Network MIDI 2.0 implementations, there was no loss of data. Any lost packets were successfully recovered by FEC.

Supporting Retransmit Commands

Retransmit support is desired on Devices that have the memory available to support the storage of more previous UMP Data Commands than needed for FEC. Devices on Wireless LAN can suffer from frequent dropouts, or Devices which have FEC disabled will benefit from using Retransmit Commands.

A Device that supports Retransmit should provide enough memory to retrieve up to several seconds of previous UMP Data Commands, because the remote Device may take a second or more to realize MIDI messages are missing and then send a Retransmit Command. As each Session is unique in terms of Sequence Numbers, a Device that supports Retransmit will need to store the sequence of UMP Data Commands for each Session independently.

Handling Lost UMP Data Commands as a Receiver

Missing UDP packets can be caused by several factors, such as network congestion or poor connection to a wireless access point. 

When a UMP Data Command is received, the Sequence Number will indicate if one or more UDP packets have been lost. In such a case, and if FEC does not recover all missing MIDI messages, the following steps are recommended (as seen in the diagram above):

  1. Wait up to 100ms for the missing packets
    Sometimes (especially on wireless LANs) UDP packets can be received out of order. By waiting for a period of time, the missing UDP packets may arrive and the data can be recovered using normal FEC handling.
  2. Send a Retransmit Command
    If the remote Device supports Retransmission, the Retransmit Command is the best way for the user to be able to continue using the Session with minimal interruption.
    1. A remote Device that does not support Retransmit will send a NAK to indicate that the Command it is not supported. When this occurs, the local Device should make a note to not send the Retransmit Command for the rest of the Session.
    2. A remote Device that does support Retransmit, but is unable to provide the missing UMP Data Commands, will return a Retransmit Error Command. If another lost UDP packet incident occurs again in the Session, then Retransmit should be retried again.
  3. Send a Session Reset Command

The Session Reset Command is recommended  when either the Host or the Client has lost all ability to recover from lost UMP Data Commands. It effectively resets the two Sequence Numbers (LastSentSeqNum and  LastReceivedSeqNum) back to zero. In doing so, both the Host and Client can restart their communication of UMP DATA Commands.

A Device that receives Session Reset may consider turning all sounds off or clearing any partially received System Exclusive Data, or to even resend previous data. It is up to each Device to make decisions on what to do when receiving a Session Reset.

It is highly recommended that all Devices support the Session Reset Command. If the Device does not support Session Reset, then the Session can be considered corrupted beyond repair and will need to be terminated using a Bye Command. This may require the user to manually reconnect Devices – and could be quite annoying to the user.

Last Words…

The Network MIDI 2.0 standard provides a robust, yet simple MIDI 2.0 transport. It provides a few mechanisms to ensure that MIDI messages arrive where they are supposed to. The MIDI Association is looking forward to seeing this protocol used in more and more MIDI Devices.

Look out for more articles on midi.org on Network MIDI 2.0!