Skip to content

spessasus/spessasynth_core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Jun 23, 2026
4ff1a04 · Jun 23, 2026

History

361 Commits
Jun 22, 2026
Jan 29, 2026
Jun 17, 2026
Jun 17, 2026
Jun 17, 2026
Jun 23, 2026
Jun 23, 2026
Jun 17, 2026
May 27, 2026
Jan 31, 2026
Jan 30, 2026
Apr 14, 2025
May 19, 2026
May 29, 2026
Jun 23, 2026
Jun 23, 2026
Jun 9, 2026
Jun 11, 2026

Repository files navigation

SpessaSynth logo

A powerful multipurpose SF2/DLS/MIDI JavaScript library. It works with any modern JS environment that supports WebAssembly.

It allows you to:

  • Play MIDI files using SF2/SF3/DLS files!
  • Read and write MIDI files!
  • Read and write SF2/SF3 files!
  • Convert DLS to SF2! (and back!)
  • and more!

v4.3.0 The General Update is here!

Featuring robust MIDI analysis and editing, broadened MIDI exclusive support, and reworked, more powerful API!

Tip:

Looking for an easy-to-use WebAudioAPI browser wrapper? Try spessasynth_lib!

Project site (consider giving it a star!)

Made with spessasynth_core

SpessaSynth Project index

Current Features

Easy Integration

  • Modular design: Easy integration into other projects (only load what you need)
  • Flexible: It's not just a MIDI player!
  • Easy to Use: Basic setup is just two lines of code!
  • No dependencies: Batteries included!
  • Full TypeScript definitions: Autocompletion in IDEs!

Powerful MIDI Synthesizer

  • Suitable for both real-time and offline synthesis
  • Excellent SoundFont support:
    • Full Generator Support
    • Full Modulator Support: First (to my knowledge) JavaScript SoundFont synth with that feature!
    • GeneralUser-GS Compatible: See more here!
    • SoundFont3 Support: Play compressed SoundFonts!
    • Experimental SF2Pack Support: Play soundfonts compressed with BASSMIDI! (Note: only works with vorbis compression)
  • Great DLS Support:
    • DLS Level 1 Support
    • DLS Level 2 Support
    • Mobile DLS Support
    • Correct articulator support: Converts articulators to both modulators and generators!
    • Tested and working with gm.dls!
    • Correct volume: Properly translated to SoundFont volume!
    • A-Law encoding support
    • Both unsigned 8-bit and signed 16-bit sample support (24-bit theoretically supported as well!)
    • Detects special articulator combinations: Such as vibratoLfoToPitch
  • Sound bank manager: Stack multiple sound banks!
  • Unlimited channel count: Your CPU is the limit!
  • Built-in, configurable effects:
    • Reverb: Multiple characters including delay and panning delay!
    • Chorus: Modulated delay lines with multiple presets!
    • Delay: Three delay lines for all of your delay needs!
    • Insertion Effects: The ultimate effects, they can give your sounds a completely different character! (limited support)
    • GS Compatible: MIDI files can configure the effects accurately!
    • Replaceable: Effects not to your liking? You can replace them with your own!
  • Excellent MIDI Standards Support:

Powerful and Fast MIDI Sequencer

  • Supports MIDI formats 0, 1, and 2: note: format 2 support is experimental as it's very, very rare.
  • Multi-Port MIDI support: More than 16 channels!
  • Smart preloading: Only preloads the samples used in the MIDI file for smooth playback (down to key and velocity!)
  • Lyrics support: Add karaoke to your program!
  • Raw lyrics available: Decode in any encoding! (Kanji? No problem!)
  • Loop points support: Ensures seamless loops!

Read and Write SoundFont and MIDI Files with Ease

Read and write MIDI files

  • Smart name detection: Handles incorrectly formatted and non-standard track names!
  • Raw name available: Decode in any encoding! (Kanji? No problem!)
  • Port detection during load time: Manage ports and channels easily!
  • Used channels on track: Quickly determine which channels are used!
  • Key range detection: Detect the key range of the MIDI!
  • Easy MIDI editing: Use helper functions to modify the song to your needs!
  • Loop detection: Automatically detects loops in MIDIs (e.g., from Touhou Project)
  • First note detection: Skip unnecessary silence at the start by jumping to the first note!
  • Lyrics support: Both regular MIDI and .kar files!
  • Write MIDI files from scratch
  • Easy saving: Save with just one function!
  • Level 4 compliance: Reads and writes everything!
  • Compression and trimming support: Reduce a MIDI file with a 1GB sound bank to as small as 5MB!
  • DLS Version support: The original legacy format with bank offset detection!
  • Automatic bank shifting and validation: Every sound bank just works!
  • Metadata support: Add title, artist, album name and cover and more! And of course, read them too! (In any encoding!)
  • Compatible with Falcosoft MIDI Player 6!
  • Easy saving: As simple as saving a MIDI file!

Read and play XMF files

  • Read the eXtensible Music Format files: With embedded DLS sound banks!
  • MXMF support: Mobile XMF for old phone ringtones!
  • Compression support: Zlib compressed files can still be read!
  • Seamless integration: Read like RMIDI files!

Read and write SoundFont2 files

  • Easy info access: Just an object of strings!
  • Smart trimming: Trim the sound bank to only include samples used in the MIDI (down to key and velocity!)
  • SF3 conversion: Compress SoundFont2 files to SoundFont3 with variable quality!
  • Easy saving: Also just one function!

Read and write SoundFont3 files

  • Same features as SoundFont2 but with now with Ogg Vorbis compression!
  • Variable compression quality: You choose between file size and quality!
  • Compression preserving: Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
  • Custom compression function: Want a different format than Vorbis? No problem!

Read and write DLS Level One or Two files

  • Read DLS (DownLoadable Sounds) files like SF2 files!
  • Native support: Saving it as sf2 is still just one function!
  • That's right, saving as DLS is also just one function!
  • Converts articulators to both modulators and generators!
  • Works with both unsigned 8-bit samples and signed 16-bit samples!
  • A-Law encoding support: Sure, why not?
  • Covers special generator cases: such as modLfoToPitch!
  • Correct volume: looking at you, Viena and gm.sf2!
  • Support built right into the synthesizer!
  • Convert SF2 to DLS: limited support

Export MIDI as WAV

  • Save the MIDI file as WAV audio!
  • Metadata support: Embed metadata such as title, artist, album and more!
  • Cue points: Write MIDI loop points as cue points!
  • Loop multiple times: Render two (or more) loops into the file for seamless transitions!
  • That's right, saving as WAV is also just one function!

Limitations

TODO

  • Improve the performance of the engine
  • Potentially port the system to Emscripten

Special Thanks

  • FluidSynth - for the source code that helped implement functionality and fixes
  • Polyphone - for the soundfont testing and editing tool
  • Meltysynth - for the initial low-pass filter implementation
  • RecordingBlogs - for detailed explanations on MIDI messages
  • stbvorbis.js - for the Vorbis decoder
  • fflate - for the MIT DEFLATE implementation
  • tsup - for the TypeScript bundler
  • foo_midi - for useful resources on XMF file format
  • Falcosoft - for help with the RMIDI format
  • Christian Collins - for various bug reports regarding the synthesizer
  • And You! - for checking out this project. I hope you like it :)

If you like this project, consider giving it a star. It really helps out!

Short example: MIDI to wav converter

For use with node.js

import * as fs from "node:fs/promises";
import {
    audioToWav,
    BasicMIDI,
    SoundBankLoader,
    SpessaLog,
    SpessaSynthProcessor,
    SpessaSynthSequencer
} from "spessasynth_core";

// Process arguments
const args = process.argv.slice(2);
if (args.length !== 3) {
    console.info(
        "Usage: tsx index.ts <soundbank path> <midi path> <wav output path>"
    );
    process.exit();
}
// Read MIDI and sound bank
const sf = await fs.readFile(args[0]);
const mid = await fs.readFile(args[1]);
// Parse the MIDI and sound bank
const midi = BasicMIDI.fromArrayBuffer(mid.buffer);
const soundBank = SoundBankLoader.fromArrayBuffer(sf.buffer);

// Initialize the synthesizer
const sampleRate = 48_000;
const synth = new SpessaSynthProcessor(sampleRate, {
    eventsEnabled: false
});
synth.soundBankManager.addSoundBank(soundBank, "main");
await synth.processorInitialized;
// Enable verbose information during render
SpessaLog.setLogLevel(true, true, true);
// Enable uncapped voice count
synth.setSystemParameter("autoAllocateVoices", true);

// Initialize the sequencer
const seq = new SpessaSynthSequencer(synth);
seq.loadNewSongList([midi]);
seq.play();

// Prepare the output buffers
const sampleCount = Math.ceil(sampleRate * (midi.duration + 2));
const outLeft = new Float32Array(sampleCount);
const outRight = new Float32Array(sampleCount);
const start = performance.now();
let filledSamples = 0;
// Note: buffer size is recommended to be very small, as this is the interval between modulator updates and LFO updates
const BUFFER_SIZE = 128;
let i = 0;
const durationRounded = Math.floor(seq.midiData!.duration * 100) / 100;
while (filledSamples < sampleCount) {
    // Process sequencer
    seq.processTick();
    // Render
    const bufferSize = Math.min(BUFFER_SIZE, sampleCount - filledSamples);
    synth.process(outLeft, outRight, filledSamples, bufferSize);
    filledSamples += bufferSize;
    i++;
    // Log progress
    if (i % 100 === 0) {
        console.info(
            "Rendered",
            Math.floor(seq.currentTime * 100) / 100,
            "/",
            durationRounded
        );
    }
}
const rendered = Math.floor(performance.now() - start);
console.info(
    "Rendered in",
    rendered,
    `ms (${Math.floor(((midi.duration * 1000) / rendered) * 100) / 100}x)`
);
const wave = audioToWav([outLeft, outRight], sampleRate);
await fs.writeFile(args[2], new Uint8Array(wave));
console.info(`File written to ${args[2]}`);

Read more in the documentation

Building

To build the NPM package, do:

npm install
npm run build

The files will be placed in the dist folder.

License

Copyright © 2026 Spessasus Licensed under the Apache-2.0 License.

Legal

This project is in no way endorsed or otherwise affiliated with the MIDI Manufacturers Association, Roland Corporation, Yamaha Corporation, Creative Technology Ltd. or E-mu Systems, Inc., or any other organization mentioned. SoundFont® is a registered trademark of Creative Technology Ltd. All other trademarks are the property of their respective owners.