From 6d9060a52b09e4252ce97aa51aa8b92e1d342816 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Sun, 26 Jul 2026 19:32:32 +0700 Subject: [PATCH] fix: gracefully fallback to oscillator when SpessaSynth bank load fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SpessaSynth init tries to load default bank, gracefully handles failure - When bank load fails, _currentSfId stays null → _playNoteOsc fallback - Client preview: oscillator emulation (approximate GM sound) - Server-side render via FluidSynth: authentic SoundFont audio --- app/static/js/services/soundfontPlayer.js | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index 8f3f1b9..3d694a0 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -60,16 +60,46 @@ await audioContext.audioWorklet.addModule(procUrl); _synthInstance = new window.SpessaSynthClass(audioContext); await _synthInstance.isReady; + // Load default SF2 to verify parsing 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; + // Check if presets were loaded by querying soundBankList + const bankCount = _synthInstance.soundBankManager?.soundBankList?.length ?? 0; + console.log("[SonicSF] SpessaSynth initialized. Banks loaded:", bankCount); + if (bankCount > 0) { + _initialized = true; + _initInProgress = false; + return; + } + } + } catch (bankErr) { + console.warn("[SonicSF] Default bank load failed:", bankErr); + } + // Fallback: init without bank — oscillator will handle preview _initialized = true; _initInProgress = false; - console.log("[SonicSF] SpessaSynth initialized via AudioWorklet."); + console.log("[SonicSF] SpessaSynth initialized (no sound bank). Oscillator fallback active."); } catch (e) { _initInProgress = false; - console.warn("[SonicSF] AudioWorklet failed, trying WorkerSynthesizer:", e); + console.warn("[SonicSF] AudioWorklet failed:", e); + // Try WorkerSynthesizer as fallback 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; + 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; + console.log("[SonicSF] Worker synth with bank OK."); + } + } catch (e2) {} _initialized = true; console.log("[SonicSF] SpessaSynth initialized via Worker."); } catch (e2) { @@ -77,6 +107,7 @@ } } }, + }, // ── Load SF3 from IndexedDB cache or server ── loadSoundFont: async function (sfId) {