Let’s say I want to something to occur at a frequency of 1 bar. The common advice is to count samples in the process block like the following
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition(pos))
const int numSamples = buffer.getNumSamples();
const auto timeInSamples = pos.timeInSamples;
const auto samplesPerBeat = int64(sampleRate * (60 / pos.bpm));
const auto onBarSample = 4 * samplesPerBeat;
const int64 linearSamplePos = timeInSamples % onBarSample;
const int64 samplesBeforeLoop = onBarSample - linearSamplePos;
if (samplesBeforeLoop < numSamples)
// Do something at samplesBeforeLoop
But this only tells me at what sample position in the current buffer something will happen. How would I go about scheduling something to happen at that sample position in real time? Like looping my own playhead or something.
it’s easier to do this with the project position’s ppq instead of timeInSamples, because that yields a number where every integer is a full quarter note. so you can write ppq - floor(ppq) to get a number between 0 and 1 that represents where in this quarter note you are. that looks an awful lot like a phasor of an oscillator so you can write code around that that takes this phase value and just moves on. you need to take the bpm into account for that. i keep having to look up the exact formulas myself, but it’s not too hard. once you have a phasor you can just take the moment where it wraps from 1 to 0 and take that as your trigger moment.
tipp: output the phasor as audio signal so you can use an oscilloscope in your debug daw to check if it works correctly visually.
now you can just multiply the ppq with some value before doing ppq - floor(ppq) in order to use different beat values than quarter notes. for example ppq * .25 is a full bar. increment speed also then has to be adjusted to work with the new setting. that’s why i would suggest implementing this without variable speed first.
Be aware of some DAWs not providing ppq, timeInSamples is generally accepted to be provided by all DAWs. Also, some DAWs provide -ve ppq values (Logic does when looping iirc, or was it Bitwig - one of them, anyway) so needs to be taken into account.