Newb - processBlock() buffers, how do I calculate when "one measure" of audio data has come in?

My goal is to copy exactly one measure (one bar) of audio from the buffer in processBlock() to another memory location.

I guess my calculation will have something to do with buffersize, BPM info from DAW, SampleRate, BitRate? For arguments sake, lets say our time signature is 4/4.

I’m guessing the processBlock() will have to run multiple times before one measure of data is accrued.

How would you go about working out how much bufferdata = one measure?

you’d use this stuff, but depending on how and when it should be captured the code would be structured differently. the currentPostionInfo’s ppqPosition gives you the representation of project position in quarter notes. but practically you can’t endlessly let it record, so maybe make a system where a button activates and stops the recording to test it first or something like that. it’s quite easy to get a feeling for it after that

1 Like

bpm = beats / minute
beats per second = bpm / 60

samplerate = samples / second

samples per beat = samplerate / beats per second

samples per measure = samples per beat * 4

Then just count samples in processBlock until you reach that many samples. Note that it’s highly unlikely that your measure actually starts on sample zero of your first processBlock, so you’ll need to account for that too.

1 Like

This is a simple matter of transforming a time in seconds into a corresponding sample count.

You can easily compute the duration in seconds for one bar at your given BPM. Then, the sample rate as reported to you in the prepare callback says you how many samples represent one second of audio. Multiplying that rate with the desired interval in seconds gives you the exact sample count you need. Pre-Allocate an audio buffer of that size in your prepare method and copy over the desired number of samples in the processBlock callbacks from the buffer passed to you. It might be possible that it would take multiple proccessBlock callbacks or even one processBlock callback could contain more data then you need, you have to handle all scenarios.

By the way, the BitRate is irrelevant for you, this is only about the dynamic resolution, not the time resolution of your audio. Furthermore, inside a plugin, audio is alway processed as normalised 32Bit floating point values (64Bit doubles are possible too, but not the standard), so from that point of view, the BitRate is always fixed

1 Like

This is the other question in my mind. I want the copy only to start when the playhead is on the “measure boundary” .
I am guessing the playHeadPosition() might give me that. But I wonder if playHeadPosition() tells me how much time (or how many samples to go) until the next measure boundary, and how I work that out…

…assuming the time signature is 4/4. :slight_smile:

…assuming the time signature is 4/4.

If a plugin was catering to EDM people, I wonder if I could assume (I’m guessing) 95% of music there would be 4/4.

In your processBlock

// this _must_ be called from AudioProcessor::processBlock(...)
if (auto playhead = getPlayhead(); playhead) { 
  // getPlayhead may not return a valid pointer, if the host/plugin API doesn't support this feature. 
  // make sure you log whether or not this block is executed at all in hosts you care about. 
  CurrentPosition position; 
  if(playhead->getCurrentPosition(position)) {
    // getCurrentPosition may return `false` if it fails. 
    // now you have a CurrentPosition instance with data in it. Use it and the sample rate, 
    // and buffer size to figure out: 
    // - should start/top recording into a buffer
    // - how far to advance the write index into your buffer.  

Remember to preallocate space for your recording buffer. Except in exceptional cases you can almost certainly guarantee that the buffer size is smaller than a single measure, and the start/stop of a measure is in the middle of a buffer.

1 Like

thanks, I had a feeling it would be.
In terms of playhead current position and wiating for a measure (or bar) boundary before I start a buffer copy, I did find this:

I guess I can use this to determine where the playhead is in relation to the next bar/measure boundary.

Just remember, as that note in ppqPositionOfLastBarStart says, it may not be available on all hosts, Pro Tools being especially noted.

just let a saw oscillator play at the rate of the measure so that the sample where 1 goes to 0 is the exact trigger of whatever this sequencer is supposed to do. in this case start or stop recording from the audio buffer