mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 13:48:40 +00:00
52 lines
1.8 KiB
JavaScript
52 lines
1.8 KiB
JavaScript
import {useEffect, useState} from "../_snowpack/pkg/react.js";
|
|
import * as Tone from "../_snowpack/pkg/tone.js";
|
|
import {TimeSpan} from "../_snowpack/link/strudel.js";
|
|
function useCycle(props) {
|
|
const {onEvent, onQuery, onSchedule, ready = true} = props;
|
|
const [started, setStarted] = useState(false);
|
|
const cycleDuration = 1;
|
|
const activeCycle = () => Math.floor(Tone.Transport.seconds / cycleDuration);
|
|
const query = (cycle = activeCycle()) => {
|
|
const timespan = new TimeSpan(cycle, cycle + 1);
|
|
const _events = onQuery?.(timespan) || [];
|
|
onSchedule?.(_events, cycle);
|
|
schedule(_events, cycle);
|
|
};
|
|
const schedule = (events, cycle = activeCycle()) => {
|
|
const timespan = new TimeSpan(cycle, cycle + 1);
|
|
const cancelFrom = timespan.begin.valueOf();
|
|
Tone.Transport.cancel(cancelFrom);
|
|
const queryNextTime = (cycle + 1) * cycleDuration - 0.1;
|
|
Tone.Transport.schedule(() => {
|
|
query(cycle + 1);
|
|
}, queryNextTime);
|
|
events?.forEach((event) => {
|
|
Tone.Transport.schedule((time) => {
|
|
const toneEvent = {
|
|
time: event.part.begin.valueOf(),
|
|
duration: event.part.end.valueOf() - event.part.begin.valueOf(),
|
|
value: event.value
|
|
};
|
|
onEvent(time, toneEvent);
|
|
}, event.part.begin.valueOf());
|
|
});
|
|
};
|
|
useEffect(() => {
|
|
ready && query();
|
|
}, [onEvent, onSchedule, onQuery]);
|
|
const start = async () => {
|
|
console.log("start");
|
|
setStarted(true);
|
|
await Tone.start();
|
|
Tone.Transport.start("+0.1");
|
|
};
|
|
const stop = () => {
|
|
console.log("stop");
|
|
setStarted(false);
|
|
Tone.Transport.pause();
|
|
};
|
|
const toggle = () => started ? stop() : start();
|
|
return {start, stop, onEvent, started, toggle, schedule, query, activeCycle};
|
|
}
|
|
export default useCycle;
|