getCurrentPosition in AAX_wrapper reports ppqPosition without delay compensation

Hi! I noticed that the getCurrentPosition function in the AAX wrapper reports the ppqPosition without taking delay compensation into account. This seem to be because “GetCurrentTickPosition” is used instead of “GetCustomTickPosition” from AAX_ITransport.

This will cause any plugin that uses that information to play MIDI to play it before everything else that is delay compensated.

Have you seen this thread:

Are you on Windows or MacOS?

I just tested on MacOS and in a session with a compressor with 27 samples of delay compensation on a track, I instantiated my plug-in on a stereo Aux Track and create a MIDI note on a MIDI Track… I triggered my plug-in and it recorded the output sample, sample accurate to the MIDI note.

Rail

On mac. Try adding a plugin with longer latency. We are developing a plugin that has an internal MIDI track and if we use the ppq position that we get from AudioPlayHead::getCurrentPosition to trigger internal MIDI it plays the notes to early (by as many samples as the introduced delay). I can test this by playing the same midi from the internal track and on the pro tools track (syncing to host). In our previous products (EZdrummer 2 for example) this works because that wrapper uses GetCustomTickPosition, and if I change to that in the juce aax wrapper it works again.

You don’t want to be calling GetCustomTickPosition() too often… check the API docs.

Rail

Yes I saw that, but as far as I can tell that’s the only way to get the correct position info (with delay compensation) - unless you know of any other way of doing it?

@urax_34 what solution did you settle for in the end? Did you end up using GetCustomTickPosition()?

We’re seeing similar problems at high sample rates when the plug-in has a substantial latency (say, tens of milliseconds).

Switching from GetCurrentTickPosition() to GetCustomTickPosition() fixes the issues for us too.

As for performance: despite what the SDK says, it doesn’t seem to change much at all.
Using this PIP: TickPositionPerf.h (5.6 KB)
We did some profiling with Visual Studio in Release configuration with full optimisation, debug symbols turned on and left for about 20secs. Focused on the just the DSP thread with the above plug-in running, the results are below:

For GetCurrentTickPosition():

For GetCustomTickPosition():

Either way, if changing the wrapper to call the custom function instead still seems like the wrong thing to do, would it be possible to have the plug-in be able to choose which of those methods are called via the AudioProcessor or something like that?

We ended up using GetCustomTickPosition() when pro tools is playing and GetCurrentTickPosition() when it isn’t. The sample position that is used in GetCustomTickPosition() could have strange values in some special cases when not playing (when the “Bars|Beats” ruler is selected).

1 Like

I guess you modified your own fork of JUCE to do that?

Yes, we did a modification in the juce AAX wrapper.

Would be cool if the workaround could be added in the aax wrapper…

I see there was already one in the rtas wrapper for GetCurrentTickPosition() not working correctly

2 Likes

just for info, this has been fixed on the dev branch : https://github.com/WeAreROLI/JUCE/commit/379e8410fb21174682179f4ae44977e91cc92140
thanks tom!

1 Like