Get tempo and time infos in Logic

Hello everyone,

I’m writing a sequencer for Logic and I got stuck when trying to get the time and tempo infos from Logic.
It works when I call the getPlayHead()->getCurrentPosition (newTime) from the processBlock() method but not from a timerCallback(), it returns zeros for all the data…

Any idea why?

Is it an AU? Not sure whether AUs get access to as much tempo detail as the VST wrapper. Debug into the playhead and you should be able to watch it getting its data.

It is an AU yes.
It seems that the thePlayHead->getCurrentPosition(newTime) won’t fill the data properly if it’s called from a timerCallback() but will do it nicely from the processBlock().
Do go deeper in the debug I noticed that
if (CallHostBeatAndTempo (&info.ppqPosition, &info.bpm) != noErr) from a timerCallback() will not return an error but won’t update position and bpm neither. If i debug even deeper inside CallHostBeatAndTempo my Xcode will just crash…

I’m guessing that Logic doesn’t allow any plugin instance to get the host data outside the processBlock time allocated?
Would that mean that I can not access host data if my plugin is just a midi sequencer and doesn’t require a processBlock() implementation?

thanks for the help

Sorry, perhaps I forgot to mention in the docs that it must of course only ever be called from the processing callback. It wouldn’t make sense to call it from any other thread, even if it was possible.

FWIW, implementing a MIDI sequencer using a timer is quite wrong.
You should do this using sample accurate timing in the process function.

Thanks Jules, everything make sense now.

Otristan, you are completely right, I now need to implement the timing thanks to the playHead and other host timing infos.

Thanks a lot

Bump for question: How do you grab the tempo/BPM from Logic before the transport is started in Logic? As soon as the transport is started, things work for me, but before then things can get hinky.

Short answer: you can’t assume that transport data will be valid outside processBlock or the processBlock will be always called.

Some tips related mostly to Logic (though also PT sometimes shuts your processBlock/audio thread).

  • Store latest known state so you can use it as a raw assumption when audio callback is idle.
  • If all you need is BPM, keep last bpm in your plug-in state. so when project is loaded your plug-in would still try to show valid values.
  • If you need to indicate or calculate values and show them to user. listen to parameters and internally. don’t assume the callback is being called. (eg - you calculate BPM to milliseconds…).
1 Like