strudel-docker/docs/dist/useCycle.js
Felix Roos 8af4a92fc0 build
2022-03-18 17:39:14 +01:00

52 lines
1.9 KiB
JavaScript

import {useEffect, useState} from "../_snowpack/pkg/react.js";
import * as Tone from "../_snowpack/pkg/tone.js";
import {TimeSpan, State} from "../_snowpack/link/strudel.js";
function useCycle(props) {
const {onEvent, onQuery, onSchedule, ready = true, onDraw} = props;
const [started, setStarted] = useState(false);
const cycleDuration = 1;
const activeCycle = () => Math.floor(Tone.getTransport().seconds / cycleDuration);
const query = (cycle = activeCycle()) => {
const timespan = new TimeSpan(cycle, cycle + 1);
const events = onQuery?.(new State(timespan)) || [];
onSchedule?.(events, cycle);
const cancelFrom = timespan.begin.valueOf();
Tone.getTransport().cancel(cancelFrom);
const queryNextTime = (cycle + 1) * cycleDuration - 0.5;
const t = Math.max(Tone.getTransport().seconds, queryNextTime) + 0.1;
Tone.getTransport().schedule(() => {
query(cycle + 1);
}, t);
events?.filter((event) => event.part.begin.valueOf() === event.whole.begin.valueOf()).forEach((event) => {
Tone.getTransport().schedule((time) => {
const toneEvent = {
time: event.whole.begin.valueOf(),
duration: event.whole.end.sub(event.whole.begin).valueOf(),
value: event.value,
context: event.context
};
onEvent(time, toneEvent);
Tone.Draw.schedule(() => {
onDraw?.(time, toneEvent);
}, time);
}, event.part.begin.valueOf());
});
};
useEffect(() => {
ready && query();
}, [onEvent, onSchedule, onQuery, onDraw, ready]);
const start = async () => {
setStarted(true);
await Tone.start();
Tone.getTransport().start("+0.1");
};
const stop = () => {
console.log("stop");
setStarted(false);
Tone.getTransport().pause();
};
const toggle = () => started ? stop() : start();
return {start, stop, setStarted, onEvent, started, toggle, query, activeCycle};
}
export default useCycle;