I'm building a simple MIDI input for my instrument with recording and playback, and I'm trying to address the very issue of MIDI jitter as outlined here by mystran.mystran wrote: Fri May 06, 2022 3:25 am Some DAWs insist on playing live MIDI notes "as soon as possible" which effectively means accurate timestamps are ignored live and everything rounded to the beginning of the next available block. This lowers the average latency slightly, but means there is one full block of jitter. Personally I find such jitter highly irritating, because it's essentially random so you can't really compensate (not to mention that what you hear on later playbacks don't match what you heard when you were playing). In a DAW that insists on doing this, even 256 samples at 44.1kHz feels kinda terrible for me, where as if we add pure latency (eg. with a delay plugin) with no jitter whatsoever I can easily tolerate at least another 20ms just fine.
Currently I'm doing this by taking the current host timestamp at the start of the AURenderCallback, and using the difference with the MIDI events timestamp to calculate an anti jitter frame offset for the to-instrument event.
However the inTimeStamp provided by AURenderCallback has me confused. It seems to provide a "buffer to analog signal" time (about 13ms in the future for a 512 frame buffer), but I can't figure out a way to use that meaningfully, or if I should be at all. Any advice/alternative approaches are appreciated.
FWIW my current solution seems to be giving very consistent results. I'm just wondering if there's a more "correct" way (using CoreAudio/CoreMIDI frameworks or otherwise).
Code: Select all
afi:507511, afi_delta:22052
afi:551612, afi_delta:22050
afi:573662, afi_delta:22050
afi:595709, afi_delta:22047
afi:617760, afi_delta:22051
afi:639810, afi_delta:22050
(Spin lock timer producing MIDI events on a dedicated thread every 500ms)
afi:187310, afi_delta:221
afi:187529, afi_delta:219
afi:187749, afi_delta:220
afi:187970, afi_delta:221
afi:188191, afi_delta:221
afi:188411, afi_delta:220
(Spin lock timer producing MIDI events on a dedicated thread every 5ms)
afi:322470, afi_delta:881
afi:323352, afi_delta:882
afi:324235, afi_delta:883
afi:325117, afi_delta:882
afi:325999, afi_delta:882
afi:326881, afi_delta:882
(Spin lock timer producing MIDI events on a dedicated thread every 20ms)