Custom SoundFonts
The bundled Sonivox SoundFont covers General MIDI but is deliberately small. When the score needs a Steinway rather than a GM piano, a metal amp emulation rather than a clean guitar, or a rock drum kit rather than the stock kick and snare, swap in a purpose-built .sf2 file. The synth pipeline stays identical โ only the sample bank changes.
The score below is the opening bars of Beethoven's Ode to Joy voiced as a chord-melody โ long, sustained notes give the sample bank room to speak. Toggle the SoundFont to hear the same MIDI events re-rendered through a different bank.
The two options give an audible A/B: the bundled Sonivox is a compact General-MIDI bank tuned for small footprint; GeneralUser GS by S. Christian Collins is a refined GM/GS bank (about 9 MB as compressed SF3) with Steinway-lineage piano samples and richer guitar/drum presets. Toggle to hear the same MIDI events re-rendered through a much fuller-bodied bank. GeneralUser GS is redistributed here under its author's permissive license (commercial and modification allowed).
Two ways to load oneโ
api.loadSoundFont(data)โ pass aUint8ArrayorArrayBufferof SoundFont bytes and alphaTab wires them into the synth. Works on every runtime.api.loadSoundFont(url)โ on Web only, pass a URL string and alphaTab downloads the file for you.
Both forms replace whatever is currently loaded โ the second parameter, append, defaults to false. When it fires, api.soundFontLoaded signals that the synth is ready. Trigger api.resetSoundFonts() to release all presets and free the memory before loading a fresh one.
Show it in codeโ
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledSynthesizer,
},
});
api.soundFontLoaded.on(() => {
console.log('Ready for playback.');
});
// Swap in a bytes-based SoundFont.
const bytes = await readScoreFile('/assets/fluidr3-guitars.sf2');
api.loadSoundFont(bytes);
// Later, drop everything and load a different one.
api.resetSoundFonts();
const drums = await readScoreFile('/assets/rock-drums.sf2');
api.loadSoundFont(drums);
getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target โ a <div> on Web, an AlphaTab control on .NET, or an AlphaTabView on Android.
readScoreFile() is a placeholder for the platform-specific step of producing a Uint8Array โ fs.promises.readFile on Node.js, System.IO.File.ReadAllBytes on .NET, ContentResolver.openInputStream on Android, or fetch(...).then(r => r.arrayBuffer()) in the browser.
Picking a SoundFontโ
- SoundFonts are a public format โ FluidR3, Timbres of Heaven, and many commercial packs work as-is.
- Larger files mean better samples but longer downloads on Web. Trim unused presets with Polyphone before shipping.
- If your score uses only guitars and drums, a 5 MB targeted SoundFont beats a 200 MB general-purpose one on both download time and RAM footprint.
Where to look nextโ
- Combining multiple SoundFonts โ load several SoundFonts side by side.
- SoundFont2 with TinySoundFont โ how the synth pipeline uses the loaded file.
api.loadSoundFont,api.resetSoundFonts, andapi.soundFontLoadedin the reference.player.soundFontโ the settings-side entry point for a single-file replacement.