PortMidi / portmidi

portmidi is a cross-platform MIDI input/output library
Other
116 stars 31 forks source link

Dropped and invalid messages when sending to an IAC - is this a bug? #30

Closed StewMacLean closed 2 years ago

StewMacLean commented 2 years ago

When I use PortMidi to send to an IAC, messages are being dropped, and more often that not, an invalid message appears in MIDIMonitor (usually the fourth line).

Initially I thought it was my binding, but I'm able to repeat it using testio, adapted to send a secession of 8 note on/off messages. This sends with timestamps, which I thought could be a cause, but indicates otherwise.

The output should show 16 Note On/Note Off messages (as it shows two for each message sent - not sure why?).

However, it only shows 10, indicating that three messages are lost on the way. This is consistent behaviour.

If I do the same thing using the command line SendMidi utility (called from a script), no errors occur. If I send directly to MIDIMonitor no errors appear. And this is probably a good clue, if I wait for just one millisecond between calls to write, it works as expected!

So, I'm not sure if this is a bug in PortMidi, or a "feature" of driving IAC too hard?

rbdannenberg commented 2 years ago

Are you using an M1? Are you using the (very) recent head with M1-related fixes? IAC by design drops MIDI messages sent at high rate, and PortMidi does a lot of work to throttle messages below the IAC maximum rate, while allowing hardware interfaces (which are not limited by CoreMIDI) to run at full bandwidth. But if you are talking small numbers of messages, this is unrelated to CoreMIDI limits.

StewMacLean commented 2 years ago

Hi Roger, yes it's me with the M1! And I have the latest fixes.

There are eight messages in total, and three go missing (and usually an invalid one) without the 1ms delay.

Would this be exceeding the IAC maximum rate? I've heard that IAC can introduce latency, but haven't found anything relating to dropped messages.

I have another problem that I suspect is related. I'm sending messages (with the 1ms delay) from a PortMidi output port to a PortMidi input port to test my read routine. About 95% of the time, it doesn't read the last message. All the messages show in MidiMonitor and also the receivemidi utility as expected.

Thanks for your help and happy to conduct any tests if needed.

On Thu, May 26, 2022 at 12:40 PM Roger B. Dannenberg < @.***> wrote:

Are you using an M1? Are you using the (very) recent head with M1-related fixes? IAC by design drops MIDI messages sent at high rate, and PortMidi does a lot of work to throttle messages below the IAC maximum rate, while allowing hardware interfaces (which are not limited by CoreMIDI) to run at full bandwidth. But if you are talking small numbers of messages, this is unrelated to CoreMIDI limits.

— Reply to this email directly, view it on GitHub https://github.com/PortMidi/portmidi/issues/30#issuecomment-1138018368, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXGQYQYAIBP2N3ZTMCI5V6LVL3CBHANCNFSM5W7DV7FA . You are receiving this because you authored the thread.Message ID: @.***>

rbdannenberg commented 2 years ago

Can you test on an x64 architecture? If the problem is peculiar to M1, I can only inspect the code and don't think I'll find a problem. But if you can show what doesn't work on x64, I'd like to see it. Maybe this is obvious, but is the sender shutting down after the last message or pausing?

The IAC rate limit is undocumented, but I got some helpful information from someone at Apple. There's a possibility of creating an IAC loop that would cause the kernel to use 100% of a core just spinning messages around the loop, so when a certain rate is reached (around 5000 messages/sec), messages are arbitrarily dropped. On Linux ALSA you can send over 10000 mesages/sec, but PortMIDI limits you to about 4666 messages/sec through IAC ports.

StewMacLean commented 2 years ago

Unfortunately I'm not set up with Pharo on my x64 machine (I'm sometimes wondering why I'm making the move to the bleeding edge!).

Your comments regarding the IAC seem founded. Using Virtual Ports I am able to send messages continuously without using a delay fine. I just have to give it a bit of breathing space when opening them, and before shutting down the library to allow it all to flow through.

Thanks for the info re IAC. Now onto a bug with Logic not responding correctly to controller assignment playhead direct positioning messages...

On Thu, May 26, 2022 at 11:44 PM Roger B. Dannenberg < @.***> wrote:

Can you test on an x64 architecture? If the problem is peculiar to M1, I can only inspect the code and don't think I'll find a problem. But if you can show what doesn't work on x64, I'd like to see it. Maybe this is obvious, but is the sender shutting down after the last message or pausing?

The IAC rate limit is undocumented, but I got some helpful information from someone at Apple. There's a possibility of creating an IAC loop that would cause the kernel to use 100% of a core just spinning messages around the loop, so when a certain rate is reached (around 5000 messages/sec), messages are arbitrarily dropped. On Linux ALSA you can send over 10000 mesages/sec, but PortMIDI limits you to about 4666 messages/sec through IAC ports.

— Reply to this email directly, view it on GitHub https://github.com/PortMidi/portmidi/issues/30#issuecomment-1138444512, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXGQYQ473UCKQRDFTGJNXRTVL5PZJANCNFSM5W7DV7FA . You are receiving this because you authored the thread.Message ID: @.***>

rbdannenberg commented 2 years ago

I think this is resolved, but not sure. Reopen or contact me if I'm wrong to close this.