diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index a42529cc4..3411728a0 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); @@ -264,9 +264,9 @@ export class StrudelMirror { console.warn('first frame could not be painted'); } } - async evaluate(autoplay = true) { + async evaluate(autostart = true) { this.flash(); - await this.repl.evaluate(this.code, autoplay); + await this.repl.evaluate(this.code, autostart); } async stop() { this.repl.scheduler.stop(); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 3232fa476..d996f3a26 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -289,7 +289,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { const { bufferSource, sliceDuration, offset } = await getSampleBufferSource(value, bank, resolveUrl); // asny stuff above took too long? - if (ac.currentTime > t) { + if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); // console.warn('sample still loading:', s, n); return; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index c2bbba36a..e6972ab71 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -562,7 +562,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) return; } - if (ac.currentTime > t) { + if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { logger('[webaudio] skip hap: still loading', ac.currentTime - t); return; } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 7a5ffac32..fae2c46cf 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -22,11 +22,14 @@ import { setMaxPolyphony, setMultiChannelOrbits, resetGlobalEffects, + getDefaultValue, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; import { SuperdoughAudioController } from 'superdough/superdoughoutput.mjs'; - +import { loadModules } from '@src/repl/util.mjs'; +import { prebake } from '@src/repl/prebake.mjs'; +import { getFontBufferSource, getFontPitch } from 'node_modules/@strudel/soundfonts/fontloader.mjs'; registerWorklet(workletUrl); const { Pattern, logger, repl } = strudel; @@ -56,7 +59,9 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d logger('[webaudio] start rendering'); let haps = pattern.queryArc(begin, end, { _cps: cps }); - await Promise.all( + await Promise.all([ + loadModules(), + prebake(), haps.map(async (h) => { let s; if (h.value.s) { @@ -65,13 +70,26 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d } else { s = h.value.s; } - let bank = getSound(s).data.samples; - if (bank) { - let { url: sampleUrl, label } = getSampleInfo(h.value, bank); - await loadBuffer(sampleUrl, audioContext, label); + // let bank = getSound(s).data.samples; + let sample = getSound(s); + if (sample.data.type == "soundfont") { + sample.data.fonts.forEach(async (font) => { + await getFontBufferSource(font, h.value, audioContext) + }) } + if (sample.data.type == "sample") { + let url; + if (Array.isArray(sample)) { + url = sample.data.samples[i % sample.data.samples.length]; + } else if (typeof sample === 'object') { + console.log(sample.data.samples) + url = Object.values(sample.data.samples).flat()[getDefaultValue("i") % Object.values(sample.data.samples).length]; + } + await loadBuffer(url, audioContext, s, 0); + } // TODO: waveform } - }), + }) + ], ); haps.forEach(async (hap) => { if (hap.hasOnset()) { diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 49d493157..b775df659 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -206,7 +206,7 @@ export function useReplContext() { }; const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { - await editorRef.current.evaluate(true); + await editorRef.current.evaluate(false); editorRef.current.repl.scheduler.stop(); await renderPatternAudio( editorRef.current.repl.state.pattern,