Skip to content

Simple MIDI Player Example

See this demo live

This example demonstrates how to quickly set up a synthesizer and a sequencer to play a MIDI file.

The example uses two classes: WorkletSynthesizer class and Sequencer class to play a MIDI file.

simple_demo.html
<p id='message'>Please wait for the sound bank to load.</p>
<input accept='.mid, .rmi, .xmf, .mxmf' id='midi_input' type='file'>
<!-- note the type="module" -->
<script src='simple_demo.js' type='module'></script>

Info

Note the type=”module” in the script tag.

simple_demo.js
// import the modules
import { Sequencer, WorkletSynthesizer } from "../../src/index.js";
import {
    EXAMPLE_SOUND_BANK_PATH,
    EXAMPLE_WORKLET_PATH
} from "../examples_common.js";

// load the sound bank (your path may vary)
fetch(EXAMPLE_SOUND_BANK_PATH).then(async (response) => {
    // load the sound bank into an array buffer
    let sfFile = await response.arrayBuffer();
    document.getElementById("message").innerText =
        "Sound bank has been loaded!";

    // create an audioContext and add the worklet
    const context = new AudioContext();
    await context.audioWorklet.addModule(EXAMPLE_WORKLET_PATH);
    // create the synthesizer
    const synth = new WorkletSynthesizer(context);
    synth.connect(context.destination);
    // add the sound bank
    await synth.soundBankManager.addSoundBank(sfFile, "main");
    // create the sequencer
    const seq = new Sequencer(synth);

    // make it loop
    seq.loopCount = Infinity;

    // add an event listener for the file inout
    document
        .getElementById("midi_input")
        .addEventListener("change", async (event) => {
            // audio context may only be resumed after user interaction
            await context.resume();
            /**
             * check if any files are added
             * @type {HTMLInputElement}
             */
            const input = event.target;
            if (!input.files[0]) {
                return;
            }
            const midiFile = await input.files[0].arrayBuffer(); // get the file and convert to ArrayBuffer

            // load a new song list and play
            seq.loadNewSongList([{ binary: midiFile }]);
            seq.play();
        });
});

What the script does:

  1. Import the necessary variables
  2. fetch-es the sound bank file
  3. Initializes an AudioContext and adds the worklet
  4. Initializes WorkletSynthesizer instance
  5. Adds a sound bank to the synthesizer
  6. Adds an EventListener for the file input:
  7. Initializes WorkletSynthesizer instance
  8. Adds a sound bank to the synthesizer
  9. Initializes a Sequencer instance and connects it to the WorkletSynthesizer instance we created earlier
  10. Starts the playback via sequencer.play();

It’s that simple!