SpotlightKid / python-rtmidi

Python bindings for the cross-platform MIDI I/O library RtMidi
https://spotlightkid.github.io/python-rtmidi/
Other
348 stars 64 forks source link

delta timestamps are broken on macOS in current release (1.5.8) #204

Open dklghub opened 3 weeks ago

dklghub commented 3 weeks ago

on macOS, when rtmidi receives midi packages containing multiple midi messages, the callback is called multiple times with the same delta time value. this was fixed a couple of months ago in rtmidi here: https://github.com/thestk/rtmidi/commit/eafe2f72a6492e7156c6a4f2771eb7ceb264e97b

this is a major issue for code that requires accurate timing so a new release might be motivated.

SpotlightKid commented 3 weeks ago

Would you happen to have test case for this?

dklghub commented 3 weeks ago

my tests involve a hardware sequencer that play a pattern. sometimes several midi note events are transmitted within the same usb midi package. the package are split into separate messages by rtmidi and a callback are invoked several times, currently with the same delta time over and over. using a simple callback to print midi message and delta time:

def onMessage(self, message, deltatime):
    global  last_time
    t = time.time()
    mydelta = t - last_time
    print("deltatime: %.8f, real delta: %.8f"%(deltatime, mydelta), message)
    last_time = t

creates this output:

deltatime: 0.02554864, real delta: 0.02556992 [248]
deltatime: 0.02551050, real delta: 0.02551007 [248]
deltatime: 0.02386400, real delta: 0.02386785 [144, 53, 127]
deltatime: 0.02386400, real delta: 0.00003815 [146, 53, 100]   <--- deltatime should be 0
deltatime: 0.02386400, real delta: 0.00000906 [147, 43, 115]   <--- deltatime should be 0
deltatime: 0.02386400, real delta: 0.00000572 [150, 60, 92]    <--- deltatime should be 0
deltatime: 0.00161525, real delta: 0.00154710 [248]
deltatime: 0.02549727, real delta: 0.02550602 [248]
deltatime: 0.02386724, real delta: 0.02387094 [134, 60, 0]
deltatime: 0.00166769, real delta: 0.00164723 [248]
dklghub commented 3 weeks ago

midiout.send_message() seems to be limited to a single message which prevents local testing

actually this is a strange limitation within rtmidi as midi is just a data stream and i might want to be able to send 100 note on messages at the same time.