I’m working on a sequencer inside my plugin today, and the clock/sync problem stops me from moving forward. Like all other sequencers, I need to get accurate timing of the quantization time(1/4 note, 1/16 1/32…etc)
Two approaches I’ve tried:
getting AudioPlayHead in audio thread, i.e. processNextBlock(), and get the ppq info.
Fail reason: the host call this to fill buffer every 256 samples(in my case, logic with default 256 samples buffer), so there are always a few ticks gone with this latency
use sample to count time, also in processNextBlock(), of course.
Fail reason: it’s not an integer after converting the quantization to samples, say, 45.12345 samples is a 1/16 note, but sample counting is just incrementing 1 continuously, no fractions, so I have to truncate the float to int(45.12345 to 45). Then the sync with the host will drift after some playing or recording.
First time to make a sequencer, I believe there’s a generic solution since many plugins I’ve seen have a sequencer and sync very well. Wondering how they make that.
You might be able to prevent drift by storing the offset (e.g. 0.12345 ) when you round down, and then incorporating that into your position calculation the next time, before truncating. That way you will have a sub-sample amount of jitter each time but no accumulating drift.
the musical time is not an integer (relative to the sample-clock). Perhaps using a ‘double’ to represent musical time, and rounding to integer as needed is a better solution.
We have a few plugins that sync to the host.
We calculate the current phase with the AudioPlayHead once in the processNextBlock function to sync to the host. After that we increment the phase in the process block with the calculated increment value (the value may be calculated with the bpm).
i wish i could look at my code and just drop it here for you but if i remember right for each block you get bpm /60 to get beats per sec. then you know for each sampleRate secs you get that amount of beats in quarter notes. multiply by 4 to get the amount of bars and then you can multiply with your rate measure like 1/16 on the ppq. then you’d go newPpq - floor(newPpq) to get the phase. as already mentioned, increment value is also something with bpm and your rate measure. then you can increment the phase for each sample with that inc value. whenever the resulting signal goes back from 1 to 0 a new beat of your measure started
sry if there are any logic errors in this comment but it does work somewhat like this