@Christoph-Hart found the culprit:
// if this is non-zero it means that the buffer coming
// from the DAW was split into chunks for processing
// so we need to update the playhead to reflect the
// "real" position for the given buffer
if(offsetWithinProcessBuffer != 0)
{
newTime.timeInSamples += offsetWithinProcessBuffer;
newTime.timeInSeconds += (double)offsetWithinProcessBuffer / processingSampleRate;
const auto numSamplesPerQuarter = (double)TempoSyncer::getTempoInSamples(newTime.bpm, processingSampleRate, 1.0f);
newTime.ppqPosition += (double)offsetWithinProcessBuffer / numSamplesPerQuarter;
}