MIDI output latency

Hi folks, I’m working on my first MIDI plug-in and experiencing the (apparently common) issue of dealing with latency with different buffer sizes. I had kind of expected that a DAW might recognize a relationship between a MIDI plug-in and an instrument being sequenced by it, and ensure that the MIDI plug-in’s processBlock executed first, but it appears not.

In this screenshot, I’ve lined up a few recordings to check latency. I’m checking my plug-in against Zoa, the popular iOS sequencer, at various buffer sizes. The tracks in the image are as follows:

  1. Zoa - buffer size 2048
  2. Zoa - buffer size 32
  3. Mine - buffer size 2048
  4. Mine - buffer size 32
  5. Mine - buffer size 512

As you can see, latency and performance generally get more stable with a lower buffer size, as the resolution of timing increases. However, I’m curious as to what Zoa is doing in the topmost track (buffer size 2048). The timing indeed slides, but it seems like it’s almost able to “right the ship” and get back on track.

Is there some way to accomplish this that I’m unaware of? If I had to guess, I’d expect that perhaps Zoa is just optimized and more efficient than my WIP plug-in, and therefore the output is able to “catch up” to real time. But I’m not sure if there’s a process that could help with keeping the timing locked more?

I’m also wondering if it might be wise to “cheat” on the timing of my MIDI buffer and try to get ahead of the instrument. In DAWs where the buffer size appears stable (e.g. the buffer provided in processBlock is always sized to samplesPerBlock provided in prepareToPlay), perhaps I could process one buffer ahead of time? That way, rather than the MIDI plugin and the instrument processing block N at the same time, my MIDI plugin could jump ahead and process/output block N+1. I’m not sure if this would be wise at all, since I know that the size of processBlock’s buffer is not guaranteed to be consistent - though in my experience, it’s stable in most DAWs.