sync highlighting with tone draw

This commit is contained in:
Felix Roos 2022-02-27 11:52:34 +01:00
parent cad81acc44
commit 1375932c05
4 changed files with 15 additions and 7 deletions

View File

@ -17,8 +17,8 @@ try {
} catch (err) { } catch (err) {
console.warn('failed to decode', err); console.warn('failed to decode', err);
} }
// "balanced" | "interactive" | "playback";
Tone.setContext( new Tone.Context({ latencyHint : .5, lookAhead:1 })) Tone.setContext(new Tone.Context({ latencyHint: 'playback', lookAhead: 1 }));
const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.getDestination()); const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.getDestination());
defaultSynth.set({ defaultSynth.set({
oscillator: { type: 'triangle' }, oscillator: { type: 'triangle' },
@ -40,7 +40,7 @@ function App() {
const { setCode, setPattern, error, code, cycle, dirty, log, togglePlay, activateCode, pattern, pushLog } = useRepl({ const { setCode, setPattern, error, code, cycle, dirty, log, togglePlay, activateCode, pattern, pushLog } = useRepl({
tune: decoded || randomTune, tune: decoded || randomTune,
defaultSynth, defaultSynth,
onEvent: useCallback(markEvent(editor), [editor]), onDraw: useCallback(markEvent(editor), [editor]),
}); });
const logBox = useRef<any>(); const logBox = useRef<any>();
// scroll log box to bottom when log changes // scroll log box to bottom when log changes
@ -124,7 +124,9 @@ function App() {
</span> </span>
</div> </div>
{error && ( {error && (
<div className={cx('absolute right-2 bottom-2 px-2', 'text-red-500')}>{error?.message || 'unknown error'}</div> <div className={cx('absolute right-2 bottom-2 px-2', 'text-red-500')}>
{error?.message || 'unknown error'}
</div>
)} )}
</div> </div>
<button <button

View File

@ -17,7 +17,7 @@ export default function CodeMirror({ value, onChange, options, editorDidMount }:
return <CodeMirror2 value={value} options={options} onBeforeChange={onChange} editorDidMount={editorDidMount} />; return <CodeMirror2 value={value} options={options} onBeforeChange={onChange} editorDidMount={editorDidMount} />;
} }
export const markEvent = (editor) => (event) => { export const markEvent = (editor) => (time, event) => {
const locs = event.value.locations; const locs = event.value.locations;
if (!locs || !editor) { if (!locs || !editor) {
return; return;

View File

@ -8,12 +8,13 @@ export declare interface UseCycleProps {
onEvent: ToneEventCallback<any>; onEvent: ToneEventCallback<any>;
onQuery?: (query: TimeSpan) => Hap[]; onQuery?: (query: TimeSpan) => Hap[];
onSchedule?: (events: Hap[], cycle: number) => void; onSchedule?: (events: Hap[], cycle: number) => void;
onDraw?: ToneEventCallback<any>;
ready?: boolean; // if false, query will not be called on change props ready?: boolean; // if false, query will not be called on change props
} }
function useCycle(props: UseCycleProps) { function useCycle(props: UseCycleProps) {
// onX must use useCallback! // onX must use useCallback!
const { onEvent, onQuery, onSchedule, ready = true } = props; const { onEvent, onQuery, onSchedule, ready = true, onDraw } = props;
const [started, setStarted] = useState<boolean>(false); const [started, setStarted] = useState<boolean>(false);
const cycleDuration = 1; const cycleDuration = 1;
const activeCycle = () => Math.floor(Tone.getTransport().seconds / cycleDuration); const activeCycle = () => Math.floor(Tone.getTransport().seconds / cycleDuration);
@ -48,6 +49,10 @@ function useCycle(props: UseCycleProps) {
value: event.value, value: event.value,
}; };
onEvent(time, toneEvent); onEvent(time, toneEvent);
Tone.Draw.schedule(() => {
// do drawing or DOM manipulation here
onDraw?.(time, toneEvent);
}, time);
}, event.part.begin.valueOf()); }, event.part.begin.valueOf());
}); });
}; };

View File

@ -11,7 +11,7 @@ let s4 = () => {
.substring(1); .substring(1);
}; };
function useRepl({ tune, defaultSynth, autolink = true, onEvent }: any) { function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }: any) {
const id = useMemo(() => s4(), []); const id = useMemo(() => s4(), []);
const [code, setCode] = useState<string>(tune); const [code, setCode] = useState<string>(tune);
const [activeCode, setActiveCode] = useState<string>(); const [activeCode, setActiveCode] = useState<string>();
@ -52,6 +52,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent }: any) {
}; };
// cycle hook to control scheduling // cycle hook to control scheduling
const cycle = useCycle({ const cycle = useCycle({
onDraw,
onEvent: useCallback( onEvent: useCallback(
(time, event) => { (time, event) => {
try { try {