Engine.getPlayhead() functionality
-
PSA:
Engine.getPlayHead().ppqPosition
gets all jittery on JACK audio with a buffer size 1024 or greater.With playback stopped, the playhead at 0 and a buffer size of 1024, ppqPosition alternates between
0.02133333333333333 0.0
very quickly. The values are different depending on the buffer size
2048
0.02133333333333333 0.04266666666666667 0.064 0.0 0.02133333333333333 0.04266666666666667 0.064 0.0 0.02133333333333333 0.042666666666666
At 512 and below everything is fine.
-
@Simon said in Engine.getPlayhead() functionality:
JACK audio
Are you using Pipewire > JACK or just JACK?
-
@d-healey Hard to tell since pipewire pretends to be everything else, but given that I have it installed, I'm going to assume it's Pipewire > Jack.
-
@Simon said in Engine.getPlayhead() functionality:
given that I have it installed, I'm going to assume it's Pipewire > Jack.
Yeah it will, just wanted to know because I'm using it so this probably affects me :)
-
It looks like the variation is a multiple of a fraction of the buffer size in samples.
At 1024, timeInSamples() goes between 0 and 512.
At 2048, it goes 0, 512, 1024, 1536, back to 0
At 4096 it goes, predictably
-
I hoped this was Linux only but the behavior is identical on Windows ASIO!
-
Alright, I have no idea why that happens, can't find any mention of it in JUCE forums so I have to assume it's something HISE specific.
I am only using the position to check if the user jumps somewhere else in the timeline. This means I can just use timeInSamples to ignore any movements smaller than 4096 samples.
I would base it on the current buffer size, but unfortunately
Engine.getBufferSize()
doesn't get updated if you change the ASIO buffer size without a restart, so it can't be relied on.If you're looking to use the current playback time for something more musical... godspeed, let us know how it goes.
-
@Simon said in Engine.getPlayhead() functionality:
I am only using the position to check if the user jumps somewhere else in the timeline.
Can't you use the transport handler for this?
-
I don't think so? Maybe I misunderstood one of the methods, but there doesn't seem to be one that fires when the playhead is moved.
-
@Simon I think
setOnGridChange
but the docs are sparse so not sure. -
@d-healey I have that commented in my script as the first thing I tried, and I can't get it to fire atm, so I'm gonna assume it's something else.
-
@Simon You might have to call this first
setEnableGrid
but I just looked at the example snippet from the docs and onBeatChanged might do the trick... -
Assuming the doc entry is accurate, onBeatChange won't work as I need the exact position.
-
@Simon The reason is that HISE splits up buffers bigger than 512 into chunks of 512 samples - above 512 there's hardly any CPU benefits but the memory consumption gets annoying (plus there are a few ugly edge cases with the audio buffer size conflicting with the streaming buffers).
Now the problem is that for every 2048 sample buffer that comes in, it calls the internal processing function 4 times and each time the ppq is bumped to stay consistent with the actual DAW position - that is if the playback is running. If not, then it jitters around like you analysed.
You can temporarily deactivate this by setting
HISE_MAX_PROCESSING_BLOCKSIZE
to a bigger value, but the real fix shouldn't be too hard. Please open a github issue and refer to this topic so that it doesn't get lost. -
@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; }