AudioPlayhead::CurrentPositionInfo determining position in bar


I have a plugin that depends on syncing to the playhead position within a beat and the beat in the bar.

My question is about hosts that do not populate ppqPositionOfLastBar.

In that situation you only have ppqPosition to go on and any odd time sig changes e.g. 7/8 back to 4/4 will throw even the beat count off by 0.5 when counting beats in the 4/4 section.
Bar starts will be affected by any time sig change.

Wondering how people handle this situation ?

I read in the documentation the pro tools doesn’t populate this field so I am wondering if I am missing something.

Hey, I’m running into the same problem here and wondering if you, or anybody else, has figured out a reliable solution to this?

In situations where we can get a real value for ppqPositionOfLastBarStart, I think we can easily identify where we are within the current bar:

if (hostInfo.ppqPositionOfLastBarStart > 0.)
    auto barLengthInQuarterNotes = hostInfo.timeSigNumerator * 4. / hostInfo.timeSigDenominator;
    auto positionInBar = (hostInfo.ppqPosition - hostInfo.ppqPositionOfLastBarStart) / barLengthInQuarterNotes;

However, when we can’t get a real value for ppqPositionOfLastBarStart I don’t see a reliable way forward. My current code for this case looks like this:

    auto barLengthInQuarterNotes = hostInfo.timeSigNumerator * 4. / hostInfo.timeSigDenominator;
    auto numBarsElapsed = hostInfo.ppqPosition / barLengthInQuarterNotes;
    auto positionInBar = numBarsElapsed - std::floor(numBarsElapsed);

Unfortunately, as you pointed out, this code carries the implicit assumption that the current time signature information is the same time signature that has been in use since the beginning of the track. That assumption could obviously be wrong, but we don’t get enough information to determine that.

So is there a better way to go about this? Am I missing something? Without being able to confidently calculate my position within the current bar, my sync behavior gets messed up.

A little more research…

It seems like there’s not really a good answer to this question, and that plugin developers are all sort of independently coming up with various ways to mitigate or step around the problem.

Hoping that’s not truly the case but that’s my read on the situation currently :slight_smile:


Been a long time since I posted that, but I got an email alert and recalled having the issue and it piqued my interest.

I have checked the plugin I was developing at the time and it looks to be working fine time positionally with changes thrown at it including time sig and tempo - but can only check with Cubase which I use as a guitarist and musician rather than a dev - so Cubase might be populating bar changes.

I had more hosts going when I was developing and asked that question.

Will have to go through the code in detail to see what my solution was (if any)

I am still very involved in audio apps as a musician but as a C++ dev I am freelancing outside audio atm - so it will be w/e at the earliest

1 Like

Hey yea no worries, would love to see what you came up with whenever you get around to it!

I have the fun of looking at this now and thanks @ncthom for coming up with some solutions. Annoyingly, I don’t think ppqPositionOfLastBarStart is even reliable when changing time signature in Logic Pro. I put some code in to check when the time sig changes and put in a break point.

See the attached image: I’m not sure I understand the arithmetic.

The red numbers are my annotation. I’ve got 8 bars of 4/4 followed by a time sig change to 3/4. You can see that ppqPositionOfLastBarStart=30 but really it should be 32 as we just entered that first bar of 3/4 and ppqPosition is just over 32 (not really sure why this isn’t bang on 32 TBH).

Anyway, I’d be curious if anyone found out any more over the past 12 months or so… I’ve report any findings back here if I make any headway.

I’m reviving this as I think it’s possible to fix it in Pro Tools?

JUCE mentioned the following in the docs:

        Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
       it's not available, the value will be 0.

blamed to Jules @ 2009 which is even before AAX exists… (PT10 was released in 2011 when googling).

But the AAX SDK seems to have ability to get/calculate last bar named GetBarBeatPosition.

Here is a hacky change I’ve made (though I guess we can calculate instead of just pasting the ppq in this callback which might be a little off):

            // No way to get these: (?)
            info.isRecording = false;
            int32_t bars = 0;
            int32_t beats = 0;
            // ticks defined above
            check (transport.GetBarBeatPosition (&bars, &beats, &ticks, info.timeInSamples));
            if (beats > 1)
                isNewLastBar = true;
            if (beats == 1 && isNewLastBar)
                info.ppqPositionOfLastBarStart = info.ppqPosition;
                isNewLastBar = false;

Would be great if the JUCE team could add this support and make the some ONEs better :slight_smile:


Sorry for bumping this, since this is between an FR and bug request which isn’t easily available with latest github issues options (that redirects you back to the forum).

Would be great if JUCE team would finally get aax on par for decent bar beats sync when signature changes.

@reuk , apologizes for pinging you.
But since you’re already into the AAX Wrapper context.

Since this was written the approach above was deprecated.

But LV2 introduced getBarCount() optional.
It seems the easy (and rightful) way would be using AAX’s GetBarBeatPosition and:

  • set the bar position to the optional bar count.
  • add a new getter/setter for optional beat position.
  • optional: lastBarPPQPosition can be calculated from the provided data.
1 Like

Thanks for reporting. I’ve added support for ppqPositionOfLastBarStart to the AAX client wrapper.


Great! more JUCE flavoured plug-ins could now play right on time! :slight_smile:

1 Like