diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index a6c451e..affd6be 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -44,11 +44,8 @@ if (_initInProgress) return; _initInProgress = true; if (!window.SpessaSynthClass || !window.__SpessaSynthCDN) { - console.warn("[SonicSF] SpessaSynth CDN not loaded. Retrying in 2s..."); + console.warn("[SonicSF] SpessaSynth CDN not loaded. Using oscillator fallback."); _initInProgress = false; - setTimeout(() => { - if (!_initialized && window.SpessaSynthClass && audioContext) this.init(audioContext); - }, 2000); return; } try { @@ -56,27 +53,50 @@ await audioContext.audioWorklet.addModule(procUrl); _synthInstance = new window.SpessaSynthClass(audioContext); await _synthInstance.isReady; - _initialized = true; - _initInProgress = false; - console.log("[SonicSF] SpessaSynth initialized."); + // Try loading default SGM bank to verify SpessaSynth works + try { + const resp = await fetch("/api/v1/plugins/soundfonts/download/sgm_v2.01?t=" + Date.now()); + if (resp.ok) { + const buf = await resp.arrayBuffer(); + await _synthInstance.soundBankManager.addSoundBank(buf.slice(0), "sgm_v2.01"); + await _synthInstance.isReady; + const bankCount = _synthInstance.soundBankManager?.soundBankList?.length ?? 0; + if (bankCount > 0) { + _initialized = true; + _initInProgress = false; + console.log("[SonicSF] SpessaSynth ready with", bankCount, "banks."); + return; + } + } + } catch (bankErr) { + console.warn("[SonicSF] Default bank load failed:", bankErr); + } + console.log("[SonicSF] SpessaSynth init OK but bank load failed. Using oscillator."); } catch (e) { - _initInProgress = false; console.warn("[SonicSF] AudioWorklet init failed:", e); try { const mod = await import("https://cdn.jsdelivr.net/npm/spessasynth_lib@4.3.1/dist/index.js"); _synthInstance = new mod.WorkerSynthesizer(audioContext); await _synthInstance.isReady; - _initialized = true; - console.log("[SonicSF] SpessaSynth initialized via Worker."); + console.log("[SonicSF] WorkerSynthesizer ready (oscillator fallback for playback)."); } catch (e2) { console.error("[SonicSF] All SpessaSynth paths failed:", e2); } } + // Always reset initialized — playNote falls through to oscillator + _initialized = false; + _initInProgress = false; }, selectInstrument: async function (channel, bank, program, sfId) { if (!_initialized || !_synthInstance) return; - if (sfId) await this.loadSoundFont(sfId); + if (sfId) { + const ok = await this.loadSoundFont(sfId); + if (!ok) { + console.warn("[SonicSF] selectInstrument: bank not loaded, oscillator will be used."); + return; + } + } try { _synthInstance.controllerChange(channel, 0, bank); } catch (e) {} try { _synthInstance.controllerChange(channel, 32, 0); } catch (e) {} try { _synthInstance.programChange(channel, program); } catch (e) {}