On Mon, 2020-03-16 at 13:03 +0100, Clemens Ladisch wrote: > Andreas Steinmetz wrote: > > the snd_usbmidi_transmit_byte helper had to be converted to > > return output notification to allow for the 'repeat' shortcut. > > Why not simply handle one MIDI byte per port in each iteration? It > could be argued that single-byte MIDI commands are likely to be real- > time messages and deserve to go first. > Actually the patch does exactly this. As soon as the helper signals that a message is complete the next port is processed. The "repeat" loop is just necessary to get a complete class compliant message for transfer as the helper processes one byte at a time. The range optimization is there to prevent O(2) performance cost if possible. > > Current multi port MIDI interfaces do > > typically have 2^n output ports and 2^x as wMaxPacketSize where > > x>n. > > The USB specification requires bulk endpoints to have a > wMaxPacketSize > value of 8/16/32/64 for full speed, or exactly 512 for high speed. > > > For the patch to properly work the wMaxPacketSize of the device > > must be > > large enough to allow for at least one MIDI event per port in a > > URB. > > There are devices that handle only the first four bytes of a received > packet (because Windows used to send only small packets), and one of > them, the ESI M4U, actually has more than one port. > Again no problem as the patch is designed to prefer quirks over user settings to prevent malfunctioning devices. Quirk processing and thus size restrictions are processed after user selection. > My original idea for that FIXME was to use round robin until the > packet > is filled (or all ports are empty), and to store the next port index > (where to start for the next packet) in the endpoint. This would be > able to distribute the balancing over multiple packets. > The problem with "round robin until the packet is filled" is that in case of a large wMaxPacketSize there's then a huge latency. I just got for further internal testing an USB3 8x8 interface that uses a wMaxPacketSize of 512. In such a case a port doing a sysex transfer will delay another port then sending a realtime message by a minimum of 123ms per queued URB. Make that 7 URBs and you have a sysex queue of 860ms until the realtime message can be transmitted. > > Regards, > Clemens -- Andreas Steinmetz