AudioPlayHead Implementation

Hi, I’m trying to implement my own AudioPlayHead class for my DAW project. Thought it would be a good idea to gather some ideas and advice from the community on how to implement its getCurrentPosition method (thought about a time callback for updating the current position).

Haven’t ever looked at making a host but I don’t think using a timer is the right way to do that. What if the user skips back/forward to another part in the track, your timer would be out-of-sync.

Audio is processed block-by-block and so you should already know what the block size is and the sample rate, so you can simply work out the current possition by counting the number of blocks.

currentPositionSeconds = (currentBlockIndex * blockSize) / sampleRate;
1 Like

As @ImJimmi suggested,
Position is temporal to audio callback.
You don’t need a separate timer. just add to it each time you get called in the audio block.

If you plan on doing this for allowing plug-ins to ‘sync’ with you,
Remember to implement it as much as possible.

  • sample position
  • seconds position
  • ppq
  • bpm

etc…

The blocksize is not guaranteed. Your derivative version of Audioplayhead could have a member that holds the position in samples. In your getNextAudioBlock callback you could do this:

void getNextAudioBlock(const AudioSourceChannelInfo& bufferToFill) override
{
    //handle transport playhead
    AudioPlayHead::CurrentPositionInfo playheadInfo;
    m_playhead.getCurrentPosition( playheadInfo );

    //if we are playing count samples
    if( playheadInfo.isPlaying || playheadInfo.isRecording )
    {
        m_playhead.setSamplePos( playheadInfo.timeInSamples + bufferToFill.numSamples );
    }
}

The CurrentPositionInfo should be filled by your own Audioplayhead implementation. You can easily calculate all informations by the num of samples and the sampler ate.

Thank you all for the replies!
I’ll try it now and update how it goes

is there a reason that counting blocks, with potentially variable block sizes, is preferable to a simple sample count?

Obviously if you’re counting samples from the beginning of the project forward, you’ll end up with huge numbers, but the upside is that you have a linear, absolute timeline with known, consistent step sizes and you can skip around all you want without losing relative placement.

Using currentBlockIndex * blockSize, not only would you incur the multiplication overhead every callback, but wouldn’t this also mean that you’d have to store somewhere a record of the size of every previously rendered block? And what if the user skips the playhead back to a point in the past that’s somewhere in the middle of a previously rendered block?

@baramgb had the same advice, I’m just curious if there’s a reason why this would not be the best way…

Surely if you’re writing your own host then you’re in control of the block size, no? I’ve never done anything with hosts myself so I might be wrong.

1 Like

I mean, I never have either. I’m assuming that if Ableton varies its block sizes, there must be a fairly good reason…

You don’t have the absolute control of the blocksize. Even if you write your own host. This is up to the audio driver.

Edit: as far as I know. :face_with_raised_eyebrow:

2 Likes

ah, because even the host is at the mercy of the block sizes being sent to it from its input sources, right?

I’m happy to update that I successfully implemented the DAW’s playback functionality.
Wouldn’t be able to do it without your help so thanks a lot!!!

2 Likes

congrats!!