Hi! I want to detect if the playback is ‘‘continuous’’ from the plugin (continuous: playback is not moved forward/backward manually, which from my point of view is different from PositionInfo.getIsPlaying()).
I come up with the following solution (pseudocode):
void process(juce::AudioBuffer<float> &buffer) noexcept {
auto currentPos = processor->getPlayHead()->getPosition()->getTimeInSamples().orFallback(0);
// previousPos is initialized as -1 (int64_t) in the constructor
// isContinuous is initialized as true (bool) in the constructor
if (currentPos - previousPos != spec.maximumBlockSize && currentPos - previousPos != 0 && previousPos != -1) {
isContinuous = false;
} else {
isContinuous = true;
}
previousPos = currentPos;
// do something else to buffer
}
Does this solution look good to you (assume that the DAW provides PositionInfo)?
You can’t rely on maximumBlocksize to check continuity, as the host can provide any (and variable) block size for every processBlock().
But what you can do is take the playhead position in samples, add the number samples in the process block and save that as an “expected next sample position”. In the next processBlock() you can check against the expected position and if it doesn’t match you have a discontinuity.
This smells like something that should be thoroughly tested with different hosts though. Maybe check if there are occasional “off by 1” false positives, which I could imagine happening if the sample time in positionInfo is computed from something else.
1 Like
if isPlaying, then it’s just current position. else it’s current position + numSamples
Have to be careful with this one. I’ve seen in at least one host that the playhead reported time can drift. This was about a year ago so it may have been since fixed in JUCE/Cubasis 3 but I had to add in a threshold of drift (approx 30 samples) - if it drifted outside those 30 samples (each way from expected number) I could be relatively confident that the playhead had been manually moved.
I think there were 1 or 2 other iOS hosts as well with the same issue.
Here is an example where I needed a timeline in the plugin. timeInSamples was my variable for tracking the timeline and I needed it to move smoothly so in problematic hosts I needed to also let it drift.
if (!juce::JUCEApplicationBase::isStandaloneApp())
{
auto pos = getPlayHead()->getPosition();
expectedTime = timeInSamples + lastBufferSize;
timeInSamples = *pos->getTimeInSamples();
if (expectedTime != timeInSamples)
{
if (std::abs(timeInSamples-lastTime) < 30 && pos->getIsPlaying())
{
timeInSamples = expectedTime;
}
}
}
2 Likes
true tho. i noticed a drift of max 1 sample in bitwig sometimes too and that was like a month ago or so
1 Like
@hugoderwolf @Mrugalla @DavidCNAntonia Many thanks to you all. Using lastBufferSize
and tolerating a small drift seems like a perfect solution
Yep, ±1 sample is what I would expect if the provided numbers are somehow computed back and forth by the host instead of synced to the audio driver. But 30 samples drift (from one block to another???) sounds like a lot!
1 Like
while we are at it :3 i made a video not long ago about an LFO whose phase always depends on rate, bpm and ppq and that thing also required this exact calculation because i needed it to trigger a crossfade:
Yeah, it was a surprise when I figured out what it was. I had a bug report of audible clicks in modulation which was being set by the host reported sample position. Turned out it was all over the place so kept jumping around in time at the end of each buffer - pretty nasty!
Hi! Note that many DAWs support automating tempo continuously.
If BPM changes between blocks, predictions become unreliable, because the plugin just doesn’t get enough information to really know what’s going on. Another special case to handle, plus loops, stopped playback, signature changes, etc.
It gets even more fun if for some reason you need to delay or predict the playhead position internally, e.g. for latency compensation somewhere within the signal chain inside of your plugin. Best come up with all kinds of crazy test cases.
Thanks for the video @Mrugalla - good strategies for coping with tempo sync!
1 Like
simon
September 22, 2023, 3:44pm
11
Hi
So this works great in Pro Tools and Studio One.
In Ableton tough, it seems both timeInSamples and timeInSeconds is non-linear when the tempo is changing??
See this simple example where the tempo changes from 135 to 194 on bar 3:
With a block size of 2048, these are the values I get in ProcessBlock():
(one entry per block)
blockInfoLogs = {
[0] = {
lastBarPpqPosition = 0
ppqPosition = 0
timeInSamples = 0
timeInSeconds = 0
bpm = 135
isRecordingOrPlaying = 1
}
[1] = {
lastBarPpqPosition = 0
ppqPosition = 0.096000000000000001
timeInSamples = 2048
timeInSeconds = 0.042666666666666665
bpm = 135
isRecordingOrPlaying = 1
}
[2] = {
lastBarPpqPosition = 0
ppqPosition = 0.192
timeInSamples = 4096
timeInSeconds = 0.08533333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[3] = {
lastBarPpqPosition = 0
ppqPosition = 0.28800000000000003
timeInSamples = 6144
timeInSeconds = 0.128
bpm = 135
isRecordingOrPlaying = 1
}
[4] = {
lastBarPpqPosition = 0
ppqPosition = 0.38400000000000001
timeInSamples = 8192
timeInSeconds = 0.17066666666666666
bpm = 135
isRecordingOrPlaying = 1
}
[5] = {
lastBarPpqPosition = 0
ppqPosition = 0.47999999999999998
timeInSamples = 10240
timeInSeconds = 0.21333333333333335
bpm = 135
isRecordingOrPlaying = 1
}
[6] = {
lastBarPpqPosition = 0
ppqPosition = 0.57600000000000007
timeInSamples = 12288
timeInSeconds = 0.25600000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[7] = {
lastBarPpqPosition = 0
ppqPosition = 0.67200000000000004
timeInSamples = 14336
timeInSeconds = 0.29866666666666669
bpm = 135
isRecordingOrPlaying = 1
}
[8] = {
lastBarPpqPosition = 0
ppqPosition = 0.76800000000000002
timeInSamples = 16384
timeInSeconds = 0.34133333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[9] = {
lastBarPpqPosition = 0
ppqPosition = 0.86399999999999999
timeInSamples = 18432
timeInSeconds = 0.38400000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[10] = {
lastBarPpqPosition = 0
ppqPosition = 0.95999999999999996
timeInSamples = 20480
timeInSeconds = 0.42666666666666669
bpm = 135
isRecordingOrPlaying = 1
}
[11] = {
lastBarPpqPosition = 0
ppqPosition = 1.056
timeInSamples = 22528
timeInSeconds = 0.46933333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[12] = {
lastBarPpqPosition = 0
ppqPosition = 1.1520000000000001
timeInSamples = 24576
timeInSeconds = 0.51200000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[13] = {
lastBarPpqPosition = 0
ppqPosition = 1.248
timeInSamples = 26624
timeInSeconds = 0.55466666666666664
bpm = 135
isRecordingOrPlaying = 1
}
[14] = {
lastBarPpqPosition = 0
ppqPosition = 1.3440000000000001
timeInSamples = 28672
timeInSeconds = 0.59733333333333338
bpm = 135
isRecordingOrPlaying = 1
}
[15] = {
lastBarPpqPosition = 0
ppqPosition = 1.4399999999999999
timeInSamples = 30720
timeInSeconds = 0.64000000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[16] = {
lastBarPpqPosition = 0
ppqPosition = 1.536
timeInSamples = 32768
timeInSeconds = 0.68266666666666664
bpm = 135
isRecordingOrPlaying = 1
}
[17] = {
lastBarPpqPosition = 0
ppqPosition = 1.6320000000000001
timeInSamples = 34816
timeInSeconds = 0.72533333333333339
bpm = 135
isRecordingOrPlaying = 1
}
[18] = {
lastBarPpqPosition = 0
ppqPosition = 1.728
timeInSamples = 36864
timeInSeconds = 0.76800000000000002
bpm = 135
isRecordingOrPlaying = 1
}
[19] = {
lastBarPpqPosition = 0
ppqPosition = 1.8240000000000001
timeInSamples = 38912
timeInSeconds = 0.81066666666666664
bpm = 135
isRecordingOrPlaying = 1
}
[20] = {
lastBarPpqPosition = 0
ppqPosition = 1.9199999999999999
timeInSamples = 40960
timeInSeconds = 0.85333333333333339
bpm = 135
isRecordingOrPlaying = 1
}
[21] = {
lastBarPpqPosition = 0
ppqPosition = 2.016
timeInSamples = 43008
timeInSeconds = 0.89600000000000002
bpm = 135
isRecordingOrPlaying = 1
}
[22] = {
lastBarPpqPosition = 0
ppqPosition = 2.1120000000000001
timeInSamples = 45056
timeInSeconds = 0.93866666666666665
bpm = 135
isRecordingOrPlaying = 1
}
[23] = {
lastBarPpqPosition = 0
ppqPosition = 2.2080000000000002
timeInSamples = 47104
timeInSeconds = 0.98133333333333327
bpm = 135
isRecordingOrPlaying = 1
}
[24] = {
lastBarPpqPosition = 0
ppqPosition = 2.3040000000000003
timeInSamples = 49152
timeInSeconds = 1.024
bpm = 135
isRecordingOrPlaying = 1
}
[25] = {
lastBarPpqPosition = 0
ppqPosition = 2.3999999999999999
timeInSamples = 51200
timeInSeconds = 1.0666666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[26] = {
lastBarPpqPosition = 0
ppqPosition = 2.496
timeInSamples = 53248
timeInSeconds = 1.1093333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[27] = {
lastBarPpqPosition = 0
ppqPosition = 2.5920000000000001
timeInSamples = 55296
timeInSeconds = 1.1519999999999999
bpm = 135
isRecordingOrPlaying = 1
}
[28] = {
lastBarPpqPosition = 0
ppqPosition = 2.6880000000000002
timeInSamples = 57344
timeInSeconds = 1.1946666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[29] = {
lastBarPpqPosition = 0
ppqPosition = 2.7840000000000003
timeInSamples = 59392
timeInSeconds = 1.2373333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[30] = {
lastBarPpqPosition = 0
ppqPosition = 2.8799999999999999
timeInSamples = 61440
timeInSeconds = 1.28
bpm = 135
isRecordingOrPlaying = 1
}
[31] = {
lastBarPpqPosition = 0
ppqPosition = 2.976
timeInSamples = 63488
timeInSeconds = 1.3226666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[32] = {
lastBarPpqPosition = 0
ppqPosition = 3.0720000000000001
timeInSamples = 65536
timeInSeconds = 1.3653333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[33] = {
lastBarPpqPosition = 0
ppqPosition = 3.1680000000000001
timeInSamples = 67584
timeInSeconds = 1.4079999999999999
bpm = 135
isRecordingOrPlaying = 1
}
[34] = {
lastBarPpqPosition = 0
ppqPosition = 3.2640000000000002
timeInSamples = 69632
timeInSeconds = 1.4506666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[35] = {
lastBarPpqPosition = 0
ppqPosition = 3.3599999999999999
timeInSamples = 71680
timeInSeconds = 1.4933333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[36] = {
lastBarPpqPosition = 0
ppqPosition = 3.456
timeInSamples = 73728
timeInSeconds = 1.536
bpm = 135
isRecordingOrPlaying = 1
}
[37] = {
lastBarPpqPosition = 0
ppqPosition = 3.552
timeInSamples = 75776
timeInSeconds = 1.5786666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[38] = {
lastBarPpqPosition = 0
ppqPosition = 3.6480000000000001
timeInSamples = 77824
timeInSeconds = 1.6213333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[39] = {
lastBarPpqPosition = 0
ppqPosition = 3.7440000000000002
timeInSamples = 79872
timeInSeconds = 1.6639999999999999
bpm = 135
isRecordingOrPlaying = 1
}
[40] = {
lastBarPpqPosition = 0
ppqPosition = 3.8399999999999999
timeInSamples = 81920
timeInSeconds = 1.7066666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[41] = {
lastBarPpqPosition = 0
ppqPosition = 3.9359999999999999
timeInSamples = 83968
timeInSeconds = 1.7493333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[42] = {
lastBarPpqPosition = 4
ppqPosition = 4.032
timeInSamples = 86016
timeInSeconds = 1.792
bpm = 135
isRecordingOrPlaying = 1
}
[43] = {
lastBarPpqPosition = 4
ppqPosition = 4.1280000000000001
timeInSamples = 88064
timeInSeconds = 1.8346666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[44] = {
lastBarPpqPosition = 4
ppqPosition = 4.2240000000000002
timeInSamples = 90112
timeInSeconds = 1.8773333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[45] = {
lastBarPpqPosition = 4
ppqPosition = 4.3200000000000003
timeInSamples = 92160
timeInSeconds = 1.9199999999999999
bpm = 135
isRecordingOrPlaying = 1
}
[46] = {
lastBarPpqPosition = 4
ppqPosition = 4.4160000000000004
timeInSamples = 94208
timeInSeconds = 1.9626666666666666
bpm = 135
isRecordingOrPlaying = 1
}
[47] = {
lastBarPpqPosition = 4
ppqPosition = 4.5120000000000005
timeInSamples = 96256
timeInSeconds = 2.0053333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[48] = {
lastBarPpqPosition = 4
ppqPosition = 4.6080000000000005
timeInSamples = 98304
timeInSeconds = 2.048
bpm = 135
isRecordingOrPlaying = 1
}
[49] = {
lastBarPpqPosition = 4
ppqPosition = 4.7039999999999997
timeInSamples = 100352
timeInSeconds = 2.0906666666666665
bpm = 135
isRecordingOrPlaying = 1
}
[50] = {
lastBarPpqPosition = 4
ppqPosition = 4.7999999999999998
timeInSamples = 102400
timeInSeconds = 2.1333333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[51] = {
lastBarPpqPosition = 4
ppqPosition = 4.8959999999999999
timeInSamples = 104448
timeInSeconds = 2.1760000000000002
bpm = 135
isRecordingOrPlaying = 1
}
[52] = {
lastBarPpqPosition = 4
ppqPosition = 4.992
timeInSamples = 106496
timeInSeconds = 2.2186666666666666
bpm = 135
isRecordingOrPlaying = 1
}
[53] = {
lastBarPpqPosition = 4
ppqPosition = 5.0880000000000001
timeInSamples = 108544
timeInSeconds = 2.2613333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[54] = {
lastBarPpqPosition = 4
ppqPosition = 5.1840000000000002
timeInSamples = 110592
timeInSeconds = 2.3039999999999998
bpm = 135
isRecordingOrPlaying = 1
}
[55] = {
lastBarPpqPosition = 4
ppqPosition = 5.2800000000000002
timeInSamples = 112640
timeInSeconds = 2.3466666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[56] = {
lastBarPpqPosition = 4
ppqPosition = 5.3760000000000003
timeInSamples = 114688
timeInSeconds = 2.3893333333333335
bpm = 135
isRecordingOrPlaying = 1
}
[57] = {
lastBarPpqPosition = 4
ppqPosition = 5.4720000000000004
timeInSamples = 116736
timeInSeconds = 2.4319999999999999
bpm = 135
isRecordingOrPlaying = 1
}
[58] = {
lastBarPpqPosition = 4
ppqPosition = 5.5680000000000005
timeInSamples = 118784
timeInSeconds = 2.4746666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[59] = {
lastBarPpqPosition = 4
ppqPosition = 5.6639999999999997
timeInSamples = 120832
timeInSeconds = 2.5173333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[60] = {
lastBarPpqPosition = 4
ppqPosition = 5.7599999999999998
timeInSamples = 122880
timeInSeconds = 2.5600000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[61] = {
lastBarPpqPosition = 4
ppqPosition = 5.8559999999999999
timeInSamples = 124928
timeInSeconds = 2.6026666666666665
bpm = 135
isRecordingOrPlaying = 1
}
[62] = {
lastBarPpqPosition = 4
ppqPosition = 5.952
timeInSamples = 126976
timeInSeconds = 2.6453333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[63] = {
lastBarPpqPosition = 4
ppqPosition = 6.048
timeInSamples = 129024
timeInSeconds = 2.6880000000000002
bpm = 135
isRecordingOrPlaying = 1
}
[64] = {
lastBarPpqPosition = 4
ppqPosition = 6.1440000000000001
timeInSamples = 131072
timeInSeconds = 2.7306666666666666
bpm = 135
isRecordingOrPlaying = 1
}
[65] = {
lastBarPpqPosition = 4
ppqPosition = 6.2400000000000002
timeInSamples = 133120
timeInSeconds = 2.7733333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[66] = {
lastBarPpqPosition = 4
ppqPosition = 6.3360000000000003
timeInSamples = 135168
timeInSeconds = 2.8159999999999998
bpm = 135
isRecordingOrPlaying = 1
}
[67] = {
lastBarPpqPosition = 4
ppqPosition = 6.4320000000000004
timeInSamples = 137216
timeInSeconds = 2.8586666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[68] = {
lastBarPpqPosition = 4
ppqPosition = 6.5280000000000005
timeInSamples = 139264
timeInSeconds = 2.9013333333333335
bpm = 135
isRecordingOrPlaying = 1
}
[69] = {
lastBarPpqPosition = 4
ppqPosition = 6.6240000000000006
timeInSamples = 141312
timeInSeconds = 2.944
bpm = 135
isRecordingOrPlaying = 1
}
[70] = {
lastBarPpqPosition = 4
ppqPosition = 6.7199999999999998
timeInSamples = 143360
timeInSeconds = 2.9866666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[71] = {
lastBarPpqPosition = 4
ppqPosition = 6.8159999999999998
timeInSamples = 145408
timeInSeconds = 3.0293333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[72] = {
lastBarPpqPosition = 4
ppqPosition = 6.9119999999999999
timeInSamples = 147456
timeInSeconds = 3.0720000000000001
bpm = 135
isRecordingOrPlaying = 1
}
[73] = {
lastBarPpqPosition = 4
ppqPosition = 7.008
timeInSamples = 149504
timeInSeconds = 3.1146666666666665
bpm = 135
isRecordingOrPlaying = 1
}
[74] = {
lastBarPpqPosition = 4
ppqPosition = 7.1040000000000001
timeInSamples = 151552
timeInSeconds = 3.1573333333333333
bpm = 135
isRecordingOrPlaying = 1
}
[75] = {
lastBarPpqPosition = 4
ppqPosition = 7.2000000000000002
timeInSamples = 153600
timeInSeconds = 3.2000000000000002
bpm = 135
isRecordingOrPlaying = 1
}
[76] = {
lastBarPpqPosition = 4
ppqPosition = 7.2960000000000003
timeInSamples = 155648
timeInSeconds = 3.2426666666666666
bpm = 135
isRecordingOrPlaying = 1
}
[77] = {
lastBarPpqPosition = 4
ppqPosition = 7.3920000000000003
timeInSamples = 157696
timeInSeconds = 3.2853333333333334
bpm = 135
isRecordingOrPlaying = 1
}
[78] = {
lastBarPpqPosition = 4
ppqPosition = 7.4880000000000004
timeInSamples = 159744
timeInSeconds = 3.3279999999999998
bpm = 135
isRecordingOrPlaying = 1
}
[79] = {
lastBarPpqPosition = 4
ppqPosition = 7.5840000000000005
timeInSamples = 161792
timeInSeconds = 3.3706666666666667
bpm = 135
isRecordingOrPlaying = 1
}
[80] = {
lastBarPpqPosition = 4
ppqPosition = 7.6799999999999997
timeInSamples = 163840
timeInSeconds = 3.4133333333333336
bpm = 135
isRecordingOrPlaying = 1
}
[81] = {
lastBarPpqPosition = 4
ppqPosition = 7.7759999999999998
timeInSamples = 165888
timeInSeconds = 3.456
bpm = 135
isRecordingOrPlaying = 1
}
[82] = {
lastBarPpqPosition = 4
ppqPosition = 7.8719999999999999
timeInSamples = 167936
timeInSeconds = 3.4986666666666668
bpm = 135
isRecordingOrPlaying = 1
}
[83] = {
lastBarPpqPosition = 4
ppqPosition = 7.968
timeInSamples = 169984
timeInSeconds = 3.5413333333333332
bpm = 135
isRecordingOrPlaying = 1
}
[84] = {
lastBarPpqPosition = 8
ppqPosition = 8.0919479166666672
timeInSamples = 120128
timeInSeconds = 2.5026666666666668
bpm = 194
isRecordingOrPlaying = 1
}
[85] = {
lastBarPpqPosition = 8
ppqPosition = 8.2299034722222224
timeInSamples = 122176
timeInSeconds = 2.5453333333333332
bpm = 194
isRecordingOrPlaying = 1
}
[86] = {
lastBarPpqPosition = 8
ppqPosition = 8.3678590277777776
timeInSamples = 124224
timeInSeconds = 2.5880000000000001
bpm = 194
isRecordingOrPlaying = 1
}
[87] = {
lastBarPpqPosition = 8
ppqPosition = 8.5058145833333327
timeInSamples = 126272
timeInSeconds = 2.6306666666666665
bpm = 194
isRecordingOrPlaying = 1
}
[88] = {
lastBarPpqPosition = 8
ppqPosition = 8.6437701388888896
timeInSamples = 128320
timeInSeconds = 2.6733333333333333
bpm = 194
isRecordingOrPlaying = 1
}
[89] = {
lastBarPpqPosition = 8
ppqPosition = 8.7817256944444448
timeInSamples = 130368
timeInSeconds = 2.7160000000000002
bpm = 194
isRecordingOrPlaying = 1
}
[90] = {
lastBarPpqPosition = 8
ppqPosition = 8.91968125
timeInSamples = 132416
timeInSeconds = 2.7586666666666666
bpm = 194
isRecordingOrPlaying = 1
}
[91] = {
lastBarPpqPosition = 8
ppqPosition = 9.0576368055555552
timeInSamples = 134464
timeInSeconds = 2.8013333333333335
bpm = 194
isRecordingOrPlaying = 1
}
[92] = {
lastBarPpqPosition = 8
ppqPosition = 9.1955923611111103
timeInSamples = 136512
timeInSeconds = 2.8439999999999999
bpm = 194
isRecordingOrPlaying = 1
}
[93] = {
lastBarPpqPosition = 8
ppqPosition = 9.3335479166666672
timeInSamples = 138560
timeInSeconds = 2.8866666666666667
bpm = 194
isRecordingOrPlaying = 1
}
[94] = {
lastBarPpqPosition = 8
ppqPosition = 9.4715034722222224
timeInSamples = 140608
timeInSeconds = 2.9293333333333331
bpm = 194
isRecordingOrPlaying = 1
}
[95] = {
lastBarPpqPosition = 8
ppqPosition = 9.6094590277777776
timeInSamples = 142656
timeInSeconds = 2.972
bpm = 194
isRecordingOrPlaying = 1
}
[96] = {
lastBarPpqPosition = 8
ppqPosition = 9.7474145833333327
timeInSamples = 144704
timeInSeconds = 3.0146666666666668
bpm = 194
isRecordingOrPlaying = 1
}
[97] = {
lastBarPpqPosition = 8
ppqPosition = 9.8853701388888879
timeInSamples = 146752
timeInSeconds = 3.0573333333333332
bpm = 194
isRecordingOrPlaying = 1
}
[98] = {
lastBarPpqPosition = 8
ppqPosition = 10.023325694444445
timeInSamples = 148800
timeInSeconds = 3.1000000000000001
bpm = 194
isRecordingOrPlaying = 1
}
[99] = {
lastBarPpqPosition = 8
ppqPosition = 10.16128125
timeInSamples = 150848
timeInSeconds = 3.1426666666666665
bpm = 194
isRecordingOrPlaying = 1
}
[100] = {
lastBarPpqPosition = 8
ppqPosition = 10.299236805555555
timeInSamples = 152896
timeInSeconds = 3.1853333333333333
bpm = 194
isRecordingOrPlaying = 1
}
[101] = {
lastBarPpqPosition = 8
ppqPosition = 10.437192361111112
timeInSamples = 154944
timeInSeconds = 3.2280000000000002
bpm = 194
isRecordingOrPlaying = 1
}
[102] = {
lastBarPpqPosition = 8
ppqPosition = 10.575147916666666
timeInSamples = 156992
timeInSeconds = 3.2706666666666666
bpm = 194
isRecordingOrPlaying = 1
}
[103] = {
lastBarPpqPosition = 8
ppqPosition = 10.713103472222222
timeInSamples = 159040
timeInSeconds = 3.3133333333333335
bpm = 194
isRecordingOrPlaying = 1
}
[104] = {
lastBarPpqPosition = 8
ppqPosition = 10.851059027777778
timeInSamples = 161088
timeInSeconds = 3.3559999999999999
bpm = 194
isRecordingOrPlaying = 1
}
[105] = {
lastBarPpqPosition = 8
ppqPosition = 10.989014583333333
timeInSamples = 163136
timeInSeconds = 3.3986666666666667
bpm = 194
isRecordingOrPlaying = 1
}
[106] = {
lastBarPpqPosition = 8
ppqPosition = 11.12697013888889
timeInSamples = 165184
timeInSeconds = 3.4413333333333331
bpm = 194
isRecordingOrPlaying = 1
}
[107] = {
lastBarPpqPosition = 8
ppqPosition = 11.264925694444445
timeInSamples = 167232
timeInSeconds = 3.484
bpm = 194
isRecordingOrPlaying = 1
}
[108] = {
lastBarPpqPosition = 8
ppqPosition = 11.40288125
timeInSamples = 169280
timeInSeconds = 3.5266666666666668
bpm = 194
isRecordingOrPlaying = 1
}
[109] = {
lastBarPpqPosition = 8
ppqPosition = 11.540836805555555
timeInSamples = 171328
timeInSeconds = 3.5693333333333332
bpm = 194
isRecordingOrPlaying = 1
}
[110] = {
lastBarPpqPosition = 8
ppqPosition = 11.67879236111111
timeInSamples = 173376
timeInSeconds = 3.6120000000000001
bpm = 194
isRecordingOrPlaying = 1
}
[111] = {
lastBarPpqPosition = 8
ppqPosition = 11.816747916666667
timeInSamples = 175424
timeInSeconds = 3.6546666666666665
bpm = 194
isRecordingOrPlaying = 1
}
[112] = {
lastBarPpqPosition = 8
ppqPosition = 11.954703472222223
timeInSamples = 177472
timeInSeconds = 3.6973333333333334
bpm = 194
isRecordingOrPlaying = 1
}
[113] = {
lastBarPpqPosition = 12
ppqPosition = 12.092659027777778
timeInSamples = 179520
timeInSeconds = 3.7400000000000002
bpm = 194
isRecordingOrPlaying = 1
}
[114] = {
lastBarPpqPosition = 12
ppqPosition = 12.230614583333333
timeInSamples = 181568
timeInSeconds = 3.7826666666666666
bpm = 194
isRecordingOrPlaying = 1
}
[115] = {
lastBarPpqPosition = 12
ppqPosition = 12.368570138888888
timeInSamples = 183616
timeInSeconds = 3.8253333333333335
bpm = 194
isRecordingOrPlaying = 1
}
[116] = {
lastBarPpqPosition = 12
ppqPosition = 12.506525694444445
timeInSamples = 185664
timeInSeconds = 3.8679999999999999
bpm = 194
isRecordingOrPlaying = 1
}
[117] = {
lastBarPpqPosition = 12
ppqPosition = 12.64448125
timeInSamples = 187712
timeInSeconds = 3.9106666666666667
bpm = 194
isRecordingOrPlaying = 1
}
[118] = {
lastBarPpqPosition = 12
ppqPosition = 12.782436805555555
timeInSamples = 189760
timeInSeconds = 3.9533333333333331
bpm = 194
isRecordingOrPlaying = 1
}
[119] = {
lastBarPpqPosition = 12
ppqPosition = 12.920392361111112
timeInSamples = 191808
timeInSeconds = 3.996
bpm = 194
isRecordingOrPlaying = 1
}
[120] = {
lastBarPpqPosition = 12
ppqPosition = 13.058347916666666
timeInSamples = 193856
timeInSeconds = 4.0386666666666668
bpm = 194
isRecordingOrPlaying = 1
}
[121] = {
lastBarPpqPosition = 12
ppqPosition = 13.196303472222223
timeInSamples = 195904
timeInSeconds = 4.0813333333333333
bpm = 194
isRecordingOrPlaying = 1
}
[122] = {
lastBarPpqPosition = 12
ppqPosition = 13.334259027777778
timeInSamples = 197952
timeInSeconds = 4.1239999999999997
bpm = 194
isRecordingOrPlaying = 1
}
[123] = {
lastBarPpqPosition = 12
ppqPosition = 13.472214583333333
timeInSamples = 200000
timeInSeconds = 4.166666666666667
bpm = 194
isRecordingOrPlaying = 1
}
[124] = {
lastBarPpqPosition = 12
ppqPosition = 13.61017013888889
timeInSamples = 202048
timeInSeconds = 4.2093333333333334
bpm = 194
isRecordingOrPlaying = 1
}
[125] = {
lastBarPpqPosition = 12
ppqPosition = 13.748125694444443
timeInSamples = 204096
timeInSeconds = 4.2519999999999998
bpm = 194
isRecordingOrPlaying = 1
}
[126] = {
lastBarPpqPosition = 12
ppqPosition = 13.88608125
timeInSamples = 206144
timeInSeconds = 4.2946666666666671
bpm = 194
isRecordingOrPlaying = 1
}
[127] = {
lastBarPpqPosition = 12
ppqPosition = 14.024036805555555
timeInSamples = 208192
timeInSeconds = 4.3373333333333335
bpm = 194
isRecordingOrPlaying = 1
}
[128] = {
lastBarPpqPosition = 12
ppqPosition = 14.16199236111111
timeInSamples = 210240
timeInSeconds = 4.3799999999999999
bpm = 194
isRecordingOrPlaying = 1
}
[129] = {
lastBarPpqPosition = 12
ppqPosition = 14.299947916666667
timeInSamples = 212288
timeInSeconds = 4.4226666666666663
bpm = 194
isRecordingOrPlaying = 1
}
[130] = {
lastBarPpqPosition = 12
ppqPosition = 14.437903472222221
timeInSamples = 214336
timeInSeconds = 4.4653333333333336
bpm = 194
isRecordingOrPlaying = 1
}
[131] = {
lastBarPpqPosition = 12
ppqPosition = 14.575859027777778
timeInSamples = 216384
timeInSeconds = 4.508
bpm = 194
isRecordingOrPlaying = 1
}
[132] = {
lastBarPpqPosition = 12
ppqPosition = 14.713814583333333
timeInSamples = 218432
timeInSeconds = 4.5506666666666664
bpm = 194
isRecordingOrPlaying = 1
}
[133] = {
lastBarPpqPosition = 12
ppqPosition = 14.851770138888888
timeInSamples = 220480
timeInSeconds = 4.5933333333333337
bpm = 194
isRecordingOrPlaying = 1
}
[134] = {
lastBarPpqPosition = 12
ppqPosition = 14.989725694444445
timeInSamples = 222528
timeInSeconds = 4.6360000000000001
bpm = 194
isRecordingOrPlaying = 1
}
[135] = {
lastBarPpqPosition = 12
ppqPosition = 15.12768125
timeInSamples = 224576
timeInSeconds = 4.6786666666666665
bpm = 194
isRecordingOrPlaying = 1
}
[136] = {
lastBarPpqPosition = 12
ppqPosition = 15.265636805555555
timeInSamples = 226624
timeInSeconds = 4.7213333333333329
bpm = 194
isRecordingOrPlaying = 1
}
[137] = {
lastBarPpqPosition = 12
ppqPosition = 15.403592361111112
timeInSamples = 228672
timeInSeconds = 4.7640000000000002
bpm = 194
isRecordingOrPlaying = 1
}
[138] = {
lastBarPpqPosition = 12
ppqPosition = 15.541547916666666
timeInSamples = 230720
timeInSeconds = 4.8066666666666666
bpm = 194
isRecordingOrPlaying = 1
}
[139] = {
lastBarPpqPosition = 12
ppqPosition = 15.679503472222223
timeInSamples = 232768
timeInSeconds = 4.8493333333333331
bpm = 194
isRecordingOrPlaying = 1
}
[140] = {
lastBarPpqPosition = 12
ppqPosition = 15.817459027777778
timeInSamples = 234816
timeInSeconds = 4.8920000000000003
bpm = 194
isRecordingOrPlaying = 1
}
[141] = {
lastBarPpqPosition = 12
ppqPosition = 15.955414583333333
timeInSamples = 236864
timeInSeconds = 4.9346666666666668
bpm = 194
isRecordingOrPlaying = 1
}
It all makes sense up to entry [84], where the timeInSeconds jumps from 3.54 to 2.50 ! Same for the timeInSamples…
So does anyone has any idea on how to check if the playback is continuous in Ableton, I guess without using timeInSamples?
Cheers
Simon
reFX
September 22, 2023, 4:20pm
12
Why don’t you just use the ppqposition? According to your own data, it’s continuous.
simon
September 22, 2023, 4:26pm
13
That’s actually a pretty good idea, thank you!
The increment must be something like numSamples * bpm / (60.0*sampleRate)
+/- a few rounding errors.
I’ll try
simon
September 22, 2023, 5:00pm
14
Ha! Actually no of course I cannot - because if the tempo jumps is during a block then the increment will be wrong since it should take into account the new tempo (which the plugin will receive only on the next block). Hence the idea of using timeInSamples
, which works in most places expect in Ableton.
The biggest irony, is that the reason I need to detect if the playback is continuous is precisely because of the fact I cannot get the tempo at an exact sample but only on the current block.
Maybe one day the VST3 interface will give a way to get a tempo map - gosh that would make my life so much easier… (it’s actually possible in an ARA plugin, I went down that way but not great or easy for the end-user, and not available in every DAW )
PS: just FYI I found this topic: CurrentPositionInfo.timeInSamples and tempo changes in ableton live - it seems this has been an Ableton bug for a looooong time.