add working poc for precise cyclist

This commit is contained in:
Felix Roos 2024-03-21 22:41:45 +01:00
parent 4362cb9317
commit ac441b4340
3 changed files with 79 additions and 90 deletions

View file

@ -1,89 +1,34 @@
import workerUrl from './worker.mjs?url';
import { samples, superdough } from 'superdough';
import { createClock, seq } from '@strudel/core';
import { getAudioContext, initAudioOnFirstClick, samples, superdough } from 'superdough';
import { setInterval, clearInterval } from 'worker-timers'; // comment out this line to test with window.setInterval
let ctx;
document.addEventListener('click', async () => {
ctx = new AudioContext();
await samples('github:tidalcycles/dirt-samples');
initWorker();
});
function initWorker() {
if (!globalThis.Worker) {
throw new Error('initWorker: Worker not supported in this environment');
}
const worker = new Worker(workerUrl);
worker.postMessage({ origin: performance.timeOrigin });
// worker.postMessage(1);
let origin;
let minLatency = 0.05;
let init = performance.now();
// performance.timeOrigin; // unix timestamp when the page loads
// Date.now() // unix timestamp (ms since January 1st 1970)
// performance.timeOrigin // unix timestamp when the page loaded
// performance.now() // precise ms since the page loaded
// performance.timeOrigin + performance.now() ~= Date.now()
// worker: performance.now() // precise ms since the worker loaded
// worker: performance.timeOrigin // unix timestamp when the worker loaded
worker.onmessage = (e) => {
const { contextTime, performanceTime } = ctx.getOutputTimestamp();
console.log('e', e.timeStamp, performance.now());
/* // clock offsets
const { contextTime: t } = outputTimestamp; // audio clock time in seconds
const { performanceTime: now } = outputTimestamp; // estimated system clock time for contextTime
const { origin: workerOrigin } = e.data; // seconds when the worker was loaded
const { phase } = e.data; // target time in seconds of current tick (relative to system clock)
let workerOriginDiffMs = workerOrigin - performance.timeOrigin;
// console.log('worker created after seconds:', workerOriginDiffMs);
let workerOriginDiffSeconds = workerOriginDiffMs / 1000;
let workerPhaseSeconds = phase + workerOriginDiffSeconds;
let nowSeconds = now / 1000;
let workerDeadline = workerPhaseSeconds - nowSeconds; */
// console.log('workerDeadline', workerDeadline);
// superdough({ s: 'bd' }, workerDeadline);
e.data.forEach((event, i) => {
let phase = event.phase * 1000;
//let phase = event.tick * 100 + origin;
let diff = (phase - performanceTime) / 1000;
superdough({ s: 'bd' }, contextTime + diff + 2);
});
/* const deadline = phase - now;
const { tickOrigin } = e.data; // ms when the first tick happened
const { tick, begin, end, haps, cps } = e.data;
// console.log('phase', phase);
if (tick === 0) {
console.log('set origin', t);
origin = t;
}
// console.log('tick', tick, begin, end, phase, origin);
haps.forEach((hap) => {
let hapBegin = hap.whole.begin;
hapBegin = (hapBegin.s * hapBegin.n) / hapBegin.d;
const stamp = ctx.getOutputTimestamp();
let targetTime = origin + hapBegin * cps;
let deadline = t - targetTime + minLatency;
// console.log('--hap, begin:', begin, 'deadline', deadline);
// console.log('hap', hap.value, begin, deadline);
superdough(hap.value, deadline);
}); */
// const stamp = ctx?.getOutputTimestamp();
// console.log('stamp', stamp);
};
let loaded = samples('github:tidalcycles/dirt-samples');
async function run() {
// let pat = seq('hh').s().fast(25.2);
let pat = seq('bd', ['hh', 'hh'], 'jvbass').s().fast(1.92);
await initAudioOnFirstClick();
await loaded;
const ctx = getAudioContext();
let last = 0;
const clock = createClock(
() => ctx.currentTime,
(phase, duration, tick, t) => {
const [begin, end] = [last, (last = tick * duration)];
console.log('q', begin.toFixed(2), end.toFixed(2), phase.toFixed(2));
let haps = pat.queryArc(begin, end).filter((h) => h.hasOnset());
// console.log('phase', phase, haps.length);
haps.forEach((hap) => {
superdough(hap.value, '=' + String(hap.whole.begin + 0.1));
});
},
0.025, // duration of each cycle
0.1, // interval between callbacks
0.4, // overlap between callbacks
setInterval,
clearInterval,
false,
);
clock.start();
}
run();

View file

@ -11,5 +11,8 @@
"devDependencies": {
"vite": "^5.2.0"
},
"dependencies": {"superdough":"workspace:*"}
"dependencies": {
"superdough": "workspace:*",
"worker-timers": "^7.1.4"
}
}