add working poc for precise cyclist
This commit is contained in:
parent
4362cb9317
commit
ac441b4340
3 changed files with 79 additions and 90 deletions
|
|
@ -1,89 +1,34 @@
|
||||||
import workerUrl from './worker.mjs?url';
|
import { createClock, seq } from '@strudel/core';
|
||||||
import { samples, superdough } from 'superdough';
|
import { getAudioContext, initAudioOnFirstClick, samples, superdough } from 'superdough';
|
||||||
|
import { setInterval, clearInterval } from 'worker-timers'; // comment out this line to test with window.setInterval
|
||||||
|
|
||||||
let ctx;
|
let loaded = samples('github:tidalcycles/dirt-samples');
|
||||||
document.addEventListener('click', async () => {
|
async function run() {
|
||||||
ctx = new AudioContext();
|
// let pat = seq('hh').s().fast(25.2);
|
||||||
await samples('github:tidalcycles/dirt-samples');
|
let pat = seq('bd', ['hh', 'hh'], 'jvbass').s().fast(1.92);
|
||||||
initWorker();
|
await initAudioOnFirstClick();
|
||||||
});
|
await loaded;
|
||||||
|
const ctx = getAudioContext();
|
||||||
function initWorker() {
|
let last = 0;
|
||||||
if (!globalThis.Worker) {
|
const clock = createClock(
|
||||||
throw new Error('initWorker: Worker not supported in this environment');
|
() => ctx.currentTime,
|
||||||
}
|
(phase, duration, tick, t) => {
|
||||||
const worker = new Worker(workerUrl);
|
const [begin, end] = [last, (last = tick * duration)];
|
||||||
worker.postMessage({ origin: performance.timeOrigin });
|
console.log('q', begin.toFixed(2), end.toFixed(2), phase.toFixed(2));
|
||||||
// worker.postMessage(1);
|
let haps = pat.queryArc(begin, end).filter((h) => h.hasOnset());
|
||||||
let origin;
|
// console.log('phase', phase, haps.length);
|
||||||
let minLatency = 0.05;
|
haps.forEach((hap) => {
|
||||||
|
superdough(hap.value, '=' + String(hap.whole.begin + 0.1));
|
||||||
let init = performance.now();
|
});
|
||||||
|
},
|
||||||
// performance.timeOrigin; // unix timestamp when the page loads
|
0.025, // duration of each cycle
|
||||||
// Date.now() // unix timestamp (ms since January 1st 1970)
|
0.1, // interval between callbacks
|
||||||
// performance.timeOrigin // unix timestamp when the page loaded
|
0.4, // overlap between callbacks
|
||||||
// performance.now() // precise ms since the page loaded
|
setInterval,
|
||||||
// performance.timeOrigin + performance.now() ~= Date.now()
|
clearInterval,
|
||||||
|
false,
|
||||||
// worker: performance.now() // precise ms since the worker loaded
|
);
|
||||||
// worker: performance.timeOrigin // unix timestamp when the worker loaded
|
clock.start();
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^5.2.0"
|
"vite": "^5.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {"superdough":"workspace:*"}
|
"dependencies": {
|
||||||
|
"superdough": "workspace:*",
|
||||||
|
"worker-timers": "^7.1.4"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
|
|
@ -142,6 +142,9 @@ importers:
|
||||||
superdough:
|
superdough:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/superdough
|
version: link:../../packages/superdough
|
||||||
|
worker-timers:
|
||||||
|
specifier: ^7.1.4
|
||||||
|
version: 7.1.4
|
||||||
devDependencies:
|
devDependencies:
|
||||||
vite:
|
vite:
|
||||||
specifier: ^5.2.0
|
specifier: ^5.2.0
|
||||||
|
|
@ -2194,6 +2197,13 @@ packages:
|
||||||
regenerator-runtime: 0.14.1
|
regenerator-runtime: 0.14.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/runtime@7.24.1:
|
||||||
|
resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: 0.14.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@babel/template@7.22.15:
|
/@babel/template@7.22.15:
|
||||||
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
@ -7587,6 +7597,14 @@ packages:
|
||||||
/fast-levenshtein@2.0.6:
|
/fast-levenshtein@2.0.6:
|
||||||
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
|
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
|
||||||
|
|
||||||
|
/fast-unique-numbers@8.0.13:
|
||||||
|
resolution: {integrity: sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==}
|
||||||
|
engines: {node: '>=16.1.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fast-xml-parser@4.3.3:
|
/fast-xml-parser@4.3.3:
|
||||||
resolution: {integrity: sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==}
|
resolution: {integrity: sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -12008,7 +12026,6 @@ packages:
|
||||||
|
|
||||||
/regenerator-runtime@0.14.1:
|
/regenerator-runtime@0.14.1:
|
||||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/regenerator-transform@0.15.2:
|
/regenerator-transform@0.15.2:
|
||||||
resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==}
|
resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==}
|
||||||
|
|
@ -13430,7 +13447,6 @@ packages:
|
||||||
/tslib@2.6.2:
|
/tslib@2.6.2:
|
||||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
optional: true
|
|
||||||
|
|
||||||
/tsutils@3.21.0(typescript@5.3.3):
|
/tsutils@3.21.0(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||||
|
|
@ -14433,6 +14449,31 @@ packages:
|
||||||
workbox-core: 7.0.0
|
workbox-core: 7.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/worker-timers-broker@6.1.4:
|
||||||
|
resolution: {integrity: sha512-y3D+Yfj37lrItEMIlcfCm/IRueYtYKgpLlTG2wgTIZ9PSw0n/K4kweilgk3gTC4ahbQNVGT90lU+Rf7W4M5bsw==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
fast-unique-numbers: 8.0.13
|
||||||
|
tslib: 2.6.2
|
||||||
|
worker-timers-worker: 7.0.67
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/worker-timers-worker@7.0.67:
|
||||||
|
resolution: {integrity: sha512-0ZP2+v2fyiiiGaCEdWxMRUk5YxGFwWdRGB12ZfQy13vw8/27Xd+MW3ua56qlcM30nzjpddXXzLuEpHhGW+Pz7w==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/worker-timers@7.1.4:
|
||||||
|
resolution: {integrity: sha512-8PRtiPAyeYukrY+iOUL+0tq4Zn5qyCHrTqFTtHxcESfIxGyulxNwyzQkybrYBKhnMWmx0bku3wxRfE1hts5R6Q==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
tslib: 2.6.2
|
||||||
|
worker-timers-broker: 6.1.4
|
||||||
|
worker-timers-worker: 7.0.67
|
||||||
|
dev: false
|
||||||
|
|
||||||
/wrap-ansi@7.0.0:
|
/wrap-ansi@7.0.0:
|
||||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue