digging a bit deeper.
var samplerate = 44100;
var minBpm = 30.0, maxBpm = 300.0;
var stepBpm = 0.1;
var bars = 1; // number of bars the 16-step loop represents
var ticksPerBar = 24 * 4 * bars; // 96 for bars=1
var numerator = samplerate * 60 * ticksPerBar; // samples = numerator / OctaTempo
var rows = [];
var range = Math.round((maxBpm - minBpm) / stepBpm);
for (var i = 0; i <= range; i++) {
var bpm = +(minBpm + i * stepBpm).toFixed(1); //make sure only sharp 1commata values are used
var octatempo = Math.round(bpm * 24); //do the Octatrick
if (octatempo <= 0) continue; // heck, no endless loop!
var samplesNeeded = numerator / octatempo; // exact float
rows.push({
bpm: bpm,
OctaTempo: octatempo,
samples_exact: samplesNeeded,
samples_rounded: Math.round(samplesNeeded),
seconds_exact: (samplesNeeded / samplerate).toFixed(6) + "sec"
});
}
console.log('Assumption: samplerate=',samplerate, 'bars=', bars);
console.table([rows.find(r=>r.bpm===120.0)]);
console.log('Top 12 (lowest BPMs):');
console.table(rows.slice(0,12));
console.log('A few around 120 BPM:');
console.table(rows.filter(r=>r.bpm>=119.5 && r.bpm<=120.5));
var check = [
56, 60, 62.5, 63, 64, 72, 75, 96, 100, 108, 112, 120, 125, 126, 135, 144,
55, 61, 62, 65, 66, 67, 85, 86, 87, 95, 97, 110, 122, 123, 124, 127, 128, 129, 130, 131, 132, 134
];
var result = [];
for (var i=0; i<check.length; i++) {
var test = check[i];
var row = (rows.find(r=>r.bpm===test));
result[i] = {bpm: test, OctaTempo: row.OctaTempo, samples_rounded: row.samples_rounded, sec: row.seconds_exact };
}
console.table(result);
explains at least what the challange is…
see screenshot…
and here the selection of your former test bpm…

