mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-24 20:18:34 +00:00
converting
This commit is contained in:
parent
19f2434694
commit
d329ccc4e3
@ -7,7 +7,6 @@ let lastEnd = 0; // query end of last tick
|
|||||||
// let getTime = getTime; // get absolute time
|
// let getTime = getTime; // get absolute time
|
||||||
let num_cycles_at_cps_change = 0;
|
let num_cycles_at_cps_change = 0;
|
||||||
// let onToggle = onToggle;
|
// let onToggle = onToggle;
|
||||||
let latency = 0.1; // fixed trigger time offset
|
|
||||||
let interval = 0.1;
|
let interval = 0.1;
|
||||||
|
|
||||||
//incoming
|
//incoming
|
||||||
@ -18,7 +17,7 @@ let interval = 0.1;
|
|||||||
// {type: toggle, payload?: {started: boolean}}
|
// {type: toggle, payload?: {started: boolean}}
|
||||||
|
|
||||||
//sending
|
//sending
|
||||||
//{type: 'tick', payload: {begin, end, phase, time }}
|
//{type: 'tick', payload: {begin, end, deadline }}
|
||||||
//{type: 'log', payload: {type, text}}
|
//{type: 'log', payload: {type, text}}
|
||||||
|
|
||||||
const getTime = () => {
|
const getTime = () => {
|
||||||
@ -34,7 +33,7 @@ const log = (text, type) => {
|
|||||||
sendMessage({ type: 'log', payload: { text, type } });
|
sendMessage({ type: 'log', payload: { text, type } });
|
||||||
};
|
};
|
||||||
|
|
||||||
createClock(
|
let clock = createClock(
|
||||||
getTime,
|
getTime,
|
||||||
// called slightly before each cycle
|
// called slightly before each cycle
|
||||||
(phase, duration, tick) => {
|
(phase, duration, tick) => {
|
||||||
@ -53,7 +52,7 @@ createClock(
|
|||||||
lastEnd = end;
|
lastEnd = end;
|
||||||
const tickdeadline = phase - time; // time left until the phase is a whole number
|
const tickdeadline = phase - time; // time left until the phase is a whole number
|
||||||
lastTick = time + tickdeadline;
|
lastTick = time + tickdeadline;
|
||||||
sendMessage({ type: 'tick', payload: { begin, end, phase, time } });
|
sendMessage({ type: 'tick', payload: { begin, end, tickdeadline } });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(`[cyclist] error: ${e.message}`, 'error');
|
log(`[cyclist] error: ${e.message}`, 'error');
|
||||||
}
|
}
|
||||||
@ -73,6 +72,33 @@ self.onconnect = function (e) {
|
|||||||
port.start(); // Required when using addEventListener. Otherwise called implicitly by onmessage setter.
|
port.start(); // Required when using addEventListener. Otherwise called implicitly by onmessage setter.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.onmessage = (message) => {
|
||||||
|
const { type, payload } = message;
|
||||||
|
switch (type) {
|
||||||
|
case 'cpschange': {
|
||||||
|
if (payload.cps !== cps) {
|
||||||
|
cps = payload.cps;
|
||||||
|
num_ticks_since_cps_change = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'toggle': {
|
||||||
|
const { started } = payload;
|
||||||
|
if (started) {
|
||||||
|
clock.start();
|
||||||
|
} else {
|
||||||
|
clock.stop();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'requestcycles': {
|
||||||
|
const secondsSinceLastTick = getTime() - lastTick - clock.duration;
|
||||||
|
const cycles = this.lastBegin + secondsSinceLastTick * this.cps; // + this.clock.minLatency;
|
||||||
|
sendMessage({ type: 'requestedcycles', payload: { cycles } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function createClock(
|
function createClock(
|
||||||
getTime,
|
getTime,
|
||||||
callback, // called slightly before each cycle
|
callback, // called slightly before each cycle
|
||||||
@ -84,6 +110,7 @@ function createClock(
|
|||||||
let phase = 0; // next callback time
|
let phase = 0; // next callback time
|
||||||
let precision = 10 ** 4; // used to round phase
|
let precision = 10 ** 4; // used to round phase
|
||||||
let minLatency = 0.01;
|
let minLatency = 0.01;
|
||||||
|
|
||||||
const setDuration = (setter) => (duration = setter(duration));
|
const setDuration = (setter) => (duration = setter(duration));
|
||||||
overlap = overlap || interval / 2;
|
overlap = overlap || interval / 2;
|
||||||
const onTick = () => {
|
const onTick = () => {
|
||||||
@ -115,6 +142,7 @@ function createClock(
|
|||||||
clear();
|
clear();
|
||||||
};
|
};
|
||||||
const getPhase = () => phase;
|
const getPhase = () => phase;
|
||||||
|
|
||||||
// setCallback
|
// setCallback
|
||||||
return { setDuration, start, stop, pause, duration, interval, getPhase, minLatency };
|
return { setDuration, start, stop, pause, duration, interval, getPhase, minLatency };
|
||||||
}
|
}
|
||||||
|
|||||||
73
packages/core/neocyclist.mjs
Normal file
73
packages/core/neocyclist.mjs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { logger } from './logger.mjs';
|
||||||
|
|
||||||
|
const sharedworker = new SharedWorker(new URL('./cyclistworker.js', import.meta.url));
|
||||||
|
sharedworker.port.start();
|
||||||
|
|
||||||
|
export class NeoCyclist {
|
||||||
|
constructor({ onTrigger, onToggle, latency = 0.1, onError }) {
|
||||||
|
this.started = false;
|
||||||
|
this.pattern;
|
||||||
|
this.onToggle = onToggle;
|
||||||
|
this.latency = latency;
|
||||||
|
this.worker = new SharedWorker(new URL('./cyclistworker.js', import.meta.url));
|
||||||
|
this.worker.port.addEventListener('message', (message) => {
|
||||||
|
const { payload, type } = message;
|
||||||
|
switch (type) {
|
||||||
|
case 'tick': {
|
||||||
|
console.log('tick');
|
||||||
|
const { begin, end } = payload;
|
||||||
|
const haps = this.pattern.queryArc(begin, end);
|
||||||
|
haps.forEach((hap) => {
|
||||||
|
if (hap.part.begin.equals(hap.whole.begin)) {
|
||||||
|
const deadline = (hap.whole.begin - begin) / this.cps + payload.deadline + latency;
|
||||||
|
const duration = hap.duration / this.cps;
|
||||||
|
onTrigger?.(hap, deadline, duration, this.cps);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'log': {
|
||||||
|
const { type, text } = payload;
|
||||||
|
if (type == 'error') {
|
||||||
|
onError(text);
|
||||||
|
} else {
|
||||||
|
logger(text, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
sendMessage(type, payload) {
|
||||||
|
this.worker.port.postMessage({ type, payload });
|
||||||
|
}
|
||||||
|
|
||||||
|
now() {
|
||||||
|
this.sendMessage('requestcycles', {});
|
||||||
|
}
|
||||||
|
setCps(cps = 1) {
|
||||||
|
this.sendMessage('cpschange', { cps });
|
||||||
|
}
|
||||||
|
setStarted(started) {
|
||||||
|
this.sendMessage('toggle', { started });
|
||||||
|
this.started = started;
|
||||||
|
this.onToggle?.(started);
|
||||||
|
}
|
||||||
|
start() {
|
||||||
|
logger('[cyclist] start');
|
||||||
|
this.setStarted(true);
|
||||||
|
}
|
||||||
|
stop() {
|
||||||
|
logger('[cyclist] stop');
|
||||||
|
this.setStarted(false);
|
||||||
|
}
|
||||||
|
setPattern(pat, autostart = false) {
|
||||||
|
this.pattern = pat;
|
||||||
|
if (autostart && !this.started) {
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log(begin, end, haps) {
|
||||||
|
const onsets = haps.filter((h) => h.hasOnset());
|
||||||
|
console.log(`${begin.toFixed(4)} - ${end.toFixed(4)} ${Array(onsets.length).fill('I').join('')}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import { logger } from './logger.mjs';
|
|||||||
import { setTime } from './time.mjs';
|
import { setTime } from './time.mjs';
|
||||||
import { evalScope } from './evaluate.mjs';
|
import { evalScope } from './evaluate.mjs';
|
||||||
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
|
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
|
||||||
|
import { NeoCyclist } from './neocyclist.mjs';
|
||||||
|
|
||||||
export function repl({
|
export function repl({
|
||||||
interval,
|
interval,
|
||||||
@ -52,11 +53,21 @@ export function repl({
|
|||||||
onUpdateState?.(state);
|
onUpdateState?.(state);
|
||||||
};
|
};
|
||||||
|
|
||||||
const scheduler = new Cyclist({
|
// const scheduler = new Cyclist({
|
||||||
|
// interval,
|
||||||
|
// onTrigger: getTrigger({ defaultOutput, getTime }),
|
||||||
|
// onError: onSchedulerError,
|
||||||
|
// getTime,
|
||||||
|
// onToggle: (started) => {
|
||||||
|
// updateState({ started });
|
||||||
|
// onToggle?.(started);
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
const scheduler = new NeoCyclist({
|
||||||
interval,
|
interval,
|
||||||
onTrigger: getTrigger({ defaultOutput, getTime }),
|
onTrigger: getTrigger({ defaultOutput, getTime }),
|
||||||
onError: onSchedulerError,
|
onError: onSchedulerError,
|
||||||
getTime,
|
|
||||||
onToggle: (started) => {
|
onToggle: (started) => {
|
||||||
updateState({ started });
|
updateState({ started });
|
||||||
onToggle?.(started);
|
onToggle?.(started);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user