Choosing the best strategy for handling MIDI payload through RFM69

Started by midix, November 05, 2022, 09:22:25 PM

midix

I'm using set300KBPS for max bitrate. I don't need large distances, should not be more than 5 meters without any obstacles in between. I do not use encryption.

For the first experiments and quick stress tests, it seems to work well. However, I'm not sure what would be the reasonably efficient way to organize the traffic handling logic.

In theory, MIDI can send bytes at a rate of 3125 payload bytes per second. In my case, it surely will rarely reach the maximum, maybe there could be large bursts with pitch bend and other MIDI control values.

Currently, I'm sending only one MIDI message per packet, which might be not efficient because of the service bytes (headers etc.) wasting the bandwidth. When I receive MIDI bytes from serial input, there could be more than one MIDI message accumulated. So, I might / (should I?) try to pack them inside the 61 byte payload of RFM69. I might even try to always accumulate more MIDI messages in a packet, but I need to be careful with latency - I would need some kind of a timer control to check if the oldest message in my accumulator has reached some threshold, and then I have to send the entire (potentially not fully filled) packet immediately to avoid latency issues.

Also, message ordering also is important. I assume that RFM69 does not mess up ordering. The receiver will always get the messages in the same order I send them, right?

Another thing is the delivery guarantee. Most MIDI messages are important. Missing some pitch bend changes might be acceptable, but missing a noteon / off is a disaster.

I now have a custom ACK logic that waits a bit for a reply and if it's missed, then sends the message again in the next iteration. However, to get rid of the ACK-introduced delay, I'm now thinking about another strategy. I might instead send bursts of the same packet with the hope that one of them will reach the target and not wait for ACKs at all. Every packet has a sequence number byte so that the target knows it has received a duplicate (with rollover handling). However, it's not clear if it's reasonable to send the same packet many times (how many?) in a row or if it's better to give a few microseconds of time (but then not too much, to still be able to handle MIDI 3125 bytes-per-second bursts).

Also, I'm not sure about the actual usable bitrate of RFM69. Those 300kbps include all the bits - preamble, header etc. right? So, what's the real useful max bitrate, assuming I'm filling in all 61 payload bytes? I am worried that those 300kbps might be not enough to match the MIDI bursts if we consider all the RFM69 service bits.

Has anyone done something similar?

I don't really want to reinvent the wheel. Maybe I should have gone for MIDI BLE instead, but not sure how it handles 3125 bytes per second either, and the latency also is much worse. A MIDI BLE study measured that for some devices it can reach even 12ms and the max real throughput is about 40kbps.