Pygame MIDI timing issue

Following up on this post, and with an explanation provided below, I’ve made a minimal reproducible example of the problem:

midi_latency_minimal_reproducible_original.py (1.2 KB)

You’ll also need to download this MIDI file to play (and update the file location in the .py file accordingly).

The problem:
The file plays a tune using a MidiPlayer class I’ve made using pygame, and the word ‘now’ prints on screen on the 8th note of the tune. However on a few participants’ computers the MIDI file is playing (approx 0.6s) late, meaning that ‘now’ is printing on the 7th note (or even the 6th note in one case). This isn’t happening on my computer, and doesn’t seem to be happening on several other people’s computers either.

Regardless of whether you can help overall, one thing that would be useful is to know which note ‘now’ prints in sync with on your system, so I can diagnose which systems this is happening on. It should be on the 8th note. With latency it might print on the 7th note (or even the 6th note). Where does it print for you, and what system are you using? The main participant having the problem is using Windows 10. I don’t have the issue myself, and I’m using MacOS Sierra.

Beyond that, there are a few other things to note:

• The latency seems to reduce a little when pygame.mixer.init(freq, bitsize, channels, buffer) and pygame.mixer.music.set_volume(1) are removed from the class. Here’s an example of this: midi_latency_minimal_reproducible_example_FIX1.py (1.1 KB)
• It’s been suggested that I try pygame.mixer.pre_init(freq, bitsize, channels, buffer) prior to pygame.mixer.init() but this doesn’t seem to make too much of a difference:
midi_latency_minimal_reproducible_example_FIX2.py (1.2 KB)
• Reducing the buffer size (in increments of 1024, 512, 256, 128… etc) doesn’t seem to help much. The participant tried it all the way down to 1!
• A mysterious quirk, which is difficult to explain, is when the if t >= 4.2 is updated to if t >= 0, ‘now’ should appear in line with the first note rather than the 8th note. As such, with latency, you’d expect ‘now’ to show up before the music even starts playing. However, it in fact prints in sync with the first note as expected without latency. But if t >= 0.6 also prints ‘now’ in sync with the first note - so the latency issue seems to kick into action there somehow. This is odd…
• Someone has suggested that it might be a rendering issue, with the notes perhaps rendered at a delay. But I’m not sure exactly what that means or how to go about fixing it?
• This is using Python 2.7

All help appreciated (even if it’s just helping me to diagnose which systems this problem is happening on)! Thanks everyone.