/* LilyScript FluidSynth audio backend — vanilla-JS port of lilylet-live-editor's * src/lib/audio/fluidAudio.ts, exposed as window.LilyFluidAudio. * * Replaces the legacy single-piano MIDI.js soundfont with FluidSynth (js-synthesizer * WASM) playing a General MIDI gm.sf3 (128 instruments), so each track sounds with * its own program instead of everything-as-piano. * * Shaped to match the subset of music-widgets' MidiAudio API that score-player.js * drives: empty / loadPlugin / resume / noteOn / noteOff / programChange / * stopAllNotes. score-player.js sends noteOn/noteOff with an absolute * performance.now()-based timestamp; we forward to FluidSynth's Sequencer via * sendEventAt(event, dtMs, isAbsolute=false) ("play in dtMs ms"), preserving the * look-ahead timing without reconciling against the sequencer's own tick origin. * * Fallback: gm.sf3 is ~40 MB and takes a moment to fetch + decode. While it loads we * fall back to the legacy MIDI.js WebAudio piano (the small, locally-bundled * acoustic-grand-piano soundfont) so playback is audible immediately; once FluidSynth * is ready we switch to it transparently. * * Globals consumed (loaded via