Compare commits

...

1 Commits

Author SHA1 Message Date
Felix Roos bd6a2c6650 first draft for sound preloading 2023-03-24 20:55:29 +01:00
4 changed files with 33 additions and 5 deletions
+1 -1
View File
@@ -46,8 +46,8 @@ export function repl({
logger(`[eval] code updated`); logger(`[eval] code updated`);
pattern = editPattern?.(pattern) || pattern; pattern = editPattern?.(pattern) || pattern;
await afterEval?.({ code, pattern });
scheduler.setPattern(pattern, autostart); scheduler.setPattern(pattern, autostart);
afterEval?.({ code, pattern });
return pattern; return pattern;
} catch (err) { } catch (err) {
// console.warn(`[repl] eval error: ${err.message}`); // console.warn(`[repl] eval error: ${err.message}`);
+2 -2
View File
@@ -50,13 +50,13 @@ function useStrudel({
setCode(code); setCode(code);
await beforeEval?.(); await beforeEval?.();
}, },
afterEval: (res) => { afterEval: async (res) => {
const { pattern: _pattern, code } = res; const { pattern: _pattern, code } = res;
setActiveCode(code); setActiveCode(code);
setPattern(_pattern); setPattern(_pattern);
setEvalError(); setEvalError();
setSchedulerError(); setSchedulerError();
afterEval?.(res); await afterEval?.(res);
}, },
onToggle: (v) => { onToggle: (v) => {
setStarted(v); setStarted(v);
+1 -1
View File
@@ -170,7 +170,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => {
sourceNode = source(t, hap.value, hapDuration); sourceNode = source(t, hap.value, hapDuration);
} else if (getSound(s)) { } else if (getSound(s)) {
const { onTrigger } = getSound(s); const { onTrigger } = getSound(s);
const soundHandle = await onTrigger(t, hap.value, onended); const soundHandle = await onTrigger(t, { ...hap.value, s }, onended);
if (soundHandle) { if (soundHandle) {
sourceNode = soundHandle.node; sourceNode = soundHandle.node;
soundHandle.stop(t + hapDuration); soundHandle.stop(t + hapDuration);
+29 -1
View File
@@ -118,11 +118,39 @@ export function Repl({ embedded = false }) {
cleanupUi(); cleanupUi();
cleanupDraw(); cleanupDraw();
}, },
afterEval: ({ code }) => { afterEval: async ({ code, pattern }) => {
// preload sounds
const t = scheduler.getTime();
const lookahead = 16;
const upcoming = pattern
.queryArc(t, t + lookahead)
.filter((h) => h.value.s)
.map((h) => `${h.value.bank ? `${h.value.bank}_` : ''}${h.value.s}:${h.value.n || 0}`)
.filter((v, i, all) => all.indexOf(v) === i);
// console.log('now preloading sounds:', upcoming);
const preload = upcoming.map(async (v) => {
const [s, n] = v.split(':');
const sound = soundMap.value[s];
if (!sound) {
throw new Error(`[preload] error: sound not found: "${s}:${n}"`);
}
// TODO: only preload if not already preloaded...
// TODO: add sound.preload interface that only loads the sample, without creating a buffersource
return sound.onTrigger(getAudioContext().currentTime + 0.5, { s, n }, () => {
// console.log('onended');
});
});
await Promise.all(preload);
// console.log('preloading done');
setPending(false); setPending(false);
setLatestCode(code); setLatestCode(code);
window.location.hash = '#' + encodeURIComponent(btoa(code)); window.location.hash = '#' + encodeURIComponent(btoa(code));
}, },
onEvalError: (err) => {
console.log('errr');
setPending(false);
},
onToggle: (play) => !play && cleanupDraw(false), onToggle: (play) => !play && cleanupDraw(false),
drawContext, drawContext,
}); });