davidfowl / BedrockFramework

High performance, low level networking APIs for building custom servers and clients.
MIT License
1.05k stars 153 forks source link

MIDI Protocol - How to handle realtime, interleaved, messages #161

Open ChristopherHaws opened 1 year ago

ChristopherHaws commented 1 year ago

Hey there! I tried asking in Gitter, but it seems pretty inactive so I figured I would ask here. :)

I am attempting to implement the MIDI 1.0 protocol using Bedrock. I have a use case where I need to connect to a networked audio mixer (which uses MIDI over TCP) but I also want to be able to support MIDI over a serial bus or other transports that might be relevant. Bedrock immediately felt like the right fit!

The main roadblock I am running into is that I can't figure out how I would use MessageReader.TryParseMessage to parse interleaved messages in the data stream since it only supports outputting a single message at a time.

Per the MIDI spec:

Real Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status bytes [most significant bit = 1] and Data bytes [most significant bit = 0] of any other MIDI messages. Giving Real-Time messages high priority allows synchronization to be maintained while other operations are being carried out"

There are only a handful of realtime messages so they are fairly easy to detect:

I was wondering how you would go about reading these messages? My first thought was to create a middleware to read just the realtime bytes and forward non-realtime bytes downstream to the IMessageReader, but I couldn't figure out how to set this up. It also felt wrong since my understanding is that middleware should not be transport or protocol specific.

Any help would be greatly appreciated! I will be open sourcing the protocol implementation once I have it working. :)

Thanks for this great project. I hope you eventually get time to keep working on it! ^_^