npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

spessasynth_core

v4.0.23

Published

MIDI and SoundFont2/DLS library with no compromises

Downloads

1,519

Readme

A powerful SF2/DLS/MIDI TypeScript/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!
  • Write SF2/SF3 files!
  • Convert DLS to SF2! (and back!)
  • and more!

v4.0.0 TypeScript Update is here!

Read about breaking changes here.

Tip:

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

Project site (consider giving it a star!)

Made with spessasynth_core

Documentation

SpessaSynth Project index

Current Features

Easy Integration

  • Modular design: Easy integration into other projects (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!
  • 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!
    • GeneralUserGS Compatible: See more here!
    • SoundFont3 Support: Play compressed SoundFonts!
    • Experimental SF2Pack Support: Play soundfonts compressed with BASSMIDI! (Note: only works with vorbis compression)
    • Can load very large SoundFonts: up to 4GB! Note: Only Firefox handles this well; Chromium has a hard-coded memory limit
  • 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
  • Soundfont manager: Stack multiple soundfonts!
  • Unlimited channel count: Your CPU is the limit!
  • 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!

Read and write RMID files with embedded sound banks

  • 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 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

import * as fs from "fs/promises";
import {
    audioToWav,
    BasicMIDI,
    SoundBankLoader,
    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();
}
const sf = await fs.readFile(args[0]);
const mid = await fs.readFile(args[1]);
const midi = BasicMIDI.fromArrayBuffer(mid.buffer);
const sampleRate = 44100;
const sampleCount = Math.ceil(44100 * (midi.duration + 2));
const synth = new SpessaSynthProcessor(sampleRate, {
    enableEventSystem: false,
    enableEffects: false
});
synth.soundBankManager.addSoundBank(
    SoundBankLoader.fromArrayBuffer(sf.buffer),
    "main"
);
await synth.processorInitialized;
const seq = new SpessaSynthSequencer(synth);
seq.loadNewSongList([midi]);
seq.play();

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;
const outputArray = [outLeft, outRight];
while (filledSamples < sampleCount) {
    // Process sequencer
    seq.processTick();
    // Render
    const bufferSize = Math.min(BUFFER_SIZE, sampleCount - filledSamples);
    synth.renderAudio(outputArray, [], [], 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]}`);

Building

To build the NPM package, do:

npm install
npm run build

The files will be placed in the dist folder.

License

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

Legal

This project is in no way endorsed or otherwise affiliated with the MIDI Manufacturers Association, 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.