Just an exploratory thread discussing possible improvements and workarounds, in case others are in the same boat as me.
I’m using GP to run backing tracks for my band. I export stems from Logic, load them into dedicated streaming file players, sync them all up to the global playhead, and it works great.
In addition to this, I use the same Logic session to create a MIDI track for sending messages to my pedalboard (for turning effects on and off, expression pedal sweeps, preset changes, and so on). I export this as a midi file and load it into a MIDI player in the same GP rackspace, sync that to the global playhead, and it passes MIDI in time with the track.
My question concerns the MIDI player and its relation to buffer size:
As I was experimenting with this, it looks like the MIDI messages are not actually passed as the playhead passes the message in the MIDI file, but actually at the buffer boundary of the buffer that happens to contain the message (not sure if it’s always at the end of the buffer, always at the start of the buffer or whichever one is closest).
In practise, this means that if I increase the buffer size to reduce possible audio glitches from the audio players, my pedalboard patch changes drift more and more out of time with the music, so I have to find the balance between consistent audio performance and “close enough” MIDI messaging.
My best attempt at the math describing the consequences I’ve experienced:
Buffer “length” at 48kHz sample rate:
- 128 samples → 128 / 48000 = 2.67 ms
- 2048 samples → 2048 / 48000 = 42.67 ms
One set of messages that I pass to the board at the start of every song is a set of tap tempo messages, aligned to the grid:
Say the song is 130 BPM. One beat = 60000 / 130 = 461.5 ms between taps. Each tap gets snapped to the buffer grid, so each measured interval can be off by up to ±one buffer period.
At 128 samples, the possible interval range between taps is roughly 458.8 ms to 464.2 ms (461.5 +/- 2.67ms). This gives the pedalboard a received BPM range of 129.3 to 130.8 BPM (60000/464.2 to 60000/458.8)
At 2048 samples, the interval range is now huge: ~418.8 ms to ~504.2 ms, which means the pedalboard could now end up with a tempo setting of anywhere from 119.0 to 143.3 BPM when processing the tap messages. Not great if I need my delays and other effects to stay in time with the music.
The same timing issue hits if I need a patch change to land exactly on a downbeat. At 2048 samples, that means a possible timing offset of 42.67ms, which translates to somewhere around a 32nd note at 130bpm. That means that the attack of that downbeat chord could get swallowed completely if you’re unlucky with your buffer timing.
Disclaimer: I know I can use markers in GP instead of the MIDI player for this, but there are two problems with that approach:
- There’s no grid in the streaming file player UI that I can use to align my messages with, so I have to painstakingly find the timestamp for each message and place it manually based on that.
So a possible improvement there would be to display a grid there and maybe even give us a “snap messages to grid” option. This would of course require the UI to know the bpm of the file, so that would need to be a setting in some way. I use the song properties to set the BPM of each song, and the song part actions to load the correct audio file in the file players, so I’m not sure how this grid could work in practise since the file player UI doesn’t know any of this information. Anyway, just a thought. - Adding things like expression pedal sweeps, where I literally pass dozens or hundreds of CC messages in a row for a few bars, would take hours to do using markers. In Logic, I can just draw them into a MIDI region in seconds, or just perform the sweep manually and record the automation.
I’m sure there are technical reasons why it’s hard to pass a MIDI message right at the correct time (when the playhead actually passes it). You would probably also somehow need to make sure that the MIDI player doesn’t actually start passing messages right away, but waits an entire buffer size before playing (so that it stays in sync with the audio players), which is probably a whole headache in its own right. But I figured it was worth at least making a post for it.

