From 6dec171af79e9df475c832cd1ae08104a30cec5d Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 27 Jul 2026 21:26:52 +0700 Subject: [PATCH] fix: _playNoteFluid else branch leaked other track's SF program 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a track has no instrument configured, _playNoteFluid called program_change(ch, 0). FluidSynth searches ALL loaded SoundFonts to resolve program 0 — if only another track's SoundFont is loaded, that SF's program 0 gets applied to the wrong track. Fix: use oscillator fallback directly instead of program_change. --- app/static/js/services/soundfontPlayer.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index b2ecae9..7931443 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -393,10 +393,13 @@ _fluidModule._fluid_synth_program_change(_synthPtr, ch, usedProg); } catch (e) {} } else { - if (ch === undefined) ch = 0; - try { - _fluidModule._fluid_synth_program_change(_synthPtr, ch, 0); - } catch (e) {} + // No instrument configured: use oscillator fallback directly. + // Do NOT call program_change(ch, 0) — FluidSynth would pick + // program 0 from whatever SoundFont is loaded (could be + // another track's SF), causing cross-track instrument leak. + var ctx = getCtx(); + self._playNoteFallback(note, velocity, durationMs, startTime, undefined, null, channel, undefined); + return; } if (ch === undefined) ch = (usedBank === 128 ? 9 : 0); var ctx = getCtx();