diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 303525a2..c835ca76 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -11,13 +11,14 @@ export class Cyclist { constructor({ interval, onTrigger, onToggle, onError, getTime, latency = 0.1 }) { this.started = false; this.cps = 1; + this.num_ticks_since_cps_change = 0; this.lastTick = 0; // absolute time when last tick (clock callback) happened this.lastBegin = 0; // query begin of last tick this.lastEnd = 0; // query end of last tick this.getTime = getTime; // get absolute time + this.num_cycles_since_last_cps_change = 0; this.onToggle = onToggle; this.latency = latency; // fixed trigger time offset - const round = (x) => Math.round(x * 1000) / 1000; this.clock = createClock( getTime, // called slightly before each cycle @@ -25,14 +26,24 @@ export class Cyclist { if (tick === 0) { this.origin = phase; } + if (this.num_ticks_since_cps_change === 0) { + this.num_cycles_since_last_cps_change = this.lastEnd; + } + this.num_ticks_since_cps_change++; try { const time = getTime(); const begin = this.lastEnd; this.lastBegin = begin; - const end = round(begin + duration * this.cps); + + //convert ticks to cycles, so you can query the pattern for events + const eventLength = duration * this.cps; + const end = this.num_cycles_since_last_cps_change + this.num_ticks_since_cps_change * eventLength; this.lastEnd = end; + + // query the pattern for events const haps = this.pattern.queryArc(begin, end); - const tickdeadline = phase - time; // time left till phase begins + + const tickdeadline = phase - time; // time left until the phase is a whole number this.lastTick = time + tickdeadline; haps.forEach((hap) => { @@ -59,6 +70,8 @@ export class Cyclist { this.onToggle?.(v); } start() { + this.num_ticks_since_cps_change = 0; + this.num_cycles_since_last_cps_change = 0; if (!this.pattern) { throw new Error('Scheduler: no pattern set! call .setPattern first.'); } @@ -84,7 +97,11 @@ export class Cyclist { } } setCps(cps = 1) { + if (this.cps === cps) { + return; + } this.cps = cps; + this.num_ticks_since_cps_change = 0; } log(begin, end, haps) { const onsets = haps.filter((h) => h.hasOnset());