Fix worklets not loading

This commit is contained in:
Nikita
2025-10-19 19:44:53 +03:00
parent 920776fdfe
commit 908c0e44ff
6 changed files with 28 additions and 23 deletions
+3 -1
View File
@@ -269,8 +269,10 @@ export class StrudelMirror {
await this.repl.evaluate(this.code);
}
async exportAudio(begin, end) {
// await this.repl.evaluate(this.code, false)
await this.repl.evaluate(this.code, false)
this.repl.exportAudio(begin, end);
this.repl.scheduler.stop();
}
async stop() {
this.repl.scheduler.stop();
+1 -1
View File
@@ -348,7 +348,7 @@ export function applyFM(param, value, begin) {
duration,
} = value;
let modulator;
let stop = () => {};
let stop = () => { };
if (fmModulationIndex) {
const ac = getAudioContext();
+2 -2
View File
@@ -208,11 +208,11 @@ export function registerWorklet(url) {
}
let workletsLoading;
function loadWorklets() {
export function loadWorklets() {
if (!workletsLoading) {
const audioCtx = getAudioContext();
const allWorkletURLs = externalWorklets.concat([workletsUrl]);
workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL)));
workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))).then(() => workletsLoading = undefined);
}
return workletsLoading;
+18 -17
View File
@@ -5,9 +5,10 @@ This program is free software: you can redistribute it and/or modify it under th
*/
import * as strudel from '@strudel/core';
import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet, setAudioContext, getSampleBufferSource, loadBuffer, getSampleInfo, getSound, initAudio, setSuperdoughAudioController } from 'superdough';
import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet, setAudioContext, getSampleBufferSource, loadBuffer, getSampleInfo, getSound, initAudio, setSuperdoughAudioController, loadWorklets, setMaxPolyphony, setMultiChannelOrbits } from 'superdough';
import './supradough.mjs';
import { workletUrl } from 'supradough';
import { SuperdoughAudioController } from 'superdough/superdoughoutput.mjs';
registerWorklet(workletUrl);
@@ -27,16 +28,16 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => {
};
export async function renderPatternAudio(pattern, cps, begin, end) {
const oldAudioCtx = getAudioContext()
await oldAudioCtx.close()
let audioContext = new OfflineAudioContext(2, (end - begin) / cps * 48000, 48000);
setAudioContext(audioContext)
setSuperdoughAudioController(null)
await initAudio({
maxPolyphony: 1024,
multiChannelOrbits: true
})
let context = getAudioContext()
setSuperdoughAudioController(new SuperdoughAudioController(context))
setMaxPolyphony(1024)
setMultiChannelOrbits(true)
await loadWorklets()
logger('[webaudio] start rendering');
console.log(audioContext)
let haps = pattern.queryArc(begin, end, { _cps: cps })
Promise.all(haps.map(async h => {
@@ -48,11 +49,11 @@ export async function renderPatternAudio(pattern, cps, begin, end) {
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
if (bank) {
let { url: sampleUrl, label } = getSampleInfo(h.value, bank);
await loadBuffer(sampleUrl, context, label)
}
}
}))
haps.forEach(async (hap) => {
@@ -62,9 +63,8 @@ export async function renderPatternAudio(pattern, cps, begin, end) {
}
})
let context = getAudioContext()
context.startRendering().then((renderedBuffer) => {
// console.log(renderedBuffer)
context.startRendering().then(async (renderedBuffer) => {
console.log(renderedBuffer)
const wavBuffer = audioBufferToWav(renderedBuffer);
const blob = new Blob([wavBuffer], { type: 'audio/wav' });
let downloadName = ''
@@ -82,9 +82,10 @@ export async function renderPatternAudio(pattern, cps, begin, end) {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
await context.close()
setAudioContext(null)
setSuperdoughAudioController(null)
initAudio()
await initAudio()
});
}
+3 -1
View File
@@ -94,11 +94,13 @@ export function Header({ context, embedded = false }) {
{!isEmbedded && <span>update</span>}
</button>
<button
onClick={() => handleExport(1, 16)}
onClick={() => !started && handleExport(0, 16)}
title="export"
className={cx(
'flex items-center space-x-1',
!isEmbedded ? 'p-2' : 'px-2',
started ? 'opacity-50' : 'hover:opacity-50',
)}
>
{!isEmbedded && <span>export</span>}
@@ -114,7 +114,7 @@ export function SettingsTab({ started }) {
isMultiCursorEnabled,
} = useSettings();
const shouldAlwaysSync = isUdels();
const canChangeAudioDevice = BaseAudioContext.prototype.setSinkId != null;
const canChangeAudioDevice = AudioContext.prototype.setSinkId != null;
return (
<div className="text-foreground p-4 space-y-4 w-full" style={{ fontFamily }}>
{canChangeAudioDevice && (